/

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:

Python
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:

Python
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:

Python
# 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:

Python
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:

Python
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:

Python
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 configuration

Custom Masking Patterns

Configure masking for fields with specific patterns:

Python
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:

Python
# 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

Environment Variable Protection

Mask environment variables that contain secrets:

Python
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:

Python
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:

Python
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:

Python
# 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

Python
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

Previous
Basic Logging