/** * @packageDocumentation * GS2-47 — a shared, reusable secret-redaction pass for diagnostic output. * * Built for `/debug-dump` (`debugDump.ts`) but deliberately generic and * dependency-free — it takes `env` as a PARAMETER rather than reading `process.env`, so the pass is * pure, deterministic in tests, and reusable by GS2-48's crash-report handler (which hard-depends on * this module). Nothing here reads ambient process state. * * DESIGN DECISION (settled by the coordinator, GS2-47): **PATTERN-ONLY** redaction — we do NOT scan * for high-entropy strings. Rationale: pattern-only is safe to reason about and near-zero * false-positive; entropy scanning catches marginally more but produces false-positive redactions * the user has to squint through, degrading the dump's debug value. A high-entropy scanner is a * DELIBERATELY-DEFERRED option (a config surface for it could be added later if ever warranted) and * is intentionally NOT implemented here. * * Three techniques, in priority order: * 1. [load-bearing] Known-secret VALUE substitution — collect the literal values of secret-named * env vars + inline config secrets, then substitute every occurrence across ALL artifacts. This * catches a leaked key wherever it surfaces (config, env, transcript, log) with no guessing. * 2. Provider key/token PATTERNS — a tight, documented, prefix-anchored set of well-known key * shapes plus explicit auth-header contexts. We never blanket-redact long alphanumeric strings. * 3. Sensitive config-FIELD masking — mask the VALUES of secret-named config keys while preserving * structure (the key stays; only the value becomes the marker). * * Fail-safe throughout: on any internal error the functions redact MORE (return the marker), never * less — a redaction hiccup must never cause raw content to be emitted. */ /** The visible, greppable placeholder substituted for every redacted secret value. */ export declare const REDACTED = ""; /** * Collect the literal secret VALUES to substitute everywhere (technique 1), from two sources: * - process-env vars whose NAME matches `SECRET_ENV_NAME_RE`, PLUS the specific var(s) named * by any `apiKeyEnvironmentVariable` in the config; * - non-empty inline secret field values in the config (technique 3's field names), so a key pasted * inline is scrubbed wherever it *also* surfaces (transcript, log, env), not only in config.json. * * `env` is a PARAMETER — never read ambiently — so the pass is pure, reusable (GS2-48) and * deterministic in tests. Values shorter than `MIN_SECRET_LITERAL_LENGTH` are skipped. The * result is returned longest-first so an overlapping-substring secret can't leave a shorter one * partially intact. Never throws (a hostile config getter is swallowed — patterns + structural * masking still apply). */ export declare function collectSecretValues(config: unknown, env: Record): string[]; /** * Redact a STRING: substitute every known literal secret value (technique 1, longest-first), then * apply the provider key/auth patterns (technique 2). Never throws — on any error it returns the * fully-withheld marker (fail safe: redact MORE, never emit the raw text). Applying it twice is * safe (re-redacting already-redacted text is a no-op). */ export declare function redactText(text: string, secrets: readonly string[]): string; /** * Deep-redact an arbitrary value for serialization: mask the VALUES of secret-named fields * (technique 3 — structure preserved: the key stays, only its value becomes the marker) and run * {@link redactText} over every string leaf (techniques 1 + 2). Circular refs are broken; functions * and bigints are rendered the way `safeStringify` would, so the result is JSON-safe. Pure — never * mutates the input. `apiKeyEnvironmentVariable` is intentionally NOT masked (it is a var name). * * Intended for the CONFIG artifact (where field-name masking is wanted). Non-config artifacts use * {@link redactText} over their stringified form instead (literal + pattern only), so a legitimate * `token`/`secret`-named field in tool output is not blanket-masked. */ export declare function redactValue(value: unknown, secrets: readonly string[]): unknown;