scrubPii() before the SDK ships it. Patterns run in a deliberate order (most specific first, multi-line first). Matched substrings are replaced with a tagged token.
Patterns
| Pattern | Replacement |
|---|---|
| PEM private key block | [REDACTED-PRIVATE-KEY] |
| JWT | [REDACTED-JWT] |
Anthropic key (sk-ant-...) | [REDACTED-API-KEY] |
OpenAI key (sk-... / sk-proj-...) | [REDACTED-API-KEY] |
Stripe live keys (sk_live_... / pk_live_...) | [REDACTED-API-KEY] |
GitHub fine-grained PAT (github_pat_...) | [REDACTED-API-KEY] |
GitHub classic PAT (ghp_...) | [REDACTED-API-KEY] |
AWS access key (AKIA...) | [REDACTED-API-KEY] |
Slack token (xoxb- / xoxp- / xoxa-) | [REDACTED-API-KEY] |
Voight key (vk_...) | [REDACTED-API-KEY] |
Email (name@host.tld) | [REDACTED-EMAIL] |
Phone, E.164 (+1234567890) | [REDACTED-PHONE] |
| Credit card (13–19 digits + Luhn) | [REDACTED-CARD] |
voight-sdk/src/privacy.ts.
Examples
Deliberate non-matches
To avoid false positives that would harm dev workflows:| Input | Not redacted | Reason |
|---|---|---|
email_template | not an email | no @ in middle |
support@app | not an email | no TLD |
sk_test_xxx | not redacted | Stripe test key — not real money |
AKIAfoo | not an AWS key | real keys are uppercase |
| 16-digit order numbers | not a card | fails Luhn checksum |
10-digit numbers without + | not a phone | E.164 requires + prefix |
tests/unit/privacy.test.ts verifies positive matches and adversarial negatives.
Properties
- Idempotent — re-running
scrubPii()on already-scrubbed text is stable. - Local — runs in the SDK subprocess on your machine; no network or filesystem I/O.
- Bounded — designed for a 2KB event payload in under 10ms on a modern laptop. Regexes are anchored with word boundaries to avoid catastrophic backtracking.
- Conservative — the pattern set is small (~13 regexes). Industry libraries like gitleaks, detect-secrets, and trufflehog ship 400+; we don’t.
Stricter than Standard
If Standard’s scrubbing isn’t strict enough for your case, Minimal drops content fields entirely:reasoning, errorMessage, input, metadata.detail, metadata.response_preview, metadata.responseText, metadata.cwd, metadata.git. What’s left is tool names, timings, token counts, and identifiers.
See the privacy overview capture-level table.