Skip to content

Providers

Providers are responsible for fetching secrets from external stores. Learn how to use existing providers or create your own.

Azure Key Vault Provider

envresolve.providers.azure_kv

Azure Key Vault provider implementation.

AzureKVProvider

Provider for resolving secrets from Azure Key Vault.

Supports both akv:// and kv:// URI schemes. Uses DefaultAzureCredential for authentication. Caches SecretClient instances per vault for efficiency.

Source code in src/envresolve/providers/azure_kv.py
class AzureKVProvider:
    """Provider for resolving secrets from Azure Key Vault.

    Supports both akv:// and kv:// URI schemes.
    Uses DefaultAzureCredential for authentication.
    Caches SecretClient instances per vault for efficiency.
    """

    def __init__(self, credential: "TokenCredential | None" = None) -> None:
        """Initialize Azure Key Vault provider.

        Args:
            credential: Azure credential to use.
                If None, DefaultAzureCredential is used.
        """
        self.credential = credential or DefaultAzureCredential()
        self._clients: dict[str, SecretClient] = {}

    def _get_client(self, vault_name: str) -> SecretClient:
        """Get or create a SecretClient for the given vault.

        Args:
            vault_name: Name of the Key Vault

        Returns:
            SecretClient instance for the vault
        """
        if vault_name not in self._clients:
            vault_url = f"https://{vault_name}.vault.azure.net"
            self._clients[vault_name] = SecretClient(
                vault_url=vault_url, credential=self.credential
            )
        return self._clients[vault_name]

    def resolve(self, parsed_uri: ParsedURI) -> str:
        """Resolve a secret from Azure Key Vault.

        Args:
            parsed_uri: Parsed URI dictionary containing vault, secret,
                and optional version

        Returns:
            The secret value as a string

        Raises:
            SecretResolutionError: If the secret cannot be resolved
        """
        vault_name = parsed_uri["vault"]
        secret_name = parsed_uri["secret"]
        version = parsed_uri["version"]

        # Reconstruct URI for error messages
        uri = f"{parsed_uri['scheme']}://{vault_name}/{secret_name}"
        if version:
            uri = f"{uri}?version={version}"

        try:
            client = self._get_client(vault_name)
            secret = client.get_secret(secret_name, version=version)
        except AzureError as e:
            msg = "Failed to resolve secret from Azure Key Vault"
            raise SecretResolutionError(msg, uri=uri, original_error=e) from e
        else:
            if secret.value is None:
                msg = "Secret value is None"
                raise SecretResolutionError(msg, uri=uri)
            return secret.value

__init__

__init__(credential: TokenCredential | None = None) -> None

Initialize Azure Key Vault provider.

Parameters:

Name Type Description Default
credential TokenCredential | None

Azure credential to use. If None, DefaultAzureCredential is used.

None
Source code in src/envresolve/providers/azure_kv.py
def __init__(self, credential: "TokenCredential | None" = None) -> None:
    """Initialize Azure Key Vault provider.

    Args:
        credential: Azure credential to use.
            If None, DefaultAzureCredential is used.
    """
    self.credential = credential or DefaultAzureCredential()
    self._clients: dict[str, SecretClient] = {}

resolve

resolve(parsed_uri: ParsedURI) -> str

Resolve a secret from Azure Key Vault.

Parameters:

Name Type Description Default
parsed_uri ParsedURI

Parsed URI dictionary containing vault, secret, and optional version

required

Returns:

Type Description
str

The secret value as a string

Raises:

Type Description
SecretResolutionError

If the secret cannot be resolved

Source code in src/envresolve/providers/azure_kv.py
def resolve(self, parsed_uri: ParsedURI) -> str:
    """Resolve a secret from Azure Key Vault.

    Args:
        parsed_uri: Parsed URI dictionary containing vault, secret,
            and optional version

    Returns:
        The secret value as a string

    Raises:
        SecretResolutionError: If the secret cannot be resolved
    """
    vault_name = parsed_uri["vault"]
    secret_name = parsed_uri["secret"]
    version = parsed_uri["version"]

    # Reconstruct URI for error messages
    uri = f"{parsed_uri['scheme']}://{vault_name}/{secret_name}"
    if version:
        uri = f"{uri}?version={version}"

    try:
        client = self._get_client(vault_name)
        secret = client.get_secret(secret_name, version=version)
    except AzureError as e:
        msg = "Failed to resolve secret from Azure Key Vault"
        raise SecretResolutionError(msg, uri=uri, original_error=e) from e
    else:
        if secret.value is None:
            msg = "Secret value is None"
            raise SecretResolutionError(msg, uri=uri)
        return secret.value

Base Provider (for custom implementations)

envresolve.providers.base

Base provider protocol.

SecretProvider

Bases: Protocol

Protocol for secret providers.

Source code in src/envresolve/providers/base.py
class SecretProvider(Protocol):
    """Protocol for secret providers."""

    def resolve(self, parsed_uri: ParsedURI) -> str:
        """Resolve a secret from its provider.

        Args:
            parsed_uri: Parsed URI dictionary

        Returns:
            The secret value as a string

        Raises:
            SecretResolutionError: If the secret cannot be resolved
        """
        ...

resolve

resolve(parsed_uri: ParsedURI) -> str

Resolve a secret from its provider.

Parameters:

Name Type Description Default
parsed_uri ParsedURI

Parsed URI dictionary

required

Returns:

Type Description
str

The secret value as a string

Raises:

Type Description
SecretResolutionError

If the secret cannot be resolved

Source code in src/envresolve/providers/base.py
def resolve(self, parsed_uri: ParsedURI) -> str:
    """Resolve a secret from its provider.

    Args:
        parsed_uri: Parsed URI dictionary

    Returns:
        The secret value as a string

    Raises:
        SecretResolutionError: If the secret cannot be resolved
    """
    ...