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

import-export.mddocs/

Key Import and Export

Import keys from external sources and export keys with secure release policies. Azure Key Vault supports importing keys in JSON Web Key (JWK) format and provides secure key release mechanisms for data protection and compliance scenarios with attestation-based key release policies.

Capabilities

Key Import

Import cryptographic key material from external sources into Azure Key Vault.

def import_key(
    name: str,
    key: JsonWebKey,
    *,
    hardware_protected: bool = None,
    enabled: bool = None,
    tags: Dict[str, str] = None,
    not_before: datetime = None,
    expires_on: datetime = None,
    exportable: bool = None,
    release_policy: KeyReleasePolicy = None,
    **kwargs
) -> KeyVaultKey:
    """
    Import a key into the Key Vault.

    Parameters:
    - name: The name for the imported key
    - key: The JSON Web Key to import
    - hardware_protected: Whether to store in HSM (True) or software (False)
    - enabled: Whether the key should be enabled
    - tags: Application-specific metadata
    - not_before: Key not valid before this date
    - expires_on: Key expiration date
    - exportable: Whether the private key can be exported
    - release_policy: Policy rules for key release

    Returns:
    KeyVaultKey: The imported key
    
    Raises:
    - InvalidArgumentError: If key format is invalid
    - ConflictError: If key with same name already exists
    - ForbiddenError: If import permission is not granted
    """

Usage Examples

from azure.keyvault.keys import KeyClient, JsonWebKey, KeyType, KeyOperation
from azure.identity import DefaultAzureCredential

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

# Import RSA key from JWK
rsa_jwk = JsonWebKey(
    kty=KeyType.rsa,
    n=b"...",  # RSA modulus (base64url decoded)
    e=b"AQAB",  # RSA public exponent (base64url decoded)
    d=b"...",  # RSA private exponent (base64url decoded)
    p=b"...",  # RSA prime p
    q=b"...",  # RSA prime q
    dp=b"...", # RSA private key parameter
    dq=b"...", # RSA private key parameter
    qi=b"...", # RSA private key parameter
    key_ops=[KeyOperation.encrypt, KeyOperation.decrypt, KeyOperation.sign, KeyOperation.verify]
)

imported_key = client.import_key(
    "imported-rsa-key",
    rsa_jwk,
    hardware_protected=False,
    tags={"source": "external", "imported": "true"}
)
print(f"Imported key: {imported_key.name}")

# Import EC key from JWK
from azure.keyvault.keys import KeyCurveName

ec_jwk = JsonWebKey(
    kty=KeyType.ec,
    crv=KeyCurveName.p_256,
    x=b"...",  # X coordinate (base64url decoded)
    y=b"...",  # Y coordinate (base64url decoded)
    d=b"...",  # Private key (base64url decoded)
    key_ops=[KeyOperation.sign, KeyOperation.verify]
)

imported_ec_key = client.import_key(
    "imported-ec-key",
    ec_jwk,
    hardware_protected=True  # Store in HSM
)

# Import symmetric key from JWK
symmetric_jwk = JsonWebKey(
    kty=KeyType.oct,
    k=b"...",  # Symmetric key material (base64url decoded)
    key_ops=[KeyOperation.encrypt, KeyOperation.decrypt]
)

imported_symmetric_key = client.import_key(
    "imported-symmetric-key",
    symmetric_jwk
)

Key Release

Release keys from Azure Key Vault with attestation-based security policies.

def release_key(
    name: str,
    target_attestation_token: str,
    *,
    version: str = None,
    algorithm: KeyExportEncryptionAlgorithm = None,
    nonce: str = None,
    **kwargs
) -> ReleaseKeyResult:
    """
    Release a key using an attestation token.

    Parameters:
    - name: The name of the key to release
    - target_attestation_token: Attestation token proving target environment security
    - version: Specific version of the key (optional, uses latest if omitted)
    - algorithm: Encryption algorithm for key export protection
    - nonce: Cryptographic nonce for freshness

    Returns:
    ReleaseKeyResult: The released key wrapped according to policy
    
    Raises:
    - ResourceNotFoundError: If the key doesn't exist
    - ForbiddenError: If key release policy requirements not met
    - InvalidArgumentError: If attestation token is invalid
    """

Usage Examples

from azure.keyvault.keys import KeyExportEncryptionAlgorithm

# Release a key with attestation token
attestation_token = "eyJ..."  # Attestation token from trusted execution environment

release_result = client.release_key(
    "confidential-key",
    attestation_token,
    algorithm=KeyExportEncryptionAlgorithm.rsa_aes_key_wrap_256
)

print(f"Released key value: {release_result.value}")

# The released key is encrypted and can only be decrypted in the attested environment

Key Release Policies

Configure and manage key release policies for secure key export.

class KeyReleasePolicy:
    """Policy rules under which a key can be exported."""
    encoded_policy: bytes
    content_type: str
    immutable: bool

Usage Examples

import json
import base64

# Define a key release policy
policy_document = {
    "version": "1.0",
    "attestation": {
        "type": "SGX",
        "measurement": "abc123...",  # Expected enclave measurement
        "mrenclave": "def456...",    # Expected enclave hash
    },
    "rules": [
        {
            "claim": "is-debuggable",
            "equals": False
        },
        {
            "claim": "product-id", 
            "equals": 1
        }
    ]
}

# Encode policy as base64
policy_json = json.dumps(policy_document)
encoded_policy = base64.b64encode(policy_json.encode()).decode()

# Create key release policy
from azure.keyvault.keys import KeyReleasePolicy

release_policy = KeyReleasePolicy(
    encoded_policy=encoded_policy.encode(),
    content_type="application/json; charset=utf-8"
)

# Create key with release policy
key_with_policy = client.create_rsa_key(
    "confidential-key-with-policy",
    size=2048,
    exportable=True,
    release_policy=release_policy
)

Import from External Key Management Systems

Common patterns for importing keys from various external sources.

Import from OpenSSL

import base64
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa

def import_from_pem(client: KeyClient, key_name: str, pem_data: bytes, password: bytes = None):
    """Import a key from PEM format."""
    
    # Load private key from PEM
    private_key = serialization.load_pem_private_key(pem_data, password=password)
    
    if isinstance(private_key, rsa.RSAPrivateKey):
        # Extract RSA parameters
        private_numbers = private_key.private_numbers()
        public_numbers = private_numbers.public_numbers
        
        # Create JWK
        jwk = JsonWebKey(
            kty=KeyType.rsa,
            n=public_numbers.n.to_bytes((public_numbers.n.bit_length() + 7) // 8, 'big'),
            e=public_numbers.e.to_bytes((public_numbers.e.bit_length() + 7) // 8, 'big'),
            d=private_numbers.private_exponent.to_bytes((private_numbers.private_exponent.bit_length() + 7) // 8, 'big'),
            p=private_numbers.p.to_bytes((private_numbers.p.bit_length() + 7) // 8, 'big'),
            q=private_numbers.q.to_bytes((private_numbers.q.bit_length() + 7) // 8, 'big'),
            dp=private_numbers.dmp1.to_bytes((private_numbers.dmp1.bit_length() + 7) // 8, 'big'),
            dq=private_numbers.dmq1.to_bytes((private_numbers.dmq1.bit_length() + 7) // 8, 'big'),
            qi=private_numbers.iqmp.to_bytes((private_numbers.iqmp.bit_length() + 7) // 8, 'big')
        )
        
        # Import to Key Vault
        return client.import_key(key_name, jwk)
    else:
        raise ValueError("Only RSA keys are supported in this example")

# Usage
with open("private-key.pem", "rb") as f:
    pem_data = f.read()

imported_key = import_from_pem(client, "imported-from-pem", pem_data)

Import from PKCS#12

from cryptography.hazmat.primitives import serialization

def import_from_pkcs12(client: KeyClient, key_name: str, p12_data: bytes, password: bytes):
    """Import a key from PKCS#12 format."""
    
    # Load PKCS#12
    private_key, certificate, additional_certificates = serialization.pkcs12.load_key_and_certificates(
        p12_data, password
    )
    
    # Convert to JWK and import (similar to PEM example above)
    # ... implementation details ...
    
    return client.import_key(key_name, jwk, tags={"format": "pkcs12"})

Types

class JsonWebKey:
    """JSON Web Key representation as defined in RFC 7517."""
    kid: str                    # Key identifier
    kty: KeyType               # Key type
    key_ops: List[KeyOperation] # Allowed operations
    
    # RSA parameters
    n: bytes    # RSA modulus
    e: bytes    # RSA public exponent  
    d: bytes    # RSA private exponent
    dp: bytes   # RSA private key parameter
    dq: bytes   # RSA private key parameter
    qi: bytes   # RSA private key parameter
    p: bytes    # RSA secret prime
    q: bytes    # RSA secret prime
    
    # EC parameters
    crv: KeyCurveName  # Elliptic curve name
    x: bytes          # X component of EC public key
    y: bytes          # Y component of EC public key
    d: bytes          # D component of EC private key
    
    # Symmetric key parameters
    k: bytes    # Symmetric key material
    
    # HSM parameters
    t: bytes    # HSM Token for Bring Your Own Key

class ReleaseKeyResult:
    """Result of a key release operation."""
    value: str  # The released key material (encrypted according to policy)

class KeyReleasePolicy:
    """Policy rules under which a key can be exported."""
    encoded_policy: bytes    # Base64-encoded policy document
    content_type: str       # MIME type of policy (e.g., "application/json; charset=utf-8")
    immutable: bool         # Whether policy can be changed after creation

class KeyExportEncryptionAlgorithm(str, Enum):
    """Supported algorithms for protecting exported key material."""
    ckm_rsa_aes_key_wrap = "CKM_RSA_AES_KEY_WRAP"      # CKM RSA AES Key Wrap
    rsa_aes_key_wrap_256 = "RSA_AES_KEY_WRAP_256"      # RSA AES Key Wrap with SHA-256
    rsa_aes_key_wrap_384 = "RSA_AES_KEY_WRAP_384"      # RSA AES Key Wrap with SHA-384

Security Considerations

Import Security

  • Key Material Handling: Ensure imported key material is from trusted sources
  • Transport Security: Use secure channels when transferring keys to import
  • Key Validation: Validate key parameters before import
  • Access Control: Restrict import permissions to authorized personnel only

Export Security

  • Attestation Verification: Verify attestation tokens are from trusted execution environments
  • Policy Enforcement: Ensure release policies meet organizational security requirements
  • Audit Logging: Monitor and log all key release operations
  • Least Privilege: Grant release permissions only when necessary

Best Practices

# Example secure import pattern
def secure_import_key(client: KeyClient, key_name: str, jwk: JsonWebKey):
    """Securely import a key with validation and audit."""
    
    # Validate key before import
    if not jwk.kty or not jwk.key_ops:
        raise ValueError("Key type and operations must be specified")
    
    # Import with restrictive settings
    imported_key = client.import_key(
        key_name,
        jwk, 
        enabled=False,  # Start disabled for review
        tags={
            "imported": "true",
            "import_date": datetime.utcnow().isoformat(),
            "requires_review": "true"
        }
    )
    
    # Log the import
    print(f"Key {key_name} imported successfully, requires review before enabling")
    
    return imported_key

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