Redaction Configuration

How to configure redaction using the Builder API, Settings, or environment variables.

Settings Object

For programmatic configuration without the builder:

from fapilog import get_logger, Settings

settings = Settings(
    core={
        "redactors": [
            "field_mask",
            "regex_mask",
            "url_credentials",
            "field_blocker",
            "string_truncate",
        ],
    },
    redactor_config={
        "field_mask": {
            "fields_to_mask": ["data.password", "data.api_key", "data.secret"],
            "mask_string": "***",
        },
        "regex_mask": {
            "patterns": [
                r"(?i).*password.*",
                r"(?i).*secret.*",
                r"(?i).*token.*",
            ],
            "mask_string": "***",
        },
        "field_blocker": {
            "blocked_fields": ["body", "request_body", "payload"],
            "allowed_fields": [],
        },
        "string_truncate": {
            "max_string_length": 1000,
        },
    },
)

logger = get_logger(settings=settings)

Redactor Order

Control the order redactors are applied:

settings = Settings(
    core={
        "redactors": [
            "field_mask",
            "regex_mask",
            "url_credentials",
            "field_blocker",
            "string_truncate",
        ],
    }
)

Default order:

  1. field_mask - Exact field path matching

  2. regex_mask - Pattern-based matching

  3. url_credentials - URL credential stripping

  4. field_blocker - High-risk field blocking

  5. string_truncate - Long string truncation

Guardrails

Set limits to prevent performance issues:

settings = Settings(
    core={
        "redaction_max_depth": 16,
        "redaction_max_keys_scanned": 1000,
    }
)

Environment Variables

Configure redaction via environment:

# Enable specific redactors
export FAPILOG_CORE__REDACTORS='["field_mask", "regex_mask", "url_credentials", "field_blocker", "string_truncate"]'

# Configure field mask
export FAPILOG_REDACTOR_CONFIG__FIELD_MASK__FIELDS_TO_MASK='["password", "api_key"]'
export FAPILOG_REDACTOR_CONFIG__FIELD_MASK__MASK_STRING='[REDACTED]'

# Configure regex mask
export FAPILOG_REDACTOR_CONFIG__REGEX_MASK__PATTERNS='["(?i).*secret.*", "(?i).*token.*"]'

# Configure field blocker
export FAPILOG_REDACTOR_CONFIG__FIELD_BLOCKER__BLOCKED_FIELDS='["body", "request_body", "payload"]'
export FAPILOG_REDACTOR_CONFIG__FIELD_BLOCKER__REPLACEMENT='[BLOCKED]'

# Configure string truncate
export FAPILOG_REDACTOR_CONFIG__STRING_TRUNCATE__MAX_STRING_LENGTH=1000

# Guardrails
export FAPILOG_CORE__REDACTION_MAX_DEPTH=16
export FAPILOG_CORE__REDACTION_MAX_KEYS_SCANNED=1000

Default Behavior by Preset

Configuration

field_mask

regex_mask

url_credentials

field_blocker

string_truncate

Settings() (no preset)

No

No

Yes

No

No

preset="dev"

No

No

No

No

No

preset="production"

Yes

Yes

Yes

No

No

preset="serverless"

Yes

Yes

Yes

No

No

preset="hardened"

Yes

Yes

Yes

Yes

No

preset="minimal"

No

No

No

No

No

The production, fastapi, and serverless presets automatically apply the CREDENTIALS redaction preset. The hardened preset additionally enables field_blocker with default blocked fields and applies the HIPAA_PHI and PCI_DSS presets.

Disabling Redaction

URL credential redaction is enabled by default. To disable all redaction:

# Via Settings
settings = Settings(
    core={"redactors": []},  # Empty list disables all
)

# Or disable the redactors stage entirely
settings = Settings(
    core={"enable_redactors": False},
)

Note: The dev and minimal presets explicitly disable redaction for development visibility.

Extending Production Preset

To add compliance presets to the production configuration:

from fapilog import LoggerBuilder

logger = (
    LoggerBuilder()
    .with_preset("production")  # Includes CREDENTIALS
    .with_redaction(preset="HIPAA_PHI")  # Add HIPAA protection
    .with_redaction(fields=["internal_id"])  # Add custom fields
    .build()
)

Regex Pattern Safety

The regex-mask redactor validates patterns at config time to prevent ReDoS (Regular Expression Denial of Service) attacks. Patterns with these constructs are rejected:

  • Nested quantifiers: (a+)+, (a*)*, (a+)*

  • Alternation with quantifiers: (a|aa)+, (foo|foobar)*

  • Wildcards in bounded repetition: (.*a){10,}

Safe Patterns

# These are safe and accepted
patterns = [
    r"user\.email",              # Literal path
    r"user\..*\.secret",         # Simple wildcard
    r"request\.headers\.[^.]+",  # Character class
    r"(password|secret|token)",  # Alternation without quantifier
]

Patterns to Avoid

# These are rejected by default
patterns = [
    r"(a+)+",           # Nested quantifiers - exponential backtracking
    r"(a|aa)+",         # Overlapping alternation - exponential backtracking
    r"(.*a){10,}",      # Wildcard in repetition - exponential backtracking
]

Escape Hatch

If you understand the risks and need to use a pattern that triggers validation:

from fapilog.redaction import RegexMaskConfig

config = RegexMaskConfig(
    patterns=[r"(complex|pattern)+"],
    allow_unsafe_patterns=True,  # Bypasses ReDoS validation
)

Warning: Only use allow_unsafe_patterns=True if you’ve verified the pattern won’t cause catastrophic backtracking with your data.