Automatically mask sensitive values (API keys, passwords, tokens) in logs and print output
pip install philiprehberger-masked-print
Automatically mask sensitive values (API keys, passwords, tokens) in logs and print output.
pip install philiprehberger-masked-print
from philiprehberger_masked_print import mask, mask_dict, MaskedFormatter
# Mask a single string
masked = mask("sk-abc123secret456xyz")
# "sk-a*************xyz"
config = {
"host": "localhost",
"password": "super-secret-value",
"database": {
"connection_string": "postgres://admin:pass@localhost/db",
},
}
safe = mask_dict(config)
# {
# "host": "localhost",
# "password": "supe***********lue",
# "database": {
# "connection_string": "post*****************/db",
# },
# }
mask_dict() accepts dotted path globs to mask specific nested fields without touching the default key heuristics.
config = {
"database": {
"primary": {"host": "db1", "password": "p1"},
"replica": {"host": "db2", "password": "p2"},
},
"auth": {"public_key": "pk", "token": "tk"},
}
safe = mask_dict(
config,
paths=["database.*.password", "auth.token"],
)
# database.primary.password and database.replica.password are masked
# auth.token is masked; auth.public_key is left alone
A * in a path glob matches a single segment. Path matching runs in addition to the default sensitive_keys matching, so both rule sets compose.
from philiprehberger_masked_print import register_pattern, register_sensitive_key
# Add a domain-specific secret pattern picked up by MaskedFormatter
register_pattern(r"PINPIN-\d{4,}")
# Add a custom key that mask_dict should treat as sensitive
register_sensitive_key("session_id")
import logging
from philiprehberger_masked_print import MaskedFormatter
handler = logging.StreamHandler()
handler.setFormatter(MaskedFormatter("%(levelname)s: %(message)s"))
logger = logging.getLogger("app")
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
logger.info("Using key sk-proj-abc123def456ghi789jkl012mno")
# INFO: Using key sk-p*************************mno
| Function / Class | Description |
|---|---|
mask(value, *, show_first=4, show_last=3, mask_char="*") | Mask a string, keeping the first and last N characters visible |
mask_dict(data, *, sensitive_keys=None, paths=None, show_first=4, show_last=3) | Recursively mask sensitive key values; paths targets nested keys with dotted globs like "database.*.password" |
MaskedFormatter(fmt) | Logging formatter that auto-redacts secret patterns (sk-..., eyJ..., AKIA..., URL credentials) |
register_pattern(pattern) | Register an extra regex pattern for MaskedFormatter to redact |
register_sensitive_key(key) | Add a key substring to the default sensitive-key set used by mask_dict |
pip install -e .
python -m pytest tests/ -v
If you find this project useful: