Redaction runs at capture time. A token in a query string never reaches the buffer, which means it cannot be recovered from a report even by us — the difference between “we do not show it” and “we do not have it”.
The rules
The engine ships a fixed rule set, shared with the other SDKs. It runs over
console lines, breadcrumb messages and data, network URLs, and network bodies.
| Pattern | Replaced with |
|---|---|
| JWTs | [REDACTED:jwt] |
Bearer … tokens | [REDACTED:bearer] |
| Card numbers that pass a Luhn check | [REDACTED:luhn-cc] |
| US social security numbers | [REDACTED:ssn-us] |
The Luhn check is what keeps phone numbers and order ids from being masked as cards — most long digit runs are not card numbers.
Headers
Request and response headers are default-deny:
| Header | What happens |
|---|---|
Content-Type, Content-Length, Cache-Control, X-Request-ID, X-Trace-ID, X-Correlation-ID | Kept verbatim. |
Authorization, Cookie, Set-Cookie, Proxy-Authorization, X-Api-Key | Value replaced with [REDACTED]. |
| Anything else | Dropped entirely. |
RedactionConfig is not read yet
TraceItXConfig accepts a redaction: RedactionConfig with defaultDeny,
allowlistedHeaders and customPatterns. The SDK does not read it today.
The defaults describe the shipped behaviour above, but changing them — adding a
custom NSRegularExpression, allowing an extra header — has no effect on what is
captured.
// Compiles, but changes nothing today.
TraceItXConfig(appId: "txx_live_…", redaction: RedactionConfig(customPatterns: [account]))
If a value your app logs needs masking and no shipped rule catches it, do not log it.
What redaction does not cover
Pixels. A card number rendered on screen is caught by
markSensitive, not by a rule — the engine reads text,
not images.
Screen names. A name passed to recordScreen passes through the same
rules, but redaction recognises shapes, not meaning: an order id or a username
built from user data becomes a navigation crumb verbatim. See
Screen tracking.
Exception messages. An NSException reason string is recorded as thrown,
after the rules above. If your app puts user data in exception messages, that
reaches the breadcrumb.
Server-side safety net
Ingest runs a subset of these rules again on arrival. It is idempotent and deliberately narrower than the client engine — it exists to catch an SDK that is old or misconfigured, not to replace client-side redaction. By the time it runs, the data has already left the device.