When you pick Standard privacy mode, every string field in every event is run throughDocumentation Index
Fetch the complete documentation index at: https://docs.voight.xyz/llms.txt
Use this file to discover all available pages before exploring further.
scrubPii() before the SDK ships it. This page documents exactly which patterns match and how each is replaced.
How it works
The function runs a list of regular expressions in deliberate order (most-specific first, multi-line patterns first). Once a pattern matches, the matched substring is replaced with a tagged token like[REDACTED-API-KEY]. The result is idempotent — re-running scrubPii() on already-scrubbed text leaves it stable.
The pattern set is:
| Name | Replacement token |
|---|---|
| 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 in E.164 format (+1234567890) | [REDACTED-PHONE] |
| Credit card (13–19 digits + Luhn checksum) | [REDACTED-CARD] |
voight-sdk/src/privacy.ts.
Examples
What it deliberately doesn’t match
To avoid false positives that would harm dev workflows:| Looks like | But not redacted | Reason |
|---|---|---|
email_template | not an email | no @ in middle |
support@app | not an email | no TLD |
sk_test_xxx (Stripe test keys) | not redacted | not actual money |
AKIAfoo (lowercase tail) | 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 — 30+ tests) verifies positive matches + adversarial negatives.
Idempotency
scrubPii() is idempotent. Re-running it on already-scrubbed text is safe:
Performance
Designed to handle a 2KB event payload in under 10ms on a modern laptop. The pattern set is small (~13 regexes), there’s no network or filesystem I/O, and the regexes are anchored with word boundaries to avoid catastrophic backtracking.Adding new patterns
The pattern set is intentionally conservative — we’d rather miss an edge case than create false positives that confuse developers. Industry libraries like gitleaks, detect-secrets, or trufflehog ship 400+ patterns; we don’t. If you have a credential format that should be covered (especially crypto wallet private keys / mnemonic phrases / API tokens for AI providers we haven’t added yet), open an issue at voightxyz/voight-sdk.What gets sent under Minimal mode
If Standard’s scrubbing isn’t strict enough for your use case, Minimal mode drops the content fields entirely —reasoning, errorMessage, input, metadata.detail, metadata.response_preview, metadata.responseText, metadata.cwd, metadata.git all disappear. What’s left is tool names, timings, token counts, and identifiers — useful for dashboards, useless to anyone trying to reconstruct your work.
See the privacy overview field-by-field table for details.
Next
Data handling
Where data lives once it leaves your machine, retention, deletion flow.