Skip to content

Masking

Opt-in masking of BaseError.debug_info.

BuiltInMaskingRule

Named immutable rules for common credentials and personal-data patterns.

These regexes detect text shapes, not verified secrets or identifiers. CARD_LIKE_LUHN does not perform a Luhn check, and IPV4 does not validate octet ranges. Consumers choose which rules to use; this package provides no default rule set.

Attributes:

Name Type Description
ANTHROPIC_KEY MaskingRule

Anthropic API keys.

AUTHORIZATION_HEADER MaskingRule

Authorization header values with a bearer or basic scheme.

AWS_ACCESS_KEY_ID MaskingRule

AWS access key IDs.

AWS_SECRET_KEY MaskingRule

AWS secret access keys.

AWS_SIGV4_QS MaskingRule

AWS SigV4 signature and credential query parameters.

BASIC_CREDENTIALS MaskingRule

Basic credentials.

BEARER_TOKEN MaskingRule

Bearer tokens.

CARD_LIKE_LUHN MaskingRule

Card-number-shaped digit runs.

CONN_STRING_CREDS MaskingRule

Credentials embedded in database and broker connection strings.

E2B_KEY MaskingRule

E2B API keys.

EMAIL MaskingRule

Email addresses.

FERNET_B64_WRAPPED MaskingRule

Base64-wrapped Fernet tokens.

FERNET_TOKEN MaskingRule

Fernet tokens.

GENERIC_CREDENTIAL_KV MaskingRule

Key-value pairs for common credential key names.

GITHUB_PAT_CLASSIC MaskingRule

Classic GitHub tokens.

GITHUB_PAT_FINE MaskingRule

Fine-grained GitHub personal access tokens.

GOOGLE_API_KEY MaskingRule

Google API keys.

GOOGLE_OAUTH_SECRET MaskingRule

Google OAuth client secrets.

HUGGINGFACE_TOKEN MaskingRule

Hugging Face tokens.

ID_MOBILE MaskingRule

Indonesian mobile numbers.

ID_NIK_CONTEXT MaskingRule

Indonesian NIK numbers that follow a nik or no_ktp label.

ID_NPWP MaskingRule

Indonesian NPWP tax numbers.

IPV4 MaskingRule

IPv4-shaped dotted numbers.

JWT MaskingRule

JSON Web Tokens.

OPENAI_KEY MaskingRule

OpenAI project and service account keys.

OPENROUTER_KEY MaskingRule

OpenRouter API keys.

PRIVATE_KEY_BLOCK MaskingRule

PEM private key blocks, including truncated ones.

SLACK_TOKEN MaskingRule

Slack tokens.

ErrorMaskingConfig

Bases: BaseModel

Policy installed through configure_error_masking.

Redaction is best effort: regex rules detect text shapes, not verified secrets. Keys are never masked.

Attributes:

Name Type Description
rules tuple[MaskingRule, ...]

Rules applied in order to text values.

deny_fields frozenset[str]

Exact, case-sensitive key names whose values are always redacted.

MaskingRule(*, name, pattern) dataclass

An immutable name and regex used to identify sensitive text.

Compilation creates the replacement [NAME] from the rule name. Substitution replaces the whole match and preserves the surrounding text. Construction validates the name; regex syntax is checked by CompiledMaskingRule.from_masking_rule.

Attributes:

Name Type Description
name str

The entity label, rendered as the placeholder (e.g. "EMAIL" -> [EMAIL]). Must be CAPITAL_CASE ASCII: an uppercase letter or underscore, followed by uppercase letters, digits, or underscores.

pattern str

The regex matching the sensitive region.

__post_init__()

Validates the rule name.

Raises:

Type Description
ValueError

If name is not CAPITAL_CASE ASCII.

configure_error_masking(config)

Replaces the process-wide masking policy, or disables masking with None.

Masking is disabled until a policy is installed. A rejected config leaves the previous policy active.

Examples:

configure_error_masking(
    ErrorMaskingConfig(rules=(BuiltInMaskingRule.EMAIL,), deny_fields=frozenset({"api_key"}))
)
error = BaseError("Failed", debug_info={"class_name": "X", "api_key": "k", "note": "a@b.com"})
error.debug_info  # {"class_name": "X", "api_key": "[Redacted]", "note": "[EMAIL]"}
configure_error_masking(None)  # Disable masking.

Parameters:

Name Type Description Default
config ErrorMaskingConfig | None

The new policy, or None to disable masking.

required

sanitize_debug_info(debug_info)

Returns a redacted copy of debug_info without modifying the input.

  1. Without a policy, or with a policy that has no rules and no denied fields, the copy is shallow and unchanged.
  2. A denied key becomes "[Redacted]" and a key that fails becomes "[Dropped]".
  3. An unreadable debug_info keeps only class_name, which is itself denied or masked.
  4. Any Exception is absorbed, so error construction never fails.
  5. A BaseError built while redacting, for example by a value's __str__, is copied unredacted to avoid re-entering the redaction.

Examples:

configure_error_masking(ErrorMaskingConfig(rules=(BuiltInMaskingRule.EMAIL,)))
sanitize_debug_info({"class_name": "X", "note": "a@b.com"})  # {"class_name": "X", "note": "[EMAIL]"}

Parameters:

Name Type Description Default
debug_info DebugInfo | Mapping[str, Any]

The diagnostics to redact.

required

Returns:

Name Type Description
DebugInfo DebugInfo

The redacted copy.