Introduce package internal/scrub, a schema-agnostic, regex/heuristic
based redaction pass to run over raw bug-report payloads before storage
(#9). It masks (never deletes) matches with bracketed placeholders so
payload structure is preserved for triage.
Categories:
- Emails: robust address regex; ignores @handles and "meet @ 3pm".
- Auth tokens/secrets: Authorization/Proxy-Authorization header values,
standalone Bearer tokens, eyJ-anchored JWTs, well-known provider key
formats (GitHub, GitLab, Slack, Stripe, OpenAI, Google, AWS), and
values under secret-named keys (password, api_key, token, ...).
- IP addresses: octet-validated IPv4 and comprehensive IPv6 (full,
compressed, loopback, IPv4-mapped), ordered for correct extraction.
- Names: deliberately weak, key-directed heuristic (name/user/...),
\b-anchored to avoid filename/hostname collisions. Documented in code
as best-effort and NOT to be relied upon.
API: Scrub([]byte) []byte, ScrubString(string) string, plus composable
per-category RedactEmails/RedactTokens/RedactIPs/RedactNames and exported
Placeholder* constants. Non-mutating and idempotent. Build-tag-free so it
compiles for host and the Wasm target.
Tests cover each category with positive and over-redaction-guard cases
(89 passing checks); go test ./... is green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>