/** * Secret-shape detection, shared by every boundary that must not leak one * (E001 security gate, findings F7/F9; E002 findings F1/F2). One copy of the * patterns: a security regex that drifts between call sites is its own defect * class. * * THREE mechanisms, because no one of them is enough (E002-F1). They are * complements, not alternatives — each catches what the others structurally * cannot: * * 1. **Known-value matching** ({@link knownSecretValues}) — several providers * OpenKai supports issue OPAQUE tokens with no prefix at all (together: * 64 hex; mistral: 32 alphanumerics; `CORTEX_ADMIN_TOKEN`). No shape can * match those without also matching git SHAs and ordinary identifiers, so * instead we redact the literal values this process actually holds — * `process.env` entries whose NAME is credential-shaped. Zero false * positives by construction: we only redact a string we know is a secret. * Blind to any key this process does not hold. * 2. **Shape matching** ({@link SECRET_PREFIXES}) — provider tokens carry a * distinctive prefix. Cheap, works on text from anywhere, catches a key * this process has never held. Blind to prefixless tokens. * 3. **Context matching** ({@link OPAQUE_AFTER_CREDENTIAL_WORD}) — a long * opaque token sitting immediately after a credential word. Catches a * prefixless key this process does NOT hold, which is precisely the gap * mechanism 1 and mechanism 2 leave between them (a teammate's key quoted * in a pasted error body, an OAuth token read from a file rather than the * environment). * * ORDER IS LOAD-BEARING, see {@link redactSecrets}. * * The prefix list is mirrored by `scripts/security-audit.sh` §1 (the * commit-time scan). They are two implementations of one list, so * `security-repro-e002.test.ts` asserts the shell script covers every prefix * below — E002-F2 was exactly this pair drifting apart unnoticed. */ /** * Provider token prefixes, as they appear in free text. Exported so the * drift test can assert `scripts/security-audit.sh` §1 covers the same set. * * `csk-` is listed explicitly: it was previously matched only by accident, * via the `sk-` alternative, which redacted `csk-XXX` as `c[redacted-secret]` * and left the leading character exposed. */ export declare const SECRET_PREFIXES: readonly string[]; /** Non-global — safe for repeated `test()`. */ export declare const SECRET_VALUE_PATTERN: RegExp; /** Env var NAMES that carry credentials regardless of their value's shape. */ export declare const SECRET_NAME_PATTERN: RegExp; /** * Replace secret-shaped spans, and any known credential value, with a fixed * marker. * * ORDER IS LOAD-BEARING — most precise mechanism first: * * 1. **Known values**, because they are exact literals. A pattern pass run * first can consume a PREFIX of a known value and leave the rest in the * clear: the token classes here stop at any character outside * `[A-Za-z0-9_-]`, and a JWT (`ANTHROPIC_OAUTH_TOKEN`) is dot-separated. * Redacting `header` alone leaves `payload.signature` — the half that * matters — exposed, and the literal no longer matches so pass 3 cannot * recover it. Exact-match first, then nothing is left to fragment. * 2. **Prefixed shapes**, whose marker starts with `[` — a character the * opaque token class rejects, so pass 3 cannot re-match pass 2's output. * 3. **Opaque-after-credential-word**, the loosest rule, last. * * ponytail: shape matching stays a blast-radius reducer, not a guarantee. The * three mechanisms cover different halves of the problem — see the file header. * Widen the prefix list when a provider ships a new shape; the drift test will * tell you to update the shell scan too. */ export declare function redactSecrets(text: string, env?: NodeJS.ProcessEnv): string; //# sourceMappingURL=secrets.d.ts.map