Source code for wallet_key_utils

"""
Wallet Master Key Utilities

Shared logic for lazily loading 32-byte AES-256-GCM master keys for wallet
encryption. Keys are loaded exclusively from the configured environment
variable; the legacy Redis persistence/generation path has been removed for
security, so a missing or invalid key raises ``ValueError`` and disables
wallet features rather than minting a new key.
"""

import os
import base64
import logging
import socket
from datetime import datetime
from observability import observability

logger = logging.getLogger(__name__)


[docs] async def ensure_master_key( current_key: bytes | None, redis_client, redis_key: str, env_var: str, ) -> bytes: """Return a 32-byte AES master key, loading exclusively from the environment variable. Resolution order: 1. *current_key* – already loaded in memory (fast path). 2. Environment variable (*env_var*) – decode, validate. 3. If missing, log structured ASCII warning and raise exception to prevent unsafe operations. Args: current_key: The key already held in memory, or ``None``. redis_client: An async Redis client (ignored, as Redis key persistence is removed for security). redis_key: Redis key under which the master key was previously stored (ignored). env_var: Name of the environment variable to check. Returns: A 32-byte ``bytes`` master key. """ # 1. Already loaded if current_key is not None: return current_key # 2. Environment variable key_b64 = os.environ.get(env_var) if not key_b64: border = "#" * 80 platform_type = env_var.split("_")[1].lower() if "_" in env_var else "wallet" msg = ( f"\n{border}\n" f"SECURITY CRITICAL WARNING: Missing environment variable '{env_var}'.\n" "Stargazer v3 will boot in DEGRADED STATE. Wallet features are completely deactivated.\n" f"{border}" ) logger.error(msg) observability.alert( "CRITICAL", "Wallet Master Keys are missing. Startup proceeding with wallet features disabled.", metadata={ "hostname": socket.gethostname(), "platform": platform_type, "timestamp": datetime.utcnow().isoformat() + "Z", }, ) raise ValueError( f"Wallet master key environment variable '{env_var}' is missing. Wallet features are deactivated." ) try: key = base64.urlsafe_b64decode(key_b64) if len(key) != 32: raise ValueError( f"Invalid key length: must be exactly 32 bytes (256-bit). Got {len(key)} bytes." ) logger.info("Successfully loaded %s from environment variable.", env_var) return key except Exception as e: border = "#" * 80 logger.error( f"\n{border}\n" f"SECURITY CRITICAL WARNING: Failed to decode environment variable '{env_var}': {e}\n" "Stargazer v3 will boot in DEGRADED STATE. Wallet features are completely deactivated.\n" f"{border}", exc_info=True, ) observability.alert( "CRITICAL", "Wallet Master Keys are missing. Startup proceeding with wallet features disabled.", metadata={ "hostname": socket.gethostname(), "platform": ( env_var.split("_")[1].lower() if "_" in env_var else "wallet" ), "timestamp": datetime.utcnow().isoformat() + "Z", "error": str(e), }, ) raise ValueError(f"Failed to decode wallet master key from '{env_var}': {e}")