CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-azure-keyvault-keys

Microsoft Azure Key Vault Keys client library for Python providing cryptographic key management operations

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

backup-recovery.mddocs/

Key Backup and Recovery

Backup and restore functionality for keys, enabling key migration and disaster recovery scenarios. Azure Key Vault provides comprehensive backup and recovery capabilities including full key backup/restore and soft-delete protection with recovery options for accidental deletion scenarios.

Capabilities

Key Backup and Restore

Create portable backups of keys for migration and disaster recovery.

def backup_key(name: str, **kwargs) -> bytes:
    """
    Back up a key from the Key Vault.

    Parameters:
    - name: The name of the key to back up

    Returns:
    bytes: The key backup as opaque bytes (includes all versions and metadata)
    
    Raises:
    - ResourceNotFoundError: If the key doesn't exist
    - ForbiddenError: If backup permission is not granted
    """

def restore_key_backup(backup: bytes, **kwargs) -> KeyVaultKey:
    """
    Restore a key from a backup.

    Parameters:
    - backup: The key backup bytes from backup_key()

    Returns:
    KeyVaultKey: The restored key
    
    Raises:
    - InvalidArgumentError: If backup data is invalid
    - ConflictError: If a key with the same name already exists
    - ForbiddenError: If restore permission is not granted
    """

Usage Examples

from azure.keyvault.keys import KeyClient
from azure.identity import DefaultAzureCredential

client = KeyClient("https://vault.vault.azure.net/", DefaultAzureCredential())

# Create a key to backup
key = client.create_rsa_key("backup-demo-key", size=2048)

# Backup the key
backup_data = client.backup_key("backup-demo-key")
print(f"Backup size: {len(backup_data)} bytes")

# Save backup to file (optional)
with open("key-backup.bin", "wb") as f:
    f.write(backup_data)

# Delete the key
client.begin_delete_key("backup-demo-key").wait()
client.purge_deleted_key("backup-demo-key")

# Restore the key from backup
restored_key = client.restore_key_backup(backup_data)
print(f"Restored key: {restored_key.name}")

# Restore from file (optional)
with open("key-backup.bin", "rb") as f:
    backup_data = f.read()
    restored_key = client.restore_key_backup(backup_data)

Soft Delete Management

Manage soft-deleted keys with recovery capabilities.

def list_deleted_keys(**kwargs) -> ItemPaged[DeletedKey]:
    """
    List all soft-deleted keys in the vault.

    Returns:
    ItemPaged[DeletedKey]: Paginated list of deleted keys with recovery information
    """

def get_deleted_key(name: str, **kwargs) -> DeletedKey:
    """
    Get information about a soft-deleted key.

    Parameters:
    - name: The name of the deleted key

    Returns:
    DeletedKey: The deleted key with recovery information
    
    Raises:
    - ResourceNotFoundError: If the deleted key doesn't exist
    """

def begin_recover_deleted_key(name: str, **kwargs) -> LROPoller[KeyVaultKey]:
    """
    Begin recovering a soft-deleted key.

    Parameters:
    - name: The name of the deleted key to recover

    Returns:
    LROPoller[KeyVaultKey]: Long-running operation poller for the recovery
    
    Raises:
    - ResourceNotFoundError: If the deleted key doesn't exist
    - ConflictError: If a key with the same name already exists (active)
    """

def purge_deleted_key(name: str, **kwargs) -> None:
    """
    Permanently delete a soft-deleted key (cannot be recovered).

    Parameters:
    - name: The name of the deleted key to purge
    
    Raises:
    - ResourceNotFoundError: If the deleted key doesn't exist
    - ForbiddenError: If purge permission is not granted
    """

Usage Examples

# Delete a key (soft delete)
delete_poller = client.begin_delete_key("my-key")
deleted_key = delete_poller.result()
print(f"Key deleted on: {deleted_key.deleted_date}")
print(f"Scheduled purge date: {deleted_key.scheduled_purge_date}")

# List all deleted keys
print("Deleted keys:")
for deleted_key in client.list_deleted_keys():
    print(f"- {deleted_key.name} (deleted: {deleted_key.deleted_date})")

# Get specific deleted key info
deleted_key = client.get_deleted_key("my-key")
print(f"Recovery ID: {deleted_key.recovery_id}")

# Recover a deleted key
recover_poller = client.begin_recover_deleted_key("my-key")
recovered_key = recover_poller.result()
print(f"Recovered key: {recovered_key.name}")

# Permanently delete (purge) a key
client.purge_deleted_key("my-key")
print("Key permanently deleted")

Recovery Scenarios

Common backup and recovery patterns for different scenarios.

Cross-Vault Migration

# Backup from source vault
source_client = KeyClient("https://source-vault.vault.azure.net/", credential)
backup_data = source_client.backup_key("migration-key")

# Restore to destination vault
dest_client = KeyClient("https://dest-vault.vault.azure.net/", credential)
restored_key = dest_client.restore_key_backup(backup_data)

Disaster Recovery

import os
from datetime import datetime

# Regular backup process
keys_to_backup = ["critical-key-1", "critical-key-2", "signing-key"]
backup_dir = "/secure/backups"

for key_name in keys_to_backup:
    try:
        backup_data = client.backup_key(key_name)
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        backup_file = os.path.join(backup_dir, f"{key_name}_{timestamp}.backup")
        
        with open(backup_file, "wb") as f:
            f.write(backup_data)
        print(f"Backed up {key_name} to {backup_file}")
    except Exception as e:
        print(f"Failed to backup {key_name}: {e}")

# Recovery process
def recover_from_backup(backup_file_path: str):
    with open(backup_file_path, "rb") as f:
        backup_data = f.read()
    
    try:
        restored_key = client.restore_key_backup(backup_data)
        print(f"Successfully restored key: {restored_key.name}")
        return restored_key
    except Exception as e:
        print(f"Failed to restore from {backup_file_path}: {e}")
        return None

Accidental Deletion Recovery

def recover_accidentally_deleted_key(key_name: str):
    """Recover a key that was accidentally deleted."""
    try:
        # Check if key is soft-deleted
        deleted_key = client.get_deleted_key(key_name)
        print(f"Found deleted key: {deleted_key.name}")
        print(f"Deleted on: {deleted_key.deleted_date}")
        print(f"Scheduled purge: {deleted_key.scheduled_purge_date}")
        
        # Recover the key
        recover_poller = client.begin_recover_deleted_key(key_name)
        recovered_key = recover_poller.result()
        print(f"Successfully recovered key: {recovered_key.name}")
        return recovered_key
        
    except ResourceNotFoundError:
        print(f"Key '{key_name}' not found in deleted keys")
        return None
    except Exception as e:
        print(f"Error recovering key: {e}")
        return None

# Example usage
recovered_key = recover_accidentally_deleted_key("accidentally-deleted-key")

Types

class DeletedKey(KeyVaultKey):
    """A deleted key's properties, cryptographic material and deletion information."""
    # Inherits all properties from KeyVaultKey, plus:
    deleted_date: datetime
    recovery_id: str
    scheduled_purge_date: datetime

class LROPoller:
    """Long-running operation poller."""
    def result(timeout: int = None) -> Any:
        """Get the final result of the long-running operation."""
    
    def wait(timeout: int = None) -> None:
        """Wait for the operation to complete."""
    
    def done() -> bool:
        """Check if the operation is complete."""
    
    def status() -> str:
        """Get the current status of the operation."""

class ItemPaged:
    """Paginated collection of items."""
    def __iter__():
        """Iterate over all items across pages."""
    
    def by_page():
        """Iterate page by page."""

Error Handling

Common exceptions and error scenarios in backup and recovery operations.

from azure.core.exceptions import (
    ResourceNotFoundError,
    ConflictError,
    ForbiddenError,
    InvalidArgumentError
)

def safe_backup_key(client: KeyClient, key_name: str) -> bytes:
    """Safely backup a key with error handling."""
    try:
        return client.backup_key(key_name)
    except ResourceNotFoundError:
        print(f"Key '{key_name}' not found")
        return None
    except ForbiddenError:
        print(f"Insufficient permissions to backup key '{key_name}'")
        return None
    except Exception as e:
        print(f"Unexpected error backing up key '{key_name}': {e}")
        return None

def safe_restore_key(client: KeyClient, backup_data: bytes) -> KeyVaultKey:
    """Safely restore a key with error handling."""
    try:
        return client.restore_key_backup(backup_data)
    except InvalidArgumentError:
        print("Invalid backup data")
        return None
    except ConflictError:
        print("Key with same name already exists")
        return None
    except ForbiddenError:
        print("Insufficient permissions to restore key")
        return None
    except Exception as e:
        print(f"Unexpected error restoring key: {e}")
        return None

Install with Tessl CLI

npx tessl i tessl/pypi-azure-keyvault-keys

docs

async-operations.md

backup-recovery.md

crypto-operations.md

import-export.md

index.md

key-management.md

rotation-policies.md

tile.json