def test_multitenant_authentication(self, client, is_hsm, **kwargs):
        if not self.is_live:
            pytest.skip("This test is incompatible with vcrpy in playback")

        client_id = os.environ.get("KEYVAULT_CLIENT_ID")
        client_secret = os.environ.get("KEYVAULT_CLIENT_SECRET")
        if not (client_id and client_secret):
            pytest.skip(
                "Values for KEYVAULT_CLIENT_ID and KEYVAULT_CLIENT_SECRET are required"
            )

        # we set up a client for this method to align with the async test, but we actually want to create a new client
        # this new client should use a credential with an initially fake tenant ID and still succeed with a real request
        credential = ClientSecretCredential(tenant_id=str(uuid4()),
                                            client_id=client_id,
                                            client_secret=client_secret)
        vault_url = self.managed_hsm_url if is_hsm else self.vault_url
        client = KeyClient(vault_url=vault_url, credential=credential)

        if self.is_live:
            time.sleep(2)  # to avoid throttling by the service
        key_name = self.get_resource_name("multitenant-key")
        key = client.create_rsa_key(key_name)
        assert key.id

        # try making another request with the credential's token revoked
        # the challenge policy should correctly request a new token for the correct tenant when a challenge is cached
        client._client._config.authentication_policy._token = None
        fetched_key = client.get_key(key_name)
        assert key.id == fetched_key.id
 def create_key(self, credential, key_vault_name, suffix):
     """Creates a Key within the given Key Vault
     :param credential: Azure Credentials
     :param key_vault_name: Name of the Key Vault.
     :param suffix: suffix for Key name
     :type key_vault_name: str
     :type suffix: str
     :returns: Azure Key object which was created
     :rtype: object
     """
     d = datetime.datetime.utcnow().replace(
         tzinfo=datetime.timezone.utc).isoformat()
     date = datetime.datetime.strptime(
         d[0:19], "%Y-%m-%dT%H:%M:%S") + datetime.timedelta(days=180)
     expires_on = date_parse.parse(
         date.replace(microsecond=0,
                      tzinfo=datetime.timezone.utc).isoformat())
     key_client = KeyClient(
         vault_url=f"https://{key_vault_name}.vault.azure.net/",
         credential=credential,
     )
     rsa_key_name = key_vault_name + "-" + suffix
     logging.info("creating a key")
     rsa_key = key_client.create_rsa_key(rsa_key_name,
                                         size=2048,
                                         expires_on=expires_on,
                                         enabled=True)
     return rsa_key
Пример #3
0
class KeyVaultKeys:
    def __init__(self):
        # DefaultAzureCredential() expects the following environment variables:
        # * AZURE_CLIENT_ID
        # * AZURE_CLIENT_SECRET
        # * AZURE_TENANT_ID
        authority_host = os.environ.get(
            'AZURE_AUTHORITY_HOST') or KnownAuthorities.AZURE_PUBLIC_CLOUD
        credential = DefaultAzureCredential(authority=authority_host)
        self.key_client = KeyClient(vault_url=os.environ["AZURE_PROJECT_URL"],
                                    credential=credential)

        self.key_name = "key-name-" + uuid.uuid1().hex

    def create_rsa_key(self):
        print("Creating an RSA key...")
        self.key_client.create_rsa_key(name=self.key_name, size=2048)
        print("\tdone")

    def get_key(self):
        print("Getting a key...")
        key = self.key_client.get_key(name=self.key_name)
        print("\tdone, key: {}.".format(key.name))

    def delete_key(self):
        print("Deleting a key...")
        deleted_key = self.key_client.begin_delete_key(
            name=self.key_name).result()
        print("\tdone: " + deleted_key.name)

    def run(self):
        print("")
        print("------------------------")
        print("Key Vault - Keys\nIdentity - Credential")
        print("------------------------")
        print("1) Create a key")
        print("2) Get that key")
        print("3) Delete that key (Clean up the resource)")
        print("")

        try:
            self.create_rsa_key()
            self.get_key()
        finally:
            self.delete_key()
class KeyVaultKeys:
    def __init__(self):
        # DefaultAzureCredential() expects the following environment variables:
        # * AZURE_CLIENT_ID
        # * AZURE_CLIENT_SECRET
        # * AZURE_TENANT_ID
        credential = DefaultAzureCredential()
        self.key_client = KeyClient(vault_url=os.environ["AZURE_PROJECT_URL"],
                                    credential=credential)

        self.key_name = "key-name-" + uuid.uuid1().hex

    def create_rsa_key(self):
        print("Creating an RSA key...")
        self.key_client.create_rsa_key(name=self.key_name,
                                       size=2048,
                                       hsm=False)
        print("\tdone")

    def get_key(self):
        print("Getting a key...")
        key = self.key_client.get_key(name=self.key_name)
        print("\tdone, key: %s." % key.name)

    def delete_key(self):
        print("Deleting a key...")
        deleted_key = self.key_client.delete_key(name=self.key_name)
        print("\tdone: " + deleted_key.name)

    def run(self):
        print("")
        print("------------------------")
        print("Key Vault - Keys\nIdentity - Credential")
        print("------------------------")
        print("1) Create a key")
        print("2) Get that key")
        print("3) Delete that key (Clean up the resource)")
        print("")

        try:
            self.create_rsa_key()
            self.get_key()
        finally:
            self.delete_key()
class KeyVaultRSAKey(rsa.RSAPublicKey, rsa.RSAPrivateKey):
    """Azure KeyVault provider for public and private account key"""
    def __init__(self, credentials, vault_url: str, key_name: str):
        self.vault_url = vault_url
        self.key_name = key_name

        self.key_client = KeyClient(vault_url=vault_url,
                                    credential=credentials)

        try:
            self.kv_key = self.key_client.get_key(key_name)
            logger.info('Using existing user key from KeyVault')
        except ResourceNotFoundError:
            logger.info('Creating new user key in KeyVault')
            self.kv_key = self.key_client.create_rsa_key(key_name,
                                                         size=self.key_size)

        self.crypto_client = CryptographyClient(self.kv_key,
                                                credential=credentials)

    @property
    def key_size(self):
        return 2048

    def encrypt(self, plaintext, padding):
        result = self.crypto_client.encrypt(EncryptionAlgorithm.rsa_oaep,
                                            plaintext)
        return result

    def public_numbers(self):
        e = int.from_bytes(self.kv_key.key.e, byteorder='big')
        n = int.from_bytes(self.kv_key.key.n, byteorder='big')
        return rsa.RSAPublicNumbers(e, n)

    def public_bytes(self):
        pass

    def verifier(self, signature, padding, algorithm):
        pass

    def verify(self, signature, data, padding, algorithm):
        pass

    def public_key(self):
        return self

    def signer(self, padding, algorithm):
        pass

    def decrypt(self, ciphertext, padding):
        pass

    def sign(self, data, padding, algorithm):
        value = hashlib.sha256(data).digest()
        res = self.crypto_client.sign(SignatureAlgorithm.rs256, digest=value)
        return res.signature
    def test_selective_key_restore(self, container_uri, sas_token):
        # create a key to selectively restore
        key_client = KeyClient(self.managed_hsm["url"], self.credential)
        key_name = self.get_resource_name("selective-restore-test-key")
        key_client.create_rsa_key(key_name)

        # backup the vault
        backup_client = KeyVaultBackupClient(self.managed_hsm["url"],
                                             self.credential)
        backup_poller = backup_client.begin_full_backup(
            container_uri, sas_token)

        # check backup status and result
        job_id = backup_poller.polling_method().resource().id
        backup_status = backup_client.get_backup_status(job_id)
        assert_in_progress_operation(backup_status)
        backup_operation = backup_poller.result()
        assert_successful_operation(backup_operation)
        backup_status = backup_client.get_backup_status(job_id)
        assert_successful_operation(backup_status)

        # restore the key
        folder_name = backup_operation.azure_storage_blob_container_uri.split(
            "/")[-1]
        restore_poller = backup_client.begin_selective_restore(
            container_uri, sas_token, folder_name, key_name)

        # check restore status and result
        job_id = restore_poller.polling_method().resource().id
        restore_status = backup_client.get_restore_status(job_id)
        assert_in_progress_operation(restore_status)
        restore_operation = restore_poller.result()
        assert_successful_operation(restore_operation)
        restore_status = backup_client.get_restore_status(job_id)
        assert_successful_operation(restore_status)

        # delete the key
        delete_function = partial(key_client.begin_delete_key, key_name)
        delete_poller = self._poll_until_no_exception(delete_function,
                                                      ResourceExistsError)
        delete_poller.wait()
        key_client.purge_deleted_key(key_name)
    def test_selective_key_restore(self, container_uri, sas_token):
        # create a key to selectively restore
        key_client = KeyClient(self.managed_hsm["url"], self.credential)
        key_name = self.get_resource_name("selective-restore-test-key")
        key_client.create_rsa_key(key_name)

        # backup the vault
        backup_client = KeyVaultBackupClient(self.managed_hsm["url"], self.credential)
        backup_poller = backup_client.begin_full_backup(container_uri, sas_token)
        backup_operation = backup_poller.result()
        assert_successful_operation(backup_operation)

        # restore the key
        folder_name = backup_operation.azure_storage_blob_container_uri.split("/")[-1]
        restore_poller = backup_client.begin_selective_restore(container_uri, sas_token, folder_name, key_name)
        restore_operation = restore_poller.result()
        assert_successful_operation(restore_operation)

        key_client.begin_delete_key(key_name).wait()
        key_client.purge_deleted_key(key_name)
Пример #8
0
class KeyVaultKeys(KeyVaultBase):
    def __init__(self):
        credential = self.get_default_credential()
        self.key_client = KeyClient(vault_url=os.environ["AZURE_PROJECT_URL"],
                                    credential=credential)

        self.key_name = "key-name-" + uuid.uuid1().hex

    def create_rsa_key(self):
        print("Creating an RSA key...")
        self.key_client.create_rsa_key(name=self.key_name, size=2048)
        print("\tdone")

    def get_key(self):
        print("Getting a key...")
        key = self.key_client.get_key(name=self.key_name)
        print("\tdone, key: {}.".format(key.name))

    def delete_key(self):
        print("Deleting a key...")
        deleted_key = self.key_client.begin_delete_key(
            name=self.key_name).result()
        print("\tdone: " + deleted_key.name)

    def run(self):
        print("")
        print("------------------------")
        print("Key Vault - Keys\nIdentity - Credential")
        print("------------------------")
        print("1) Create a key")
        print("2) Get that key")
        print("3) Delete that key (Clean up the resource)")
        print("")

        try:
            self.create_rsa_key()
            self.get_key()
        finally:
            self.delete_key()
Пример #9
0
    def test_selective_key_restore(self, container_uri, sas_token):
        # create a key to selectively restore
        key_client = KeyClient(self.managed_hsm["url"], self.credential)
        key_name = self.get_resource_name("selective-restore-test-key")
        key_client.create_rsa_key(key_name)

        # backup the vault
        backup_client = KeyVaultBackupClient(self.managed_hsm["url"],
                                             self.credential)
        backup_poller = backup_client.begin_backup(container_uri, sas_token)
        backup_operation = backup_poller.result()

        # restore the key
        restore_poller = backup_client.begin_restore(
            backup_operation.folder_url, sas_token, key_name=key_name)
        restore_poller.wait()

        # delete the key
        delete_function = partial(key_client.begin_delete_key, key_name)
        delete_poller = self._poll_until_no_exception(delete_function,
                                                      ResourceExistsError)
        delete_poller.wait()
        key_client.purge_deleted_key(key_name)
    def test_example_selective_key_restore(self, container_uri, sas_token):
        # create a key to selectively restore
        key_client = KeyClient(self.managed_hsm["url"], self.credential)
        key_name = self.get_resource_name("selective-restore-test-key")
        key_client.create_rsa_key(key_name)

        backup_client = KeyVaultBackupClient(self.managed_hsm["url"],
                                             self.credential)
        backup_poller = backup_client.begin_backup(container_uri, sas_token)
        backup_operation = backup_poller.result()
        folder_url = backup_operation.folder_url

        # [START begin_selective_restore]
        # begin a restore of a single key from a backed up vault
        restore_poller = backup_client.begin_restore(folder_url,
                                                     sas_token,
                                                     key_name=key_name)

        # check if the restore completed
        done = backup_poller.done()

        # wait for the restore to complete
        restore_poller.wait()
Пример #11
0
def run_sample():
    # Instantiate a key client that will be used to call the service.
    # Notice that the client is using default Azure credentials.
    # To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
    # 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
    VAULT_URL = os.environ["VAULT_URL"]
    credential = DefaultAzureCredential()
    client = KeyClient(vault_url=VAULT_URL, credential=credential)
    try:
        # Let's create keys with RSA and EC type. If the key
        # already exists in the Key Vault, then a new version of the key is created.
        print("\n1. Create Key")
        rsa_key = client.create_rsa_key("rsaKeyName", hsm=False)
        ec_key = client.create_ec_key("ecKeyName", hsm=False)
        print("Key with name '{0}' was created of type '{1}'.".format(rsa_key.name, rsa_key.key_material.kty))
        print("Key with name '{0}' was created of type '{1}'.".format(ec_key.name, ec_key.key_material.kty))

        # The ec key is no longer needed. Need to delete it from the Key Vault.
        print("\n2. Delete a Key")
        key = client.delete_key(rsa_key.name)
        time.sleep(20)
        print("Key with name '{0}' was deleted on date {1}.".format(key.name, key.deleted_date))

        # We accidentally deleted the rsa key. Let's recover it.
        # A deleted key can only be recovered if the Key Vault is soft-delete enabled.
        print("\n3. Recover Deleted  Key")
        recovered_key = client.recover_deleted_key(rsa_key.name)
        print("Recovered Key with name '{0}'.".format(recovered_key.name))

        # Let's delete ec key now.
        # If the keyvault is soft-delete enabled, then for permanent deletion deleted key needs to be purged.
        client.delete_key(ec_key.name)

        # To ensure key is deleted on the server side.
        print("\nDeleting EC Key...")
        time.sleep(20)

        # To ensure permanent deletion, we might need to purge the key.
        print("\n4. Purge Deleted Key")
        client.purge_deleted_key(ec_key.name)
        print("EC Key has been permanently deleted.")

    except HttpResponseError as e:
        if "(NotSupported)" in e.message:
            print("\n{0} Please enable soft delete on Key Vault to perform this operation.".format(e.message))
        else:
            print("\nrun_sample has caught an error. {0}".format(e.message))

    finally:
        print("\nrun_sample done")
Пример #12
0
# Instantiate a key client that will be used to call the service.
# Notice that the client is using default Azure credentials.
# To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
# 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
VAULT_ENDPOINT = os.environ["VAULT_ENDPOINT"]
credential = DefaultAzureCredential()
client = KeyClient(vault_endpoint=VAULT_ENDPOINT, credential=credential)
try:
    # Let's create an RSA key with size 2048, hsm disabled and optional key_operations of encrypt, decrypt.
    # if the key already exists in the Key Vault, then a new version of the key is created.
    print("\n.. Create an RSA Key")
    key_size = 2048
    key_ops = ["encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey"]
    key_name = "rsaKeyName"
    rsa_key = client.create_rsa_key(key_name,
                                    size=key_size,
                                    hsm=False,
                                    key_operations=key_ops)
    print("RSA Key with name '{0}' created of type '{1}'.".format(
        rsa_key.name, rsa_key.key_material.kty))

    # Let's create an Elliptic Curve key with algorithm curve type P-256.
    # if the key already exists in the Key Vault, then a new version of the key is created.
    print("\n.. Create an EC Key")
    key_curve = "P-256"
    key_name = "ECKeyName"
    ec_key = client.create_ec_key(key_name, curve=key_curve, hsm=False)
    print("EC Key with name '{0}' created of type '{1}'.".format(
        ec_key.name, ec_key.key_material.kty))

    # Let's get the rsa key details using its name
    print("\n.. Get a Key by its name")
#
# 3. Recover a deleted key (recover_deleted_key)
#
# 4. Purge a deleted key (purge_deleted_key)
# ----------------------------------------------------------------------------------------------------------

# Instantiate a key client that will be used to call the service.
# Notice that the client is using default Azure credentials.
# To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
# 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
VAULT_URL = os.environ["VAULT_URL"]
credential = DefaultAzureCredential()
client = KeyClient(vault_url=VAULT_URL, credential=credential)
try:
    print("\n.. Create keys")
    rsa_key = client.create_rsa_key("rsaKeyName", hsm=False)
    ec_key = client.create_ec_key("ecKeyName", hsm=False)
    print("Created key '{0}' of type '{1}'.".format(rsa_key.name,
                                                    rsa_key.key_material.kty))
    print("Created key '{0}' of type '{1}'.".format(ec_key.name,
                                                    ec_key.key_material.kty))

    print("\n.. Delete the keys")
    for key_name in (ec_key.name, rsa_key.name):
        deleted_key = client.delete_key(key_name)
        print("Deleted key '{0}'".format(deleted_key.name))

    time.sleep(20)

    print("\n.. Recover a deleted key")
    recovered_key = client.recover_deleted_key(rsa_key.name)
Пример #14
0
# operation.
#
# ----------------------------------------------------------------------------------------------------------

# Instantiate a key client that will be used to call the service.
# Notice that the client is using default Azure credentials.
# To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
# 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
VAULT_URL = os.environ["VAULT_URL"]
credential = DefaultAzureCredential()
client = KeyClient(vault_url=VAULT_URL, credential=credential)

# Let's create keys with RSA and EC type. If the key
# already exists in the Key Vault, then a new version of the key is created.
print("\n.. Create Key")
rsa_key = client.create_rsa_key("rsaKeyName")
ec_key = client.create_ec_key("ecKeyName")
print("Key with name '{0}' was created of type '{1}'.".format(rsa_key.name, rsa_key.key_type))
print("Key with name '{0}' was created of type '{1}'.".format(ec_key.name, ec_key.key_type))

# You need to check the type of all the keys in the vault.
# Let's list the keys and print their key types.
# List operations don 't return the keys with their type information.
# So, for each returned key we call get_key to get the key with its type information.
print("\n.. List keys from the Key Vault")
keys = client.list_properties_of_keys()
for key in keys:
    retrieved_key = client.get_key(key.name)
    print(
        "Key with name '{0}' with type '{1}' was found.".format(retrieved_key.name, retrieved_key.key_type)
    )
# operation.
#
# ----------------------------------------------------------------------------------------------------------

# Instantiate a key client that will be used to call the service.
# Notice that the client is using default Azure credentials.
# To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
# 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
VAULT_URL = os.environ["VAULT_URL"]
credential = DefaultAzureCredential()
client = KeyClient(vault_url=VAULT_URL, credential=credential)
try:
    # Let's create keys with RSA and EC type. If the key
    # already exists in the Key Vault, then a new version of the key is created.
    print("\n.. Create Key")
    rsa_key = client.create_rsa_key("rsaKeyName", hsm=False)
    ec_key = client.create_ec_key("ecKeyName", hsm=False)
    print("Key with name '{0}' was created of type '{1}'.".format(
        rsa_key.name, rsa_key.key_material.kty))
    print("Key with name '{0}' was created of type '{1}'.".format(
        ec_key.name, ec_key.key_material.kty))

    # You need to check the type of all the keys in the vault.
    # Let's list the keys and print their key types.
    # List operations don 't return the keys with their type information.
    # So, for each returned key we call get_key to get the key with its type information.
    print("\n.. List keys from the Key Vault")
    keys = client.list_keys()
    for key in keys:
        retrieved_key = client.get_key(key.name)
        print("Key with name '{0}' with type '{1}' was found.".format(
Пример #16
0
def run_sample():
    # Instantiate a key client that will be used to call the service.
    # Notice that the client is using default Azure credentials.
    # To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
    # 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
    VAULT_URL = os.environ["VAULT_URL"]
    credential = DefaultAzureCredential()
    client = KeyClient(vault_url=VAULT_URL, credential=credential)
    try:
        # Let's create an RSA key with size 2048, hsm disabled and optional key_operations of encrypt, decrypt.
        # if the key already exists in the Key Vault, then a new version of the key is created.
        print("\n1. Create an RSA Key")
        key_size = 2048
        key_ops = [
            "encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey"
        ]
        key_name = "rsaKeyName"
        rsa_key = client.create_rsa_key(key_name,
                                        size=key_size,
                                        hsm=False,
                                        key_operations=key_ops)
        print("RSA Key with name '{0}' created of type '{1}'.".format(
            rsa_key.name, rsa_key.key_material.kty))

        # Let's create an Elliptic Curve key with algorithm curve type P-256.
        # if the key already exists in the Key Vault, then a new version of the key is created.
        print("\n1. Create an EC Key")
        key_curve = "P-256"
        key_name = "ECKeyName"
        ec_key = client.create_ec_key(key_name, curve=key_curve, hsm=False)
        print("EC Key with name '{0}' created of type '{1}'.".format(
            ec_key.name, ec_key.key_material.kty))

        # Let's get the rsa key details using its name
        print("\n2. Get a Key using it's name")
        rsa_key = client.get_key(rsa_key.name)
        print("Key with name '{0}' was found.".format(rsa_key.name))

        # Let's say we want to update the expiration time for the EC key and disable the key to be useable for cryptographic operations.
        # The update method allows the user to modify the metadata (key attributes) associated with a key previously stored within Key Vault.
        print("\n3. Update a Key by name")
        expires = datetime.datetime.utcnow() + datetime.timedelta(days=365)
        updated_ec_key = client.update_key(ec_key.name,
                                           ec_key.version,
                                           expires=expires,
                                           enabled=False)
        print("Key with name '{0}' was updated on date '{1}'".format(
            updated_ec_key.name, updated_ec_key.updated))
        print("Key with name '{0}' was updated to expire on '{1}'".format(
            updated_ec_key.name, updated_ec_key.expires))

        # The RSA key is no longer used, need to delete it from the Key Vault.
        print("\n4. Delete Key")
        deleted_key = client.delete_key(rsa_key.name)
        print("Deleting Key..")
        print("Key with name '{0}' was deleted.".format(deleted_key.name))

    except HttpResponseError as e:
        print("\nrun_sample has caught an error. {0}".format(e.message))

    finally:
        print("\nrun_sample done")
#
# 3. Recover a deleted key (begin_recover_deleted_key)
#
# 4. Purge a deleted key (purge_deleted_key)
# ----------------------------------------------------------------------------------------------------------

# Instantiate a key client that will be used to call the service.
# Notice that the client is using default Azure credentials.
# To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
# 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
VAULT_ENDPOINT = os.environ["VAULT_ENDPOINT"]
credential = DefaultAzureCredential()
client = KeyClient(vault_endpoint=VAULT_ENDPOINT, credential=credential)
try:
    print("\n.. Create keys")
    rsa_key = client.create_rsa_key("rsaKeyName")
    ec_key = client.create_ec_key("ecKeyName")
    print("Created key '{0}' of type '{1}'.".format(rsa_key.name, rsa_key.key_type))
    print("Created key '{0}' of type '{1}'.".format(ec_key.name, ec_key.key_type))

    print("\n.. Delete the keys")
    for key_name in (ec_key.name, rsa_key.name):
        deleted_key = client.begin_delete_key(key_name).result()
        print("Deleted key '{0}'".format(deleted_key.name))

    print("\n.. Recover a deleted key")
    recovered_key = client.begin_recover_deleted_key(rsa_key.name).result()
    print("Recovered key '{0}'".format(recovered_key.name))

    # deleting the recovered key so it doesn't outlast this script
    client.begin_delete_key(recovered_key.name).wait()
# 3. Update a key's rotation policy (update_key_rotation_policy)
#
# 4. Rotate a key on-demand (rotate_key)
#
# 5. Delete a key (begin_delete_key)
# ----------------------------------------------------------------------------------------------------------

# Instantiate a key client that will be used to call the service.
# Here we use the DefaultAzureCredential, but any azure-identity credential can be used.
VAULT_URL = os.environ["VAULT_URL"]
credential = DefaultAzureCredential()
client = KeyClient(vault_url=VAULT_URL, credential=credential)

# First, create a key
key_name = "rotation-sample-key"
key = client.create_rsa_key(key_name)
print("\nCreated a key; new version is {}".format(key.properties.version))

# Set the key's automated rotation policy to rotate the key two months after the key was created
actions = [
    KeyRotationLifetimeAction(KeyRotationPolicyAction.ROTATE,
                              time_after_create="P2M")
]
updated_policy = client.update_key_rotation_policy(key_name,
                                                   lifetime_actions=actions)

# The created policy should only have one action
assert len(updated_policy.lifetime_actions
           ) == 1, "There should be exactly one rotation policy action"
policy_action = updated_policy.lifetime_actions[0]
print("\nCreated a new key rotation policy: {} after {}".format(
def run_sample():
    # Instantiate a key client that will be used to call the service.
    # Notice that the client is using default Azure credentials.
    # To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
    # 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
    VAULT_URL = os.environ["VAULT_URL"]
    credential = DefaultAzureCredential()
    client = KeyClient(vault_url=VAULT_URL, credential=credential)
    try:
        # Let's create keys with RSA and EC type. If the key
        # already exists in the Key Vault, then a new version of the key is created.
        print("\n1. Create Key")
        rsa_key = client.create_rsa_key("rsaKeyName", hsm=False)
        ec_key = client.create_ec_key("ecKeyName", hsm=False)
        print("Key with name '{0}' was created of type '{1}'.".format(
            rsa_key.name, rsa_key.key_material.kty))
        print("Key with name '{0}' was created of type '{1}'.".format(
            ec_key.name, ec_key.key_material.kty))

        # You need to check the type of all the keys in the vault.
        # Let's list the keys and print their key types.
        # List operations don 't return the keys with their type information.
        # So, for each returned key we call get_key to get the key with its type information.
        print("\n2. List keys from the Key Vault")
        keys = client.list_keys()
        for key in keys:
            retrieved_key = client.get_key(key.name)
            print("Key with name '{0}' with type '{1}' was found.".format(
                retrieved_key.name, retrieved_key.key_material.kty))

        # The rsa key size now should now be 3072, default - 2048. So you want to update the key in Key Vault to ensure
        # it reflects the new key size. Calling create_rsa_key on an existing key creates a new version of the key in
        # the Key Vault with the new key size.
        new_key = client.create_rsa_key(rsa_key.name, hsm=False, size=3072)
        print(
            "New version was created for Key with name '{0}' with the updated size."
            .format(new_key.name))

        # You should have more than one version of the rsa key at this time. Lets print all the versions of this key.
        print("\n3. List versions of the key using its name")
        key_versions = client.list_key_versions(rsa_key.name)
        for key in key_versions:
            print("RSA Key with name '{0}' has version: '{1}'".format(
                key.name, key.version))

        # Both the rsa key and ec key are not needed anymore. Let's delete those keys.
        client.delete_key(rsa_key.name)
        client.delete_key(ec_key.name)

        # To ensure key is deleted on the server side.
        print("\nDeleting keys...")
        time.sleep(20)

        # You can list all the deleted and non-purged keys, assuming Key Vault is soft-delete enabled.
        print("\n3. List deleted keys from the Key Vault")
        deleted_keys = client.list_deleted_keys()
        for deleted_key in deleted_keys:
            print("Key with name '{0}' has recovery id '{1}'".format(
                deleted_key.name, deleted_key.recovery_id))

    except HttpResponseError as e:
        if "(NotSupported)" in e.message:
            print(
                "\n{0} Please enable soft delete on Key Vault to perform this operation."
                .format(e.message))
        else:
            print("\nrun_sample has caught an error. {0}".format(e.message))

    finally:
        print("\nrun_sample done")