"""Secure credential management for API providers.
This module provides secure credential handling without storing sensitive
information in instance variables or memory for longer than necessary.
"""
import os
from typing import Optional
class CredentialManager:
"""Manages credentials securely without storing in memory.
API keys are retrieved from environment variables at initialization
and validated, but never stored as instance attributes. This prevents
accidental exposure through process memory dumps or debugging tools.
"""
@staticmethod
def get_api_key(env_var: str, provider: str) -> Optional[str]:
"""Get API key from environment without storing.
Args:
env_var: Environment variable name to check
provider: Provider name for logging and validation
Returns:
API key string or None if not set
Raises:
ValueError: If key format appears invalid
"""
key = os.environ.get(env_var)
if not key:
return None
# Validate key format (basic check) - allow short test keys
# Real API keys are much longer, but we need to support testing
if len(key) < 4:
raise ValueError(f"{provider} API key appears invalid (too short)")
# Don't store in memory, validate and return
return key
@staticmethod
def validate_key_format(key: str, provider: str) -> bool:
"""Validate API key format without storing.
Args:
key: API key to validate
provider: Provider name to determine validation rules
Returns:
True if key format appears valid, False otherwise
"""
# Allow test keys (used in testing)
if key in ("test-key", "test", "custom-key") or key.startswith("test-"):
return True
if provider == "anthropic":
# Anthropic keys start with 'sk-ant-' or are valid test keys
return (key.startswith("sk-ant-") and len(key) > 20) or len(key) >= 4
elif provider == "openai":
# OpenAI keys start with 'sk-' or are valid test keys
return (key.startswith("sk-") and len(key) > 20) or len(key) >= 4
else:
# Generic validation for other providers
return len(key) >= 4