add api secrets seperate from .env
This commit is contained in:
+52
-3
@@ -51,19 +51,68 @@ def _setup_file_logging():
|
||||
logger.addHandler(file_handler)
|
||||
return logger
|
||||
|
||||
def _mask_sensitive_data(msg: str) -> str:
|
||||
"""Mask API keys and other sensitive data in log messages"""
|
||||
import re
|
||||
|
||||
# List of patterns to mask
|
||||
sensitive_patterns = [
|
||||
(r'api_key=([a-zA-Z0-9_\-]+)', r'api_key=***masked***'),
|
||||
(r'password=([^\s&]+)', r'password=***masked***'),
|
||||
(r'token=([a-zA-Z0-9_\-]+)', r'token=***masked***'),
|
||||
(r'key=([a-zA-Z0-9_\-]{8,})', r'key=***masked***'), # Keys longer than 8 chars
|
||||
(r'([a-zA-Z0-9]{32,})', lambda m: m.group(1)[:8] + '***masked***' if len(m.group(1)) > 16 else m.group(1)) # Long strings likely to be keys
|
||||
]
|
||||
|
||||
masked_msg = msg
|
||||
for pattern, replacement in sensitive_patterns:
|
||||
if isinstance(replacement, str):
|
||||
masked_msg = re.sub(pattern, replacement, masked_msg, flags=re.IGNORECASE)
|
||||
else:
|
||||
masked_msg = re.sub(pattern, replacement, masked_msg, flags=re.IGNORECASE)
|
||||
|
||||
return masked_msg
|
||||
|
||||
def _log(level: str, msg: str):
|
||||
"""Enhanced logging that writes to both console and file"""
|
||||
print(f"[{datetime.now(timezone.utc).isoformat(timespec='seconds')}] {level}: {msg}")
|
||||
"""Enhanced logging that writes to both console and file with sensitive data masking"""
|
||||
masked_msg = _mask_sensitive_data(msg)
|
||||
print(f"[{datetime.now(timezone.utc).isoformat(timespec='seconds')}] {level}: {masked_msg}")
|
||||
|
||||
try:
|
||||
file_logger = _setup_file_logging()
|
||||
getattr(file_logger, level.lower(), file_logger.info)(msg)
|
||||
getattr(file_logger, level.lower(), file_logger.info)(masked_msg)
|
||||
except Exception as e:
|
||||
print(f"File logging error: {e}")
|
||||
|
||||
# Initialize logging
|
||||
_setup_file_logging()
|
||||
|
||||
def _load_environment_files():
|
||||
"""Load environment variables from .env and optionally .env.secrets"""
|
||||
from pathlib import Path
|
||||
|
||||
# Try to load from python-dotenv if available
|
||||
try:
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load main .env file
|
||||
env_file = Path(".env")
|
||||
if env_file.exists():
|
||||
load_dotenv(env_file)
|
||||
_log("INFO", f"Loaded environment from {env_file}")
|
||||
|
||||
# Load secrets file if it exists
|
||||
secrets_file = Path(".env.secrets")
|
||||
if secrets_file.exists():
|
||||
load_dotenv(secrets_file)
|
||||
_log("INFO", f"Loaded secrets from {secrets_file}")
|
||||
|
||||
except ImportError:
|
||||
_log("WARNING", "python-dotenv not available - environment files not loaded")
|
||||
|
||||
# Load environment files at startup
|
||||
_load_environment_files()
|
||||
|
||||
def _bool_env(name: str, default: bool) -> bool:
|
||||
v = os.environ.get(name)
|
||||
if v is None:
|
||||
|
||||
Reference in New Issue
Block a user