Data Masking
Data Masking
Protect sensitive information by automatically masking fields like passwords, tokens, API keys, and credit card numbers. Data masking ensures compliance and prevents accidental exposure of secrets in logs.
Configuring Sensitive Fields
Use LogSettings to specify which fields should be masked:
from bytehide_logs import Log, LogSettings
# Configure masking for sensitive fields
settings = LogSettings(
mask_sensitive_data=["password", "token", "api_key", "secret"]
)
Log.configure(settings)
# Now these fields are automatically masked
Log.info("User authentication", context={
"username": "alice@example.com",
"password": "super_secret_123", # Will be masked
"api_key": "sk_live_abc123xyz" # Will be masked
})from bytehide_logs import Log, LogSettings
# Configure masking for sensitive fields
settings = LogSettings(
mask_sensitive_data=["password", "token", "api_key", "secret"]
)
Log.configure(settings)
# Now these fields are automatically masked
Log.info("User authentication", context={
"username": "alice@example.com",
"password": "super_secret_123", # Will be masked
"api_key": "sk_live_abc123xyz" # Will be masked
})Common Sensitive Fields
Standard fields to mask in most applications:
settings = LogSettings(
mask_sensitive_data=[
# Authentication
"password",
"token",
"refresh_token",
"session_token",
"auth_token",
# API & Services
"api_key",
"secret_key",
"secret",
"api_secret",
# Payment
"credit_card",
"card_number",
"cvv",
"routing_number",
"account_number",
# Personal
"ssn",
"social_security_number",
"passport_number",
# Keys & Certificates
"private_key",
"signing_key",
"certificate",
]
)
Log.configure(settings)settings = LogSettings(
mask_sensitive_data=[
# Authentication
"password",
"token",
"refresh_token",
"session_token",
"auth_token",
# API & Services
"api_key",
"secret_key",
"secret",
"api_secret",
# Payment
"credit_card",
"card_number",
"cvv",
"routing_number",
"account_number",
# Personal
"ssn",
"social_security_number",
"passport_number",
# Keys & Certificates
"private_key",
"signing_key",
"certificate",
]
)
Log.configure(settings)Masking Examples
Before and after masking:
# Before masking is applied
Log.info("Payment processing", context={
"card_number": "4532-1234-5678-9010",
"cvv": "123",
"amount": 99.99
})
# Output (with mask_sensitive_data=["card_number", "cvv"]):
# {
# "message": "Payment processing",
# "card_number": "****",
# "cvv": "****",
# "amount": 99.99
# }# Before masking is applied
Log.info("Payment processing", context={
"card_number": "4532-1234-5678-9010",
"cvv": "123",
"amount": 99.99
})
# Output (with mask_sensitive_data=["card_number", "cvv"]):
# {
# "message": "Payment processing",
# "card_number": "****",
# "cvv": "****",
# "amount": 99.99
# }Nested Sensitive Data
Masking works with nested context objects:
Log.info("Creating API key", context={
"user_id": "user_123",
"api_key": "sk_test_4eC39HqLyjWDarhtT657L0df", # Masked
"permissions": ["read", "write"],
"auth": {
"token": "super_secret_xyz", # Masked even in nested objects
"expires_at": "2026-12-31"
}
})Log.info("Creating API key", context={
"user_id": "user_123",
"api_key": "sk_test_4eC39HqLyjWDarhtT657L0df", # Masked
"permissions": ["read", "write"],
"auth": {
"token": "super_secret_xyz", # Masked even in nested objects
"expires_at": "2026-12-31"
}
})Exception Masking
Sensitive data in exceptions is also masked:
try:
authenticate(password="user_secret_pass")
except AuthenticationError as e:
Log.error(
"Authentication failed",
exception=e, # Exception message with password is masked
context={
"password_attempt": "bad_secret" # Masked
}
)try:
authenticate(password="user_secret_pass")
except AuthenticationError as e:
Log.error(
"Authentication failed",
exception=e, # Exception message with password is masked
context={
"password_attempt": "bad_secret" # Masked
}
)User Tokens Are Automatically Masked
The AuthUser token field is automatically masked without explicit configuration:
from bytehide_logs import AuthUser
user = AuthUser(
id="user_123",
email="alice@example.com",
token="secret_session_token_xyz" # Automatically masked
)
Log.identify(user)
Log.info("User identified")
# Token is masked even without mask_sensitive_data configurationfrom bytehide_logs import AuthUser
user = AuthUser(
id="user_123",
email="alice@example.com",
token="secret_session_token_xyz" # Automatically masked
)
Log.identify(user)
Log.info("User identified")
# Token is masked even without mask_sensitive_data configurationCustom Masking Patterns
Configure masking for fields with specific patterns:
settings = LogSettings(
mask_sensitive_data=[
"password",
"api_*", # Matches api_key, api_secret, api_token, etc.
"*_token", # Matches refresh_token, session_token, auth_token, etc.
"*_key", # Matches private_key, public_key, etc.
]
)
Log.configure(settings)
# All matching fields are masked
Log.info("Configuration loaded", context={
"api_key": "secret_key", # Masked by "api_*"
"api_secret": "secret_secret", # Masked by "api_*"
"refresh_token": "xyz", # Masked by "*_token"
"private_key": "abc", # Masked by "*_key"
"app_name": "MyApp" # Not masked
})settings = LogSettings(
mask_sensitive_data=[
"password",
"api_*", # Matches api_key, api_secret, api_token, etc.
"*_token", # Matches refresh_token, session_token, auth_token, etc.
"*_key", # Matches private_key, public_key, etc.
]
)
Log.configure(settings)
# All matching fields are masked
Log.info("Configuration loaded", context={
"api_key": "secret_key", # Masked by "api_*"
"api_secret": "secret_secret", # Masked by "api_*"
"refresh_token": "xyz", # Masked by "*_token"
"private_key": "abc", # Masked by "*_key"
"app_name": "MyApp" # Not masked
})Partial Masking
Show partial information while masking sensitive data:
# Log with partially visible token for debugging
Log.info("Token usage", context={
"token": "sk_live_abc123xyz...", # Last part visible
"token_prefix": "sk_live",
"user_id": "user_456"
})
# Query logs with prefix to debug token issues
# Query: token_prefix:"sk_live" AND level:error# Log with partially visible token for debugging
Log.info("Token usage", context={
"token": "sk_live_abc123xyz...", # Last part visible
"token_prefix": "sk_live",
"user_id": "user_456"
})
# Query logs with prefix to debug token issues
# Query: token_prefix:"sk_live" AND level:errorEnvironment Variable Protection
Mask environment variables that contain secrets:
import os
from bytehide_logs import Log, LogSettings
# Mask environment-sourced sensitive data
api_key = os.environ.get("API_KEY") # From environment
settings = LogSettings(
mask_sensitive_data=[
"api_key",
"database_password",
"oauth_secret"
]
)
Log.configure(settings)
Log.info("Connecting to service", context={
"api_key": api_key, # Masked automatically
"service": "external_api"
})import os
from bytehide_logs import Log, LogSettings
# Mask environment-sourced sensitive data
api_key = os.environ.get("API_KEY") # From environment
settings = LogSettings(
mask_sensitive_data=[
"api_key",
"database_password",
"oauth_secret"
]
)
Log.configure(settings)
Log.info("Connecting to service", context={
"api_key": api_key, # Masked automatically
"service": "external_api"
})Database Connection Masking
Mask database credentials:
settings = LogSettings(
mask_sensitive_data=[
"password",
"connection_string",
"database_url"
]
)
Log.configure(settings)
Log.info("Database connected", context={
"database_url": "postgresql://user:password@localhost/dbname", # Masked
"host": "localhost",
"database": "mydb"
})settings = LogSettings(
mask_sensitive_data=[
"password",
"connection_string",
"database_url"
]
)
Log.configure(settings)
Log.info("Database connected", context={
"database_url": "postgresql://user:password@localhost/dbname", # Masked
"host": "localhost",
"database": "mydb"
})API Request/Response Masking
Mask sensitive API data:
from bytehide_logs import Log, LogSettings
settings = LogSettings(
mask_sensitive_data=[
"authorization",
"bearer_token",
"api_key",
"credit_card",
"sensitive_field"
]
)
Log.configure(settings)
def make_api_call(api_endpoint, headers, body):
"""Make API call with sensitive data masking."""
Log.info("Making API request", context={
"endpoint": api_endpoint,
"headers": {
"authorization": headers.get("Authorization"), # Masked
"content_type": "application/json"
},
"body_fields": list(body.keys()) # Keys visible, sensitive values masked
})
response = requests.post(api_endpoint, json=body, headers=headers)
Log.info("API response received", context={
"status_code": response.status_code,
"response": response.json() # Sensitive fields masked
})from bytehide_logs import Log, LogSettings
settings = LogSettings(
mask_sensitive_data=[
"authorization",
"bearer_token",
"api_key",
"credit_card",
"sensitive_field"
]
)
Log.configure(settings)
def make_api_call(api_endpoint, headers, body):
"""Make API call with sensitive data masking."""
Log.info("Making API request", context={
"endpoint": api_endpoint,
"headers": {
"authorization": headers.get("Authorization"), # Masked
"content_type": "application/json"
},
"body_fields": list(body.keys()) # Keys visible, sensitive values masked
})
response = requests.post(api_endpoint, json=body, headers=headers)
Log.info("API response received", context={
"status_code": response.status_code,
"response": response.json() # Sensitive fields masked
})Compliance & Security
Data masking helps meet compliance requirements:
# GDPR & CCPA Compliance
# - Protect personally identifiable information
# - Prevent accidental exposure in logs
# - Simplify log retention policies
# Security Best Practices
# - Never log plaintext passwords
# - Mask authentication credentials
# - Protect API keys and secrets
# - Redact payment information
settings = LogSettings(
mask_sensitive_data=[
# GDPR: Personal Information
"password",
"email_address",
"phone_number",
# CCPA: Consumer Privacy
"credit_card",
"ssn",
# Security: Credentials
"api_key",
"secret",
"token",
]
)
Log.configure(settings)# GDPR & CCPA Compliance
# - Protect personally identifiable information
# - Prevent accidental exposure in logs
# - Simplify log retention policies
# Security Best Practices
# - Never log plaintext passwords
# - Mask authentication credentials
# - Protect API keys and secrets
# - Redact payment information
settings = LogSettings(
mask_sensitive_data=[
# GDPR: Personal Information
"password",
"email_address",
"phone_number",
# CCPA: Consumer Privacy
"credit_card",
"ssn",
# Security: Credentials
"api_key",
"secret",
"token",
]
)
Log.configure(settings)Complete Example
from bytehide_logs import Log, LogSettings
import os
# Configure masking for your application
settings = LogSettings(
mask_sensitive_data=[
"password",
"token",
"api_key",
"secret",
"credit_card",
"cvv",
"authorization",
"database_password"
]
)
Log.configure(settings)
def handle_payment(payment_data):
"""Handle payment with secure logging."""
# Log operation without exposing sensitive data
Log.info("Payment processing initiated", context={
"user_id": payment_data["user_id"],
"amount": payment_data["amount"],
"credit_card": "****1234", # Safe partial info
"card_number": payment_data["card_number"] # Automatically masked
})
try:
result = process_payment(payment_data)
Log.info("Payment successful", context={
"user_id": payment_data["user_id"],
"transaction_id": result["transaction_id"]
})
except Exception as e:
Log.error(
"Payment failed",
exception=e,
context={
"user_id": payment_data["user_id"],
"error_details": str(e) # Masked if contains sensitive data
}
)
def authenticate_api(api_key):
"""Authenticate with API key (safely logged)."""
Log.info("Authenticating with API", context={
"api_key": api_key, # Automatically masked
"service": "payment_gateway"
})
return authenticate(api_key)from bytehide_logs import Log, LogSettings
import os
# Configure masking for your application
settings = LogSettings(
mask_sensitive_data=[
"password",
"token",
"api_key",
"secret",
"credit_card",
"cvv",
"authorization",
"database_password"
]
)
Log.configure(settings)
def handle_payment(payment_data):
"""Handle payment with secure logging."""
# Log operation without exposing sensitive data
Log.info("Payment processing initiated", context={
"user_id": payment_data["user_id"],
"amount": payment_data["amount"],
"credit_card": "****1234", # Safe partial info
"card_number": payment_data["card_number"] # Automatically masked
})
try:
result = process_payment(payment_data)
Log.info("Payment successful", context={
"user_id": payment_data["user_id"],
"transaction_id": result["transaction_id"]
})
except Exception as e:
Log.error(
"Payment failed",
exception=e,
context={
"user_id": payment_data["user_id"],
"error_details": str(e) # Masked if contains sensitive data
}
)
def authenticate_api(api_key):
"""Authenticate with API key (safely logged)."""
Log.info("Authenticating with API", context={
"api_key": api_key, # Automatically masked
"service": "payment_gateway"
})
return authenticate(api_key)Next Steps
- Learn about exception handling to safely log errors
- Explore user identification for secure user tracking
- Discover metadata context for detailed context management