# Cloud Secret Management

Integration with major cloud providers' secret management services including AWS Secrets Manager, Azure Key Vault, and Google Secret Manager. These sources enable secure configuration management in cloud environments with automatic credential handling and secret retrieval.

## Capabilities

### AWS Secrets Manager Source

Load settings from AWS Secrets Manager with support for automatic credential detection and JSON secret parsing.

```python { .api }
class AWSSecretsManagerSettingsSource(EnvSettingsSource):
    """Source for AWS Secrets Manager."""
    
    def __init__(
        self,
        settings_cls: type[BaseSettings],
        aws_secret_name: str | None = None,
        aws_secret_key: str | None = None,
        aws_session_token: str | None = None,
        aws_access_key_id: str | None = None,
        aws_secret_access_key: str | None = None,
        aws_region_name: str | None = None,
        case_sensitive: bool | None = None,
        env_prefix: str | None = None,
        env_nested_delimiter: str | None = None,
        env_nested_max_split: int | None = None,
        env_ignore_empty: bool | None = None,
        env_parse_none_str: str | None = None,
        env_parse_enums: bool | None = None,
    ):
        """
        Initialize AWS Secrets Manager settings source.
        
        Parameters:
        - settings_cls: The settings class
        - aws_secret_name: Name of the secret in AWS Secrets Manager
        - aws_secret_key: Specific key within the secret (for JSON secrets)
        - aws_session_token: AWS session token for authentication
        - aws_access_key_id: AWS access key ID
        - aws_secret_access_key: AWS secret access key
        - aws_region_name: AWS region name
        - case_sensitive: Whether secret keys are case-sensitive
        - env_prefix: Prefix for secret keys
        - env_nested_delimiter: Delimiter for nested secret values
        - env_nested_max_split: Maximum splits for nested values
        - env_ignore_empty: Whether to ignore empty secret values
        - env_parse_none_str: String value to parse as None
        - env_parse_enums: Whether to parse enum field names to values
        """
```

### Azure Key Vault Source

Load settings from Azure Key Vault with support for managed identity authentication and secret versioning.

```python { .api }
class AzureKeyVaultSettingsSource(EnvSettingsSource):
    """Source for Azure Key Vault."""
    
    def __init__(
        self,
        settings_cls: type[BaseSettings],
        azure_key_vault_url: str | None = None,
        azure_client_id: str | None = None,
        azure_client_secret: str | None = None,
        azure_tenant_id: str | None = None,
        case_sensitive: bool | None = None,
        env_prefix: str | None = None,
        env_nested_delimiter: str | None = None,
        env_nested_max_split: int | None = None,
        env_ignore_empty: bool | None = None,
        env_parse_none_str: str | None = None,
        env_parse_enums: bool | None = None,
    ):
        """
        Initialize Azure Key Vault settings source.
        
        Parameters:
        - settings_cls: The settings class
        - azure_key_vault_url: URL of the Azure Key Vault
        - azure_client_id: Azure client ID for service principal auth
        - azure_client_secret: Azure client secret for service principal auth
        - azure_tenant_id: Azure tenant ID
        - case_sensitive: Whether secret names are case-sensitive
        - env_prefix: Prefix for secret names
        - env_nested_delimiter: Delimiter for nested secret values
        - env_nested_max_split: Maximum splits for nested values
        - env_ignore_empty: Whether to ignore empty secret values
        - env_parse_none_str: String value to parse as None
        - env_parse_enums: Whether to parse enum field names to values
        """

class AzureKeyVaultMapping(Mapping[str, Optional[str]]):
    """Mapping interface for Azure Key Vault secrets."""
    
    def __init__(
        self,
        vault_url: str,
        credential: Any,
        case_sensitive: bool = False,
        env_prefix: str = "",
    ): ...
```

### Google Secret Manager Source

Load settings from Google Secret Manager with support for service account authentication and project-based secret access.

```python { .api }
class GoogleSecretManagerSettingsSource(EnvSettingsSource):
    """Source for Google Secret Manager."""
    
    def __init__(
        self,
        settings_cls: type[BaseSettings],
        gcp_project_id: str | None = None,
        gcp_secret_name: str | None = None,
        gcp_secret_version: str | None = None,
        case_sensitive: bool | None = None,
        env_prefix: str | None = None,
        env_nested_delimiter: str | None = None,
        env_nested_max_split: int | None = None,
        env_ignore_empty: bool | None = None,
        env_parse_none_str: str | None = None,
        env_parse_enums: bool | None = None,
    ):
        """
        Initialize Google Secret Manager settings source.
        
        Parameters:
        - settings_cls: The settings class
        - gcp_project_id: Google Cloud project ID
        - gcp_secret_name: Name of the secret in Secret Manager
        - gcp_secret_version: Version of the secret (defaults to 'latest')
        - case_sensitive: Whether secret names are case-sensitive
        - env_prefix: Prefix for secret names
        - env_nested_delimiter: Delimiter for nested secret values
        - env_nested_max_split: Maximum splits for nested values
        - env_ignore_empty: Whether to ignore empty secret values
        - env_parse_none_str: String value to parse as None
        - env_parse_enums: Whether to parse enum field names to values
        """

class GoogleSecretManagerMapping(Mapping[str, Optional[str]]):
    """Mapping interface for Google Secret Manager secrets."""
    
    def __init__(
        self,
        project_id: str,
        secret_name: str | None = None,
        secret_version: str = "latest",
        case_sensitive: bool = False,
        env_prefix: str = "",
    ): ...
```

## Usage Examples

### AWS Secrets Manager Basic Usage

```python
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic_settings import AWSSecretsManagerSettingsSource

class AppSettings(BaseSettings):
    database_url: str
    api_key: str
    debug: bool = False
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            AWSSecretsManagerSettingsSource(
                settings_cls,
                aws_secret_name="myapp/production/config",
                aws_region_name="us-east-1"
            ),
            env_settings,
            dotenv_settings,
            file_secret_settings,
        )

# Requires boto3 and AWS credentials configured
# Secret in AWS: {"database_url": "postgresql://...", "api_key": "secret123"}
settings = AppSettings()
```

### AWS Secrets Manager with Specific Key

```python
class DatabaseSettings(BaseSettings):
    host: str
    port: int
    username: str
    password: str
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            AWSSecretsManagerSettingsSource(
                settings_cls,
                aws_secret_name="myapp/database",
                aws_secret_key="production",  # Load from "production" key in JSON
                aws_region_name="us-west-2"
            ),
            env_settings,
        )

# AWS Secret structure:
# {
#   "production": {
#     "host": "prod-db.company.com",
#     "port": 5432,
#     "username": "app_user",
#     "password": "secure_password"
#   },
#   "staging": { ... }
# }
settings = DatabaseSettings()
```

### AWS with Custom Credentials

```python
class AppSettings(BaseSettings):
    api_token: str
    service_url: str
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            AWSSecretsManagerSettingsSource(
                settings_cls,
                aws_secret_name="myapp/api-config",
                aws_access_key_id="AKIA...",
                aws_secret_access_key="...",
                aws_region_name="eu-west-1"
            ),
            env_settings,
        )

settings = AppSettings()
```

### Azure Key Vault Basic Usage

```python
from pydantic_settings import AzureKeyVaultSettingsSource

class AppSettings(BaseSettings):
    database_password: str
    api_key: str
    encryption_key: str
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            AzureKeyVaultSettingsSource(
                settings_cls,
                azure_key_vault_url="https://myapp-vault.vault.azure.net/",
                azure_tenant_id="12345678-1234-1234-1234-123456789012"
            ),
            env_settings,
        )

# Requires azure-keyvault-secrets and azure-identity packages
# Uses DefaultAzureCredential for authentication (managed identity, etc.)
settings = AppSettings()
```

### Azure Key Vault with Service Principal

```python
class ProductionSettings(BaseSettings):
    db_connection_string: str
    jwt_secret: str
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            AzureKeyVaultSettingsSource(
                settings_cls,
                azure_key_vault_url="https://prod-vault.vault.azure.net/",
                azure_client_id="app-service-principal-id",
                azure_client_secret="service-principal-secret",
                azure_tenant_id="company-tenant-id"
            ),
            env_settings,
        )

settings = ProductionSettings()
```

### Google Secret Manager Basic Usage

```python
from pydantic_settings import GoogleSecretManagerSettingsSource

class AppSettings(BaseSettings):
    database_url: str
    api_key: str
    encryption_key: str
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            GoogleSecretManagerSettingsSource(
                settings_cls,
                gcp_project_id="my-gcp-project",
                gcp_secret_name="myapp-config"
            ),
            env_settings,
        )

# Requires google-cloud-secret-manager package
# Uses Application Default Credentials or service account
settings = AppSettings()
```

### Google Secret Manager with Specific Version

```python
class AppSettings(BaseSettings):
    api_key: str
    database_password: str
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            GoogleSecretManagerSettingsSource(
                settings_cls,
                gcp_project_id="production-project",
                gcp_secret_name="app-secrets",
                gcp_secret_version="3"  # Use specific version instead of 'latest'
            ),
            env_settings,
        )

settings = AppSettings()
```

### Multi-Cloud Configuration

```python
class MultiCloudSettings(BaseSettings):
    # Different secrets from different providers
    aws_api_key: str  # From AWS Secrets Manager
    azure_db_password: str  # From Azure Key Vault
    gcp_service_token: str  # From Google Secret Manager
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            # AWS for API keys
            AWSSecretsManagerSettingsSource(
                settings_cls,
                aws_secret_name="myapp/aws-config",
                aws_region_name="us-east-1",
                env_prefix="aws_"
            ),
            # Azure for database secrets
            AzureKeyVaultSettingsSource(
                settings_cls,
                azure_key_vault_url="https://db-vault.vault.azure.net/",
                env_prefix="azure_"
            ),
            # GCP for service tokens
            GoogleSecretManagerSettingsSource(
                settings_cls,
                gcp_project_id="services-project",
                gcp_secret_name="service-tokens",
                env_prefix="gcp_"
            ),
            env_settings,
        )

settings = MultiCloudSettings()
```

### Cloud Secrets with Environment Override

```python
class FlexibleSettings(BaseSettings):
    database_url: str
    api_key: str
    debug: bool = False
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        # Environment variables take precedence over cloud secrets
        return (
            init_settings,
            env_settings,  # Highest priority
            AWSSecretsManagerSettingsSource(
                settings_cls,
                aws_secret_name="myapp/config",
                aws_region_name="us-east-1"
            ),
            dotenv_settings,
            file_secret_settings,
        )

# Can override cloud secrets with environment variables
# export DATABASE_URL="postgresql://localhost/dev"  # Overrides AWS secret
settings = FlexibleSettings()
```

### Error Handling with Cloud Secrets

```python
from pydantic_settings import SettingsError

class RobustSettings(BaseSettings):
    api_key: str
    database_url: str
    
    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls,
        init_settings,
        env_settings,
        dotenv_settings,
        file_secret_settings,
    ):
        return (
            init_settings,
            env_settings,
            # Fallback to local secrets if cloud fails
            file_secret_settings,
            dotenv_settings,
        )

# Handle cloud provider authentication/access issues
try:
    settings = RobustSettings()
except SettingsError as e:
    print(f"Failed to load settings: {e}")
    # Fallback to environment variables or local files
    import os
    os.environ['API_KEY'] = 'fallback-key'
    settings = RobustSettings()
```