Key Management API
This module provides tools for securely managing encryption keys and other secrets using HashiCorp Vault, implementing best practices for secure key storage, rotation, and access.
KeyManager Class
- class secureml.key_management.KeyManager(vault_url: str | None = None, vault_token: str | None = None, vault_path: str = 'secureml', use_env_fallback: bool = True, use_default_fallback: bool = False)
Manage encryption keys and other secrets for SecureML operations.
This class provides methods for retrieving and managing secrets from various backends, with a primary focus on HashiCorp Vault for production environments and fallback to environment variables or default values for development.
- __init__(vault_url: str | None = None, vault_token: str | None = None, vault_path: str = 'secureml', use_env_fallback: bool = True, use_default_fallback: bool = False)
Initialize the key manager.
- Args:
vault_url: URL for the HashiCorp Vault server vault_token: Authentication token for Vault vault_path: Base path in Vault where SecureML secrets are stored use_env_fallback: Whether to fall back to environment variables if Vault is unavailable use_default_fallback: Whether to fall back to default values (DEVELOPMENT ONLY)
- derive_key(base_key: str | bytes, purpose: str, key_bytes: int = 32) bytes
Derive a purpose-specific key from a base key.
This implements key separation, allowing different keys to be used for different purposes while all being derived from a single master key.
- Args:
base_key: The base key to derive from purpose: A string describing the key’s purpose key_bytes: Length of the derived key in bytes
- Returns:
The derived key as bytes
- get_encryption_key(key_name: str = 'master_key', key_bytes: int = 32, encoding: str = 'bytes') bytes | str
Get an encryption key from the secret backend.
- Args:
key_name: Name of the key to retrieve key_bytes: Number of bytes for the key (if generating a default) encoding: Output encoding (‘bytes’, ‘hex’, or ‘base64’)
- Returns:
The encryption key in the requested encoding
- get_secret(secret_name: str, default: Any | None = None) Any
Retrieve a secret from the configured backend.
This method attempts to retrieve the secret from Vault first, then falls back to environment variables, and finally to the provided default value if allowed.
- Args:
secret_name: Name of the secret to retrieve default: Default value to return if the secret is not found
- Returns:
The secret value if found, otherwise the default value
- Raises:
ValueError: If no secret is found and no default is provided or allowed
- set_secret(secret_name: str, value: Any) bool
Store a secret in Vault.
- Args:
secret_name: Name of the secret to store value: Value of the secret
- Returns:
True if the secret was stored successfully, False otherwise
The KeyManager class provides methods for retrieving and managing secrets from various backends, with a primary focus on HashiCorp Vault for production environments and fallback to environment variables or default values for development.
Basic Usage Example:
from secureml.key_management import KeyManager
# Initialize a key manager
key_manager = KeyManager(
vault_url="https://vault.example.com:8200",
vault_token="s.your-vault-token",
vault_path="secureml",
use_env_fallback=True,
use_default_fallback=False
)
# Retrieve a secret
api_key = key_manager.get_secret("api_key")
# Get an encryption key
encryption_key = key_manager.get_encryption_key(
key_name="master_key",
key_bytes=32,
encoding="bytes"
)
Global Configuration
- secureml.key_management.configure_default_key_manager(vault_url: str | None = None, vault_token: str | None = None, vault_path: str = 'secureml', use_env_fallback: bool = True, use_default_fallback: bool = False) None
Configure the default key manager used by SecureML.
This function should be called early in your application’s lifecycle to ensure secure key storage is properly configured.
- Args:
vault_url: URL for the HashiCorp Vault server vault_token: Authentication token for Vault vault_path: Base path in Vault where SecureML secrets are stored use_env_fallback: Whether to fall back to environment variables use_default_fallback: Whether to fall back to default values (DEVELOPMENT ONLY)
The module provides a global configuration function to set up a default key manager for the entire application:
from secureml.key_management import configure_default_key_manager
# Configure the default key manager (do this once at startup)
configure_default_key_manager(
vault_url="https://vault.example.com:8200",
vault_token="s.your-vault-token",
vault_path="secureml",
use_env_fallback=True
)
Utility Functions
- secureml.key_management.get_encryption_key(key_name: str = 'master_key', key_bytes: int = 32, encoding: str = 'bytes') bytes | str
Get an encryption key using the default key manager.
- Args:
key_name: Name of the key to retrieve key_bytes: Number of bytes for the key (if generating a default) encoding: Output encoding (‘bytes’, ‘hex’, or ‘base64’)
- Returns:
The encryption key in the requested encoding
This utility function uses the default key manager to retrieve encryption keys:
from secureml.key_management import get_encryption_key
# Get an encryption key using the default key manager
key = get_encryption_key(
key_name="data_encryption_key",
encoding="base64"
)
# Use the key for encryption operations
# ...
HashiCorp Vault Integration
The module seamlessly integrates with HashiCorp Vault for secure key storage and management. To use Vault:
Ensure the hvac package is installed: pip install secureml[vault]
Configure Vault connection details when initializing KeyManager
Store your secrets in Vault using the set_secret method
Fallback Mechanisms
For ease of development and handling different environments, the module provides fallback mechanisms:
Environment Variables: When Vault is unavailable, the manager can fall back to environment variables prefixed with “SECUREML_” (e.g., SECUREML_API_KEY)
Default Values: For development environments only, the manager can generate deterministic default values
Key Derivation
The derive_key method allows deriving purpose-specific keys from a base key, implementing key separation:
# Get the master key
master_key = key_manager.get_encryption_key(key_name="master_key")
# Derive purpose-specific keys
encryption_key = key_manager.derive_key(master_key, purpose="data_encryption")
hmac_key = key_manager.derive_key(master_key, purpose="data_integrity")
Best Practices
Use Vault in Production: Always use HashiCorp Vault or another secure key management solution in production
Disable Default Fallbacks: Set use_default_fallback=False in production to prevent insecure defaults
Key Rotation: Implement regular key rotation practices
Separate Keys by Purpose: Use key derivation to create separate keys for different purposes
Environment Variables: For simple deployments, use environment variables with appropriate access controls
Never Hardcode Secrets: Never include secrets or keys directly in your code