/** * PII + secret redaction for span content. * * Walks a JSON-shaped value and replaces matches in string values. Reused by the * gen_ai content path (`gen-ai.ts`), which redacts conversation/tool content inline * before stamping it onto a span (awaited per call). * * Scope (see createOpenRedactionAdapter): emails, phones (US, international, * India, China, South Korea, Japan, UK mobile, Brazil), ~28 vendor API keys * / tokens (AWS, GitHub, Stripe, OpenAI, etc.), EVM private keys, Anthropic * `sk-ant-*` keys, generic `sk-*` keys, and BIP39 mnemonic phrases. * * The process-wide default redactor is registered unconditionally at plugin * boot (see initDefaultPiiRedactor), so the event-log redact-field path * (`logger.event()`) is scrubbed without an env gate. */ /** Minimal interface so tests can inject a synchronous stub. */ export interface PiiRedactor { redact(text: string): Promise; } /** * Walks a JSON-shaped value. Strings are run through the redactor; arrays * and plain objects are recursed; everything else (number, boolean, null, * non-plain objects) is returned unchanged. Preserves reference identity * when nothing changes — useful for short-circuit downstream comparisons. */ export declare function redactStringsDeep(value: unknown, redactor: PiiRedactor): Promise; export declare function setDefaultPiiRedactor(r: PiiRedactor | null): void; export declare function getDefaultPiiRedactor(): PiiRedactor | null; /** * Register the process-wide default PII redactor at plugin boot. Always on, no * env gate: `logger.event()` redact fields (free-text LLM reasoning, venue * errors, raw signals) are scrubbed on the live path. * * Fire-and-forget and never awaited, so it adds no boot latency and can't * introduce a boot failure mode. The OpenRedaction + bip39 imports are dynamic, * so they cold-start here; until the promise resolves `getDefaultPiiRedactor()` * is null and the event path fails safe (drops the fields rather than emitting * them raw). On install failure the redactor stays null — the fields keep being * dropped, never leaked. */ export declare function initDefaultPiiRedactor(): void; /** * Find BIP39-mnemonic spans in `text` using a true sliding window — not * a greedy regex with a post-hoc validator. * * Why this and not a regex+validator: * - OpenRedaction calls the validator on whatever the regex captured. JS * regex matching is left-to-right with no backtracking across `lastIndex` * advances; once a (greedy) match is rejected, the engine moves past it * entirely. So a 17-word lowercase run like "my secret is <12 BIP39> * so keep safe" gets captured whole, fails validation on word count, * and the engine doesn't retry the 12-word window starting 3 tokens in. * * Algorithm: * 1. Tokenize lowercase-only words and their offsets (skips capitalized * words and punctuation — real mnemonics from wallet exports are * always all-lowercase space-separated). * 2. Walk left to right. At each token position, try valid mnemonic * counts largest-first (24, 21, 18, 15, 12) so a 24-word phrase * inside a longer prose run isn't missed by a premature 12-match. * 3. A window is valid only when every word is BIP39 AND the gap between * consecutive tokens in the source is whitespace-only (rejects forms * with commas or other punctuation between words, which real wallet * exports don't use). * 4. On match, record the source span and advance past it; otherwise step * forward one token. */ export declare function findMnemonicSpans(text: string, bip39: Set): Array<{ start: number; end: number; }>; /** * Pre-redact BIP39 mnemonics in `text` before handing the result to * OpenRedaction. Returns the original string when no mnemonics are present * (cheap path — only the tokenizer runs and finds nothing). */ export declare function redactMnemonicsPreRedaction(text: string): Promise; /** * Build an OpenRedaction-backed PiiRedactor. * * Detects: * - Contact PII: emails. * - Phones (all custom — upstream phone patterns are unreliable, see * ALLOWLISTED_PATTERN_TYPES docstring): US, international (`+` prefix), * India, China, South Korea, Japan, UK mobile, Brazil. Each requires * either an explicit country code OR a country-specific mobile prefix * plus separators, so bare numeric IDs (timestamps, span IDs, UUIDs) * survive untouched. * - Credentials (upstream): cloud / vendor API keys + tokens (AWS, Azure, * GCP, GitHub, Slack, Stripe, OpenAI, Twilio, …), bearer + JWT tokens, * OAuth secrets, generic API keys, SSH/PEM private keys, URLs with * embedded auth. * - Crypto secrets (custom patterns): EVM private keys (0x + 64 hex), * Anthropic `sk-ant-*` keys, generic `sk-*` keys (OpenAI/OpenRouter). * - BIP39 mnemonic phrases (out-of-band sliding-window pre-pass — see * `redactMnemonicsPreRedaction`): 12/15/18/21/24 BIP39 words, found and * redacted before the OpenRedaction pass so embedded phrases like * "my key is <12 words> keep safe" are caught. * * Tuning: * - `enableFalsePositiveFilter: false` — explicit; the library defaults * this to truthy in practice and suppresses valid international-phone * matches in some contexts. * - `enableContextAnalysis: false` — saves CPU; context rules add * latency and aren't load-bearing for the patterns we keep. * - `enableCache: true` — chat history repeats; cache skips re-scan. * - `confidenceThreshold: 0.5` — kept conservative; custom patterns score * 1.0 so this only affects built-ins. * * Lazy-imports `openredaction` and `bip39` — both deps stay cold for builds * / tests that don't enable redaction. */ export declare function createOpenRedactionAdapter(): Promise; //# sourceMappingURL=redact-pii.d.ts.map