Microsoft Azure Key Vault secrets client library for Python providing secure storage and management of sensitive information
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive data models representing secrets, their properties, and metadata with complete type definitions for all secret-related operations. These models provide structured access to secret data and enable type-safe operations.
Complete secret representation including both value and metadata properties.
class KeyVaultSecret:
def __init__(
self,
properties: SecretProperties,
value: Optional[str]
):
"""
Represents a complete Key Vault secret with value and properties.
Parameters:
- properties (SecretProperties): Secret metadata and properties
- value (str, optional): The secret's value
"""
@property
def name(self) -> Optional[str]:
"""The name of the secret."""
@property
def id(self) -> Optional[str]:
"""The full identifier URL of the secret."""
@property
def properties(self) -> SecretProperties:
"""The secret's properties and metadata."""
@property
def value(self) -> Optional[str]:
"""The secret's value (sensitive data)."""
def __repr__(self) -> str:
"""String representation of the secret (excludes value for security)."""Secret metadata without the actual secret value, used for operations that don't require the sensitive data.
class SecretProperties:
def __init__(self, *args, **kwargs):
"""
Represents secret metadata without the actual value.
"""
@property
def id(self) -> Optional[str]:
"""The full identifier URL of the secret."""
@property
def name(self) -> Optional[str]:
"""The name of the secret."""
@property
def version(self) -> Optional[str]:
"""The version identifier of the secret."""
@property
def vault_url(self) -> Optional[str]:
"""The URL of the vault containing the secret."""
@property
def content_type(self) -> Optional[str]:
"""
Content type of the secret value.
Common types: 'text/plain', 'application/json', 'application/x-pem-file'
"""
@property
def enabled(self) -> Optional[bool]:
"""Whether the secret is enabled for use."""
@property
def not_before(self) -> Optional[datetime]:
"""The datetime before which the secret cannot be used."""
@property
def expires_on(self) -> Optional[datetime]:
"""The datetime after which the secret expires."""
@property
def created_on(self) -> Optional[datetime]:
"""When the secret was created."""
@property
def updated_on(self) -> Optional[datetime]:
"""When the secret was last updated."""
@property
def recovery_level(self) -> Optional[str]:
"""
Recovery level for soft-deleted secrets.
Values: 'Purgeable', 'Recoverable+Purgeable', 'Recoverable',
'Recoverable+ProtectedSubscription'
"""
@property
def recoverable_days(self) -> Optional[int]:
"""Number of days a deleted secret can be recovered."""
@property
def key_id(self) -> Optional[str]:
"""ID of the key backing the secret (for certificate-backed secrets)."""
@property
def managed(self) -> Optional[bool]:
"""Whether the secret's lifetime is managed by Key Vault."""
@property
def tags(self) -> Optional[Dict[str, str]]:
"""User-defined metadata tags associated with the secret."""
def __repr__(self) -> str:
"""String representation of the secret properties."""Parser and representation for Key Vault secret identifiers/URLs.
class KeyVaultSecretIdentifier:
def __init__(self, source_id: str):
"""
Parse and represent a Key Vault secret identifier.
Parameters:
- source_id (str): The full secret identifier URL to parse
Format: https://{vault}.vault.azure.net/secrets/{name}[/{version}]
Raises:
- ValueError: If the secret ID format is invalid
"""
@property
def source_id(self) -> str:
"""The original identifier URL that was parsed."""
@property
def vault_url(self) -> str:
"""The base URL of the Key Vault (e.g., 'https://vault.vault.azure.net/')."""
@property
def name(self) -> str:
"""The name of the secret."""
@property
def version(self) -> Optional[str]:
"""
The version of the secret, if specified in the identifier.
None if the identifier refers to the latest version.
"""Represents a soft-deleted secret with recovery information and deletion metadata.
class DeletedSecret:
def __init__(
self,
properties: SecretProperties,
deleted_date: Optional[datetime] = None,
recovery_id: Optional[str] = None,
scheduled_purge_date: Optional[datetime] = None
):
"""
Represents a deleted secret with recovery capabilities.
Parameters:
- properties (SecretProperties): The secret's properties
- deleted_date (datetime, optional): When the secret was deleted
- recovery_id (str, optional): Identifier for recovery operations
- scheduled_purge_date (datetime, optional): When the secret will be permanently deleted
"""
@property
def id(self) -> Optional[str]:
"""The full identifier URL of the deleted secret."""
@property
def name(self) -> Optional[str]:
"""The name of the deleted secret."""
@property
def properties(self) -> SecretProperties:
"""The secret's properties and metadata."""
@property
def deleted_date(self) -> Optional[datetime]:
"""When the secret was deleted."""
@property
def recovery_id(self) -> Optional[str]:
"""
The identifier used for recovery operations.
Used with recover_deleted_secret() operations.
"""
@property
def scheduled_purge_date(self) -> Optional[datetime]:
"""
When the secret is scheduled for permanent deletion.
After this date, the secret cannot be recovered.
"""
def __repr__(self) -> str:
"""String representation of the deleted secret."""Enumeration of recovery levels for soft-deleted secrets indicating the protection and recovery capabilities.
class DeletionRecoveryLevel(str, Enum):
"""
Enumeration of recovery levels for deleted secrets.
Determines how deleted secrets can be recovered and their protection level.
"""
PURGEABLE = "Purgeable"
RECOVERABLE_PURGEABLE = "Recoverable+Purgeable"
RECOVERABLE = "Recoverable"
RECOVERABLE_PROTECTED_SUBSCRIPTION = "Recoverable+ProtectedSubscription"
CUSTOMIZED_RECOVERABLE_PURGEABLE = "CustomizedRecoverable+Purgeable"
CUSTOMIZED_RECOVERABLE = "CustomizedRecoverable"
CUSTOMIZED_RECOVERABLE_PROTECTED_SUBSCRIPTION = "CustomizedRecoverable+ProtectedSubscription"Enumeration of supported Key Vault API versions.
class ApiVersion(str, Enum):
"""
Supported Azure Key Vault API versions.
"""
V7_6 = "7.6" # Default version (latest)
V7_5 = "7.5"
V7_4 = "7.4"
V7_3 = "7.3"
V7_2 = "7.2"
V7_1 = "7.1"
V7_0 = "7.0"
V2016_10_01 = "2016-10-01" # Legacy versionfrom azure.keyvault.secrets import KeyVaultSecretIdentifier
# Parse a complete secret identifier
secret_id = "https://vault.vault.azure.net/secrets/my-secret/abc123def456"
identifier = KeyVaultSecretIdentifier(secret_id)
print(f"Vault URL: {identifier.vault_url}") # https://vault.vault.azure.net/
print(f"Secret Name: {identifier.name}") # my-secret
print(f"Version: {identifier.version}") # abc123def456
# Parse identifier without version (latest)
latest_id = "https://vault.vault.azure.net/secrets/my-secret"
latest_identifier = KeyVaultSecretIdentifier(latest_id)
print(f"Version: {latest_identifier.version}") # None (refers to latest)from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential
client = SecretClient("https://vault.vault.azure.net/", DefaultAzureCredential())
# Get a secret and examine its properties
secret = client.get_secret("my-secret")
print(f"Secret Name: {secret.name}")
print(f"Secret Value: {secret.value}")
print(f"Content Type: {secret.properties.content_type}")
print(f"Enabled: {secret.properties.enabled}")
print(f"Created: {secret.properties.created_on}")
print(f"Tags: {secret.properties.tags}")
# Check expiration
if secret.properties.expires_on:
from datetime import datetime
if secret.properties.expires_on < datetime.now(secret.properties.expires_on.tzinfo):
print("Warning: Secret has expired!")from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential
client = SecretClient("https://vault.vault.azure.net/", DefaultAzureCredential())
# Delete a secret and examine the deleted secret info
poller = client.begin_delete_secret("my-secret")
deleted_secret = poller.result()
print(f"Deleted Secret: {deleted_secret.name}")
print(f"Deleted On: {deleted_secret.deleted_date}")
print(f"Recovery ID: {deleted_secret.recovery_id}")
print(f"Scheduled Purge: {deleted_secret.scheduled_purge_date}")
# Check if recovery is possible
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
if deleted_secret.scheduled_purge_date and deleted_secret.scheduled_purge_date > now:
print("Secret can still be recovered")
# Recover the secret
recover_poller = client.begin_recover_deleted_secret("my-secret")
recovered_properties = recover_poller.result()
print(f"Recovered: {recovered_properties.name}")
else:
print("Secret is past recovery period")from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential
client = SecretClient("https://vault.vault.azure.net/", DefaultAzureCredential())
# List all versions of a secret
for version_props in client.list_properties_of_secret_versions("my-secret"):
print(f"Version: {version_props.version}")
print(f"Created: {version_props.created_on}")
print(f"Enabled: {version_props.enabled}")
# Get specific version
versioned_secret = client.get_secret("my-secret", version_props.version)
print(f"Value for version {version_props.version}: {versioned_secret.value}")from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential
from datetime import datetime, timedelta
client = SecretClient("https://vault.vault.azure.net/", DefaultAzureCredential())
# Set a secret with comprehensive metadata
expiration = datetime.utcnow() + timedelta(days=365)
not_before = datetime.utcnow()
secret = client.set_secret(
"production-api-key",
"super-secret-value",
enabled=True,
content_type="text/plain",
tags={
"environment": "production",
"service": "api-gateway",
"owner": "platform-team",
"classification": "confidential"
},
not_before=not_before,
expires_on=expiration
)
# Later, update only the metadata without changing the value
updated_props = client.update_secret_properties(
"production-api-key",
tags={
"environment": "production",
"service": "api-gateway",
"owner": "platform-team",
"classification": "confidential",
"last-rotated": datetime.utcnow().isoformat()
}
)
print(f"Updated tags: {updated_props.tags}")from typing import Dict, Optional
from datetime import datetime
from enum import Enum
from azure.keyvault.secrets._generated.models import DeletionRecoveryLevelInstall with Tessl CLI
npx tessl i tessl/pypi-azure-keyvault-secrets