What rtb-redact does not do¶
A pattern catalogue never reaches complete recall, and a crate this small has a deliberately narrow job. This page is the honest inventory: what is out of scope, what is absent on purpose, and what will still get through. Design around these rather than discovering them.
For the per-rule detail — exact patterns, thresholds and examples — see Redaction rules.
It is not a guarantee, and not a security boundary¶
string is a safety net at the edge, not a control you can point at in a threat
model and call the problem solved. It reduces the blast radius of an accident.
It does not make it safe to send untrusted strings to a third party on purpose.
Anywhere you knowingly hold a credential, strip it at the source as well. The net is for the ones you did not know were there.
It cannot catch a shape it has never seen¶
A credential in a bespoke or internal format — a signed cookie your own service mints, a licence key, a partner's non-standard token — matches no named rule. It is caught only if it happens to be a whitespace-bounded run of 40 or more characters from the base64 alphabet, and that depends on the punctuation around it rather than on the token.
Formats the crate does not know include GitHub fine-grained PATs
(github_pat_…), GitLab runner and deploy tokens (glrt-, gldt-), Stripe
keys, and anything internal. Cover a secret the rules
miss is the practical answer.
Short secrets slip through¶
Below the thresholds, nothing happens: a provider-prefixed token under 20 characters, a JWT under 100, an opaque run under 40. A high-entropy but short secret — a six-digit TOTP code, a short PIN, a compact session id — is not redacted, and cannot be without destroying ordinary text.
Structured data is not parsed¶
Every rule works on flat text. JSON, YAML and TOML are not understood, and the
key/value separator they use is :, not =:
A secret inside a serialised payload is caught only if the value itself
matches a rule — a sk-ant-… token in JSON is redacted by the prefix rule, a
plain password is not. If you log structured payloads, redact the fields before
serialising rather than the JSON afterwards.
Header values are not redacted by string¶
SENSITIVE_HEADERS lists header names, and string does not consult it. A
header line pasted into free text is only redacted if some other rule happens
to fire:
in : Cookie: session=abc123; theme=dark out: unchanged
in : x-api-key: sk-abcdef1234567890abcdef out: x-api-key: [redacted]
The second one is redacted by the sk- prefix rule, not because x-api-key is
a known header. Redacting headers is a separate, explicit call — see
Redact HTTP headers.
Typed secrets are a different tool's job¶
rtb-redact operates on strings that have already been assembled. Preventing a
secret from being formatted into a string in the first place is what
secrecy::SecretString is for, which is what
rtb-credentials uses to hold tokens.
Use both. The typed wrapper stops the credentials you know about from being
printed; rtb-redact catches the ones that arrived inside somebody else's
string.
Telemetry attributes are not automatically redacted¶
Within the toolkit, rtb-telemetry runs string over an event's args and
err_msg before an out-of-process sink serialises them. attrs are not
covered. Callers own redaction for attribute values — either use stable
enumerated values, or run rtb_redact::string over them yourself before
attaching them.
There is no report of what was removed¶
Redaction is one-way and silent. The functions return the scrubbed string and
nothing else: no count, no list of which rules fired, no way to reverse it and
no marker distinguishing "a token was here" from "a git hash was here" — both
become the same [redacted].
If you need to know that a redaction happened, compare against the input, or
match on Cow::Borrowed versus Cow::Owned from string, which tells you
whether anything changed.
Non-ASCII secrets are not matched¶
Every pattern uses ASCII character classes. Non-ASCII text passes through untouched — which is right for prose, and means a credential containing non-ASCII characters will not be recognised. Real provider tokens are ASCII, so this is a narrow gap, but it is a gap.
It does not stream, and it does not bound input size¶
The whole string is held in memory and copied. There is no incremental or reader-based API, so a very large payload is redacted by materialising a second copy of it. Redact log lines and event fields, not multi-megabyte bodies.
It cannot be extended from outside the crate¶
No feature flags, no options struct, no pattern registration, no way to change
the [redacted] marker. This is deliberate — see Why there is nothing to
configure — but it
does mean a missing pattern is a change to this crate rather than a setting in
yours.
Related¶
- Why rtb-redact matches shapes, not values
- Redaction rules — what each rule does and does not match
- Cover a secret the rules miss