symfonic.capabilities.governance.stages.credentials¶
credentials ¶
Credential hygiene: the first stage, and one of the two fail-closed ones.
The built-in pattern and compiler come from the stdlib-only
symfonic.agent.hygiene leaf. That exact import is the governance
package's one containment exception: it does not construct or import the
legacy engine, and both paths now use the same credential policy object.
Shallow by design (the legacy invariant): nested dicts are not walked, because graph properties are persisted flat and value-scanning carries a false-positive tax that belongs to its own design track.
One scoped exception, added for #27. ToolCall.result is free text, and
the stage never read it — so a tool returning a credential in its output (an
API client echoing an auth header, a shell tool printing an env dump, a DB tool
returning a connection string) passed a fail-closed scrubber untouched. Keys
cannot be dropped from a string, so the result is redacted whole when the
pattern matches anywhere in it.
That is blunt, and deliberately so. Partial redaction of free text means
guessing where a value begins, and a guess inside a fail-closed stage is the
worst place for one. The cost is real — a result that merely discusses
authorization is redacted too — and it is pinned by a test rather than
discovered, so a deployment that finds it unacceptable narrows patterns
knowing exactly what it is trading.
CredentialHygieneStage ¶
Drop credential-shaped keys before any other stage observes them.
Source code in src/symfonic/capabilities/governance/stages/credentials.py
compile_credential_pattern ¶
Build a single alternation regex from a list of pattern fragments.
None-> return :data:DEFAULT_CREDENTIAL_KEY_PATTERN(v6.1.9).- Empty list/tuple -> return
None(explicit opt-out of scrubbing). - Non-empty list -> compile each fragment as a sub-alternation and OR them together into one case-insensitive regex.
Invalid regex fragments raise :class:re.error at compile time, not
silently at scrub time — a misconfigured pattern list should fail fast
during config construction, not leak secrets at runtime.