Skip to content

Redaction

In the agent process, before the event leaves the host. z4j never sees unredacted values. This is critical: even a compromised brain cannot exfiltrate your secrets from historical events because they were never sent in the first place. The canonical pattern catalog lives in z4j_core.redaction.patterns.

Default key-name patterns (full-match, case-insensitive)

Section titled “Default key-name patterns (full-match, case-insensitive)”

Field names that match any of these regexes have their value replaced with the redaction marker:

  • Passwords: password, password_confirmation, password_hash, passwd, pwd, old_password, new_password.
  • Secrets: secret, secrets, client_secret, webhook_secret.
  • Tokens: token, access_token, refresh_token, id_token, api_token, bearer_token, session_token.
  • API keys: api_key (also apikey, api-key), x-api-key, x_api_key.
  • Authorization and cookies: authorization, auth, credentials, cookie, set-cookie, set_cookie.
  • Personal identifiers: ssn, social_security, social_security_number, credit_card, credit_card_number, card_number, cvv, cvc.

Default value patterns (substring match, case-insensitive)

Section titled “Default value patterns (substring match, case-insensitive)”

String values that match any of these regexes are fully redacted regardless of the surrounding key name:

  • JWT (eyJ... three-segment base64).
  • Authorization: Bearer <16+ chars>.
  • Stripe (sk_live_*, sk_test_*, pk_live_*, pk_test_*, whsec_*, rk_live_*).
  • Slack tokens (xoxb-, xoxp-, xoxa-) and Slack incoming-webhook URLs.
  • GitHub PATs (ghp_, gho_, ghs_) and fine-grained PATs (github_pat_).
  • AWS access key IDs (AKIA..., ASIA... for STS).
  • Google Cloud / Firebase API keys (AIza...).
  • Twilio account tokens (SK[hex32]).
  • SendGrid API keys (SG.<base64>.<base64>).
  • Database URIs with embedded credentials (postgresql://user:pw@host, mysql://, mongodb://, mongodb+srv://, redis://, rediss://, amqp://, amqps://).
  • PEM private key BEGIN lines (-----BEGIN RSA PRIVATE KEY-----, etc.).
  • Email addresses (PII for most apps; reduced to a placeholder).
  • US SSN format (XXX-XX-XXXX).

Long strings are length-tagged (<str len=142>) and binary / bytes payloads become <bytes len=N>.

Per-project overrides land in the project’s settings (redaction_overrides):

{
"redaction_overrides": {
"field_names": ["internal_token", "my_secret_field"],
"patterns": ["^user-[0-9a-f]{8}-secret-[0-9a-f]{16}$"]
}
}

Overrides are additive to the built-in rules, never subtractive. If a built-in rule produces false positives for your domain, rename the field rather than disabling the rule.

  • Task names (email.send vs email.send_welcome). Operator metadata, not secrets.
  • Queue names and routing keys.
  • Error class names (ValueError, MyDomainError).
  • Error messages — be careful. An error message containing a known secret pattern (e.g. “invalid API key: sk_live_abc123”) will be redacted via value-pattern match, but custom exception types that interpolate secrets into their message in a non-matching shape are your risk.

Tracebacks are scrubbed line-by-line with the same rules. Stack frames preserve file, line, and function name; local-variable values fall under the key-name and value-pattern rules.

  • Single argument value: 64 KiB max; truncated above.
  • Total event payload: 2 MiB max; truncated above.

These caps keep the redactor and the wire bounded.

A kwarg called password_hint is redacted because password is a substring of the field name and the engine uses fullmatch with case-insensitivity (the regex password matches when the field is exactly password; longer field names are matched only when they appear in the pattern list). Inspect the patterns above; rename or add an override if you have a legitimate non-secret field that collides.

Not supported. If your workload genuinely has no secrets and you want raw values in events, you are likely using the wrong tool.