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:

  1. Ensure the hvac package is installed: pip install secureml[vault]

  2. Configure Vault connection details when initializing KeyManager

  3. 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:

  1. Environment Variables: When Vault is unavailable, the manager can fall back to environment variables prefixed with “SECUREML_” (e.g., SECUREML_API_KEY)

  2. 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

  1. Use Vault in Production: Always use HashiCorp Vault or another secure key management solution in production

  2. Disable Default Fallbacks: Set use_default_fallback=False in production to prevent insecure defaults

  3. Key Rotation: Implement regular key rotation practices

  4. Separate Keys by Purpose: Use key derivation to create separate keys for different purposes

  5. Environment Variables: For simple deployments, use environment variables with appropriate access controls

  6. Never Hardcode Secrets: Never include secrets or keys directly in your code