Skip to content

Commit cbf7ba8

Browse files
authored
[KV] Add executable rotation samples (Azure#21161)
1 parent 8b97ddd commit cbf7ba8

12 files changed

+276
-93
lines changed

sdk/keyvault/azure-keyvault-keys/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ from azure.keyvault.keys import KeyClient, KeyRotationLifetimeAction, KeyRotatio
251251
credential = DefaultAzureCredential()
252252
key_client = KeyClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential)
253253

254-
# Set the key's automated rotation policy to rotate the key 30 days before expiry
254+
# Set the key's automated rotation policy to rotate the key 30 days before the key expires
255255
actions = [KeyRotationLifetimeAction(KeyRotationPolicyAction.ROTATE, time_before_expiry="P30D")]
256256
# You may also specify the duration after which the newly rotated key will expire
257257
# In this example, any new key versions will expire after 90 days

sdk/keyvault/azure-keyvault-keys/samples/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ These code snippets highlight this SDK's common use cases.
2020
[backup_restore_operations_async.py][backup_operations_async_sample] - backup and
2121
recover keys
2222
* [recover_purge_operations.py][recover_purge_sample] and
23-
[recover_purge_operations_async.py][recover_purge_async_sample] - recovering and purging keys
23+
[recover_purge_operations_async.py][recover_purge_async_sample] - recover and purge keys
24+
* [key_rotation.py][key_rotation_sample] and
25+
[key_rotation_async.py][key_rotation_async_sample] - rotate keys automatically and on-demand
2426

2527
[hello_world_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys/samples/hello_world.py
2628
[hello_world_async_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys/samples/hello_world_async.py
@@ -29,4 +31,6 @@ recover keys
2931
[list_operations_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys/samples/list_operations.py
3032
[list_operations_async_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys/samples/list_operations_async.py
3133
[recover_purge_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations.py
32-
[recover_purge_async_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations_async.py
34+
[recover_purge_async_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys/samples/recover_purge_operations_async.py
35+
[key_rotation_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys/samples/key_rotation.py
36+
[key_rotation_async_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys/samples/key_rotation_async.py

sdk/keyvault/azure-keyvault-keys/samples/backup_restore_operations.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,23 @@
44
# ------------------------------------
55
import os
66
import time
7-
from azure.keyvault.keys import KeyClient
87
from azure.identity import DefaultAzureCredential
9-
from azure.core.exceptions import HttpResponseError
8+
from azure.keyvault.keys import KeyClient
109

1110
# ----------------------------------------------------------------------------------------------------------
1211
# Prerequisites:
13-
# 1. An Azure Key Vault (https://docs.microsoft.com/en-us/azure/key-vault/quick-create-cli)
12+
# 1. An Azure Key Vault (https://docs.microsoft.com/azure/key-vault/quick-create-cli)
1413
#
1514
# 2. azure-keyvault-keys and azure-identity libraries (pip install these)
1615
#
17-
# 3. Set Environment variables AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, VAULT_URL
16+
# 3. Set environment variable VAULT_URL with the URL of your key vault
17+
#
18+
# 4. Set up your environment to use azure-identity's DefaultAzureCredential. To authenticate a service principal with
19+
# environment variables, set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID
1820
# (See https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys#authenticate-the-client)
1921
#
22+
# 5. Key create, backup, delete, purge, and restore permissions for your service principal in your vault
23+
#
2024
# ----------------------------------------------------------------------------------------------------------
2125
# Sample - demonstrates the basic backup and restore operations on a vault(key) resource for Azure Key Vault
2226
#
@@ -32,9 +36,7 @@
3236
# ----------------------------------------------------------------------------------------------------------
3337

3438
# Instantiate a key client that will be used to call the service.
35-
# Notice that the client is using default Azure credentials.
36-
# To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
37-
# 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
39+
# Here we use the DefaultAzureCredential, but any azure-identity credential can be used.
3840
VAULT_URL = os.environ["VAULT_URL"]
3941
credential = DefaultAzureCredential()
4042
client = KeyClient(vault_url=VAULT_URL, credential=credential)

sdk/keyvault/azure-keyvault-keys/samples/backup_restore_operations_async.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,23 @@
44
# ------------------------------------
55
import asyncio
66
import os
7-
from azure.keyvault.keys.aio import KeyClient
87
from azure.identity.aio import DefaultAzureCredential
9-
from azure.core.exceptions import HttpResponseError
8+
from azure.keyvault.keys.aio import KeyClient
109

1110
# ----------------------------------------------------------------------------------------------------------
1211
# Prerequisites:
13-
# 1. An Azure Key Vault (https://docs.microsoft.com/en-us/azure/key-vault/quick-create-cli)
12+
# 1. An Azure Key Vault (https://docs.microsoft.com/azure/key-vault/quick-create-cli)
1413
#
1514
# 2. azure-keyvault-keys and azure-identity libraries (pip install these)
1615
#
17-
# 3. Set Environment variables AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, VAULT_URL
16+
# 3. Set environment variable VAULT_URL with the URL of your key vault
17+
#
18+
# 4. Set up your environment to use azure-identity's DefaultAzureCredential. To authenticate a service principal with
19+
# environment variables, set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID
1820
# (See https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys#authenticate-the-client)
1921
#
22+
# 5. Key create, backup, delete, purge, and restore permissions for your service principal in your vault
23+
#
2024
# ----------------------------------------------------------------------------------------------------------
2125
# Sample - demonstrates the basic backup and restore operations on a vault(key) resource for Azure Key Vault
2226
#
@@ -30,11 +34,10 @@
3034
#
3135
# 5. Restore a key (restore_key_backup)
3236
# ----------------------------------------------------------------------------------------------------------
37+
3338
async def run_sample():
3439
# Instantiate a key client that will be used to call the service.
35-
# Notice that the client is using default Azure credentials.
36-
# To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
37-
# 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
40+
# Here we use the DefaultAzureCredential, but any azure-identity credential can be used.
3841
VAULT_URL = os.environ["VAULT_URL"]
3942
credential = DefaultAzureCredential()
4043
client = KeyClient(vault_url=VAULT_URL, credential=credential)

sdk/keyvault/azure-keyvault-keys/samples/hello_world.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,23 @@
44
# ------------------------------------
55
import datetime
66
import os
7-
from azure.keyvault.keys import KeyClient
87
from azure.identity import DefaultAzureCredential
9-
from azure.core.exceptions import HttpResponseError
8+
from azure.keyvault.keys import KeyClient
109

1110
# ----------------------------------------------------------------------------------------------------------
1211
# Prerequisites:
13-
# 1. An Azure Key Vault (https://docs.microsoft.com/en-us/azure/key-vault/quick-create-cli)
12+
# 1. An Azure Key Vault (https://docs.microsoft.com/azure/key-vault/quick-create-cli)
1413
#
1514
# 2. azure-keyvault-keys and azure-identity libraries (pip install these)
1615
#
17-
# 3. Set Environment variables AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, VAULT_URL
16+
# 3. Set environment variable VAULT_URL with the URL of your key vault
17+
#
18+
# 4. Set up your environment to use azure-identity's DefaultAzureCredential. To authenticate a service principal with
19+
# environment variables, set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID
1820
# (See https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys#authenticate-the-client)
1921
#
22+
# 5. Key create, get, update, and delete permissions for your service principal in your vault
23+
#
2024
# ----------------------------------------------------------------------------------------------------------
2125
# Sample - demonstrates the basic CRUD operations on a vault(key) resource for Azure Key Vault
2226
#
@@ -32,9 +36,7 @@
3236
# ----------------------------------------------------------------------------------------------------------
3337

3438
# Instantiate a key client that will be used to call the service.
35-
# Notice that the client is using default Azure credentials.
36-
# To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
37-
# 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
39+
# Here we use the DefaultAzureCredential, but any azure-identity credential can be used.
3840
VAULT_URL = os.environ["VAULT_URL"]
3941
credential = DefaultAzureCredential()
4042
client = KeyClient(vault_url=VAULT_URL, credential=credential)

sdk/keyvault/azure-keyvault-keys/samples/hello_world_async.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,26 @@
22
# Copyright (c) Microsoft Corporation.
33
# Licensed under the MIT License.
44
# ------------------------------------
5-
import datetime
65
import asyncio
6+
import datetime
77
import os
8-
from azure.keyvault.keys.aio import KeyClient
98
from azure.identity.aio import DefaultAzureCredential
10-
from azure.core.exceptions import HttpResponseError
9+
from azure.keyvault.keys.aio import KeyClient
1110

1211
# ----------------------------------------------------------------------------------------------------------
1312
# Prerequisites:
14-
# 1. An Azure Key Vault (https://docs.microsoft.com/en-us/azure/key-vault/quick-create-cli)
13+
# 1. An Azure Key Vault (https://docs.microsoft.com/azure/key-vault/quick-create-cli)
1514
#
1615
# 2. azure-keyvault-keys and azure-identity libraries (pip install these)
1716
#
18-
# 3. Set Environment variables AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, VAULT_URL
17+
# 3. Set environment variable VAULT_URL with the URL of your key vault
18+
#
19+
# 4. Set up your environment to use azure-identity's DefaultAzureCredential. To authenticate a service principal with
20+
# environment variables, set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID
1921
# (See https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys#authenticate-the-client)
2022
#
23+
# 5. Key create, get, update, and delete permissions for your service principal in your vault
24+
#
2125
# ----------------------------------------------------------------------------------------------------------
2226
# Sample - demonstrates the basic CRUD operations on a vault(key) resource for Azure Key Vault
2327
#
@@ -31,11 +35,10 @@
3135
#
3236
# 5. Delete a key (delete_key)
3337
# ----------------------------------------------------------------------------------------------------------
38+
3439
async def run_sample():
3540
# Instantiate a key client that will be used to call the service.
36-
# Notice that the client is using default Azure credentials.
37-
# To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
38-
# 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
41+
# Here we use the DefaultAzureCredential, but any azure-identity credential can be used.
3942
VAULT_URL = os.environ["VAULT_URL"]
4043
credential = DefaultAzureCredential()
4144
client = KeyClient(vault_url=VAULT_URL, credential=credential)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# ------------------------------------
2+
# Copyright (c) Microsoft Corporation.
3+
# Licensed under the MIT License.
4+
# ------------------------------------
5+
import os
6+
from azure.identity import DefaultAzureCredential
7+
from azure.keyvault.keys import KeyClient, KeyRotationLifetimeAction, KeyRotationPolicyAction
8+
9+
# ----------------------------------------------------------------------------------------------------------
10+
# Prerequisites:
11+
# 1. An Azure Key Vault (https://docs.microsoft.com/azure/key-vault/quick-create-cli)
12+
#
13+
# 2. azure-keyvault-keys and azure-identity libraries (pip install these)
14+
#
15+
# 3. Set environment variable VAULT_URL with the URL of your key vault
16+
#
17+
# 4. Set up your environment to use azure-identity's DefaultAzureCredential. To authenticate a service principal with
18+
# environment variables, set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID
19+
# (See https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys#authenticate-the-client)
20+
#
21+
# 5. Key rotation permissions for your service principal in your vault
22+
#
23+
# ----------------------------------------------------------------------------------------------------------
24+
# Sample - creates and updates a key's automated rotation policy, and rotates a key on-demand
25+
#
26+
# 1. Create a new key rotation policy (update_key_rotation_policy)
27+
#
28+
# 2. Get a key's current rotation policy (get_key_rotation_policy)
29+
#
30+
# 3. Update a key's rotation policy (update_key_rotation_policy)
31+
#
32+
# 4. Rotate a key on-demand (rotate_key)
33+
#
34+
# 5. Delete a key (begin_delete_key)
35+
# ----------------------------------------------------------------------------------------------------------
36+
37+
# Instantiate a key client that will be used to call the service.
38+
# Here we use the DefaultAzureCredential, but any azure-identity credential can be used.
39+
VAULT_URL = os.environ["VAULT_URL"]
40+
credential = DefaultAzureCredential()
41+
client = KeyClient(vault_url=VAULT_URL, credential=credential)
42+
43+
# First, create a key
44+
key_name = "rotation-sample-key"
45+
key = client.create_rsa_key(key_name)
46+
print("\nCreated a key; new version is {}".format(key.properties.version))
47+
48+
# Set the key's automated rotation policy to rotate the key two months after the key was created
49+
actions = [KeyRotationLifetimeAction(KeyRotationPolicyAction.ROTATE, time_after_create="P2M")]
50+
updated_policy = client.update_key_rotation_policy(key_name, lifetime_actions=actions)
51+
52+
# The created policy should only have one action
53+
assert len(updated_policy.lifetime_actions) == 1, "There should be exactly one rotation policy action"
54+
policy_action = updated_policy.lifetime_actions[0]
55+
print("\nCreated a new key rotation policy: {} after {}".format(policy_action.action, policy_action.time_after_create))
56+
57+
# Get the key's current rotation policy
58+
current_policy = client.get_key_rotation_policy(key_name)
59+
policy_action = current_policy.lifetime_actions[0]
60+
print("\nCurrent rotation policy: {} after {}".format(policy_action.action, policy_action.time_after_create))
61+
62+
# Update the key's automated rotation policy to notify 30 days before the key expires
63+
new_actions = [KeyRotationLifetimeAction(KeyRotationPolicyAction.NOTIFY, time_before_expiry="P30D")]
64+
# You may also specify the duration after which the newly rotated key will expire
65+
# In this example, any new key versions will expire after 90 days
66+
new_policy = client.update_key_rotation_policy(key_name, expires_in="P90D", lifetime_actions=new_actions)
67+
68+
# The updated policy should only have one action
69+
assert len(new_policy.lifetime_actions) == 1, "There should be exactly one rotation policy action"
70+
policy_action = new_policy.lifetime_actions[0]
71+
print("\nUpdated rotation policy: {} {} before expiry".format(policy_action.action, policy_action.time_before_expiry))
72+
73+
# Finally, you can rotate a key on-demand by creating a new version of the key
74+
rotated_key = client.rotate_key(key_name)
75+
print("\nRotated the key on-demand; new version is {}".format(rotated_key.properties.version))
76+
77+
# To clean up, delete the key
78+
client.begin_delete_key(key_name)
79+
print("\nDeleted the key")
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# ------------------------------------
2+
# Copyright (c) Microsoft Corporation.
3+
# Licensed under the MIT License.
4+
# ------------------------------------
5+
import asyncio
6+
import os
7+
from azure.identity.aio import DefaultAzureCredential
8+
from azure.keyvault.keys import KeyRotationLifetimeAction, KeyRotationPolicyAction
9+
from azure.keyvault.keys.aio import KeyClient
10+
11+
# ----------------------------------------------------------------------------------------------------------
12+
# Prerequisites:
13+
# 1. An Azure Key Vault (https://docs.microsoft.com/azure/key-vault/quick-create-cli)
14+
#
15+
# 2. azure-keyvault-keys and azure-identity libraries (pip install these)
16+
#
17+
# 3. Set environment variable VAULT_URL with the URL of your key vault
18+
#
19+
# 4. Set up your environment to use azure-identity's DefaultAzureCredential. To authenticate a service principal with
20+
# environment variables, set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID
21+
# (See https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-keys#authenticate-the-client)
22+
#
23+
# 5. Key rotation permissions for your service principal in your vault
24+
#
25+
# ----------------------------------------------------------------------------------------------------------
26+
# Sample - creates and updates a key's automated rotation policy, and rotates a key on-demand
27+
#
28+
# 1. Create a new key rotation policy (update_key_rotation_policy)
29+
#
30+
# 2. Get a key's current rotation policy (get_key_rotation_policy)
31+
#
32+
# 3. Update a key's rotation policy (update_key_rotation_policy)
33+
#
34+
# 4. Rotate a key on-demand (rotate_key)
35+
#
36+
# 5. Delete a key (delete_key)
37+
# ----------------------------------------------------------------------------------------------------------
38+
39+
async def run_sample():
40+
# Instantiate a key client that will be used to call the service.
41+
# Here we use the DefaultAzureCredential, but any azure-identity credential can be used.
42+
VAULT_URL = os.environ["VAULT_URL"]
43+
credential = DefaultAzureCredential()
44+
client = KeyClient(vault_url=VAULT_URL, credential=credential)
45+
46+
# First, create a key
47+
key_name = "rotation-sample-key"
48+
key = await client.create_rsa_key(key_name)
49+
print("\nCreated a key; new version is {}".format(key.properties.version))
50+
51+
# Set the key's automated rotation policy to rotate the key two months after the key was created
52+
actions = [KeyRotationLifetimeAction(KeyRotationPolicyAction.ROTATE, time_after_create="P2M")]
53+
updated_policy = await client.update_key_rotation_policy(key_name, lifetime_actions=actions)
54+
55+
# The created policy should only have one action
56+
assert len(updated_policy.lifetime_actions) == 1, "There should be exactly one rotation policy action"
57+
policy_action = updated_policy.lifetime_actions[0]
58+
print(
59+
"\nCreated a new key rotation policy: {} after {}".format(policy_action.action, policy_action.time_after_create)
60+
)
61+
62+
# Get the key's current rotation policy
63+
current_policy = await client.get_key_rotation_policy(key_name)
64+
policy_action = current_policy.lifetime_actions[0]
65+
print("\nCurrent rotation policy: {} after {}".format(policy_action.action, policy_action.time_after_create))
66+
67+
# Update the key's automated rotation policy to notify 30 days before the key expires
68+
new_actions = [KeyRotationLifetimeAction(KeyRotationPolicyAction.NOTIFY, time_before_expiry="P30D")]
69+
# You may also specify the duration after which the newly rotated key will expire
70+
# In this example, any new key versions will expire after 90 days
71+
new_policy = await client.update_key_rotation_policy(key_name, expires_in="P90D", lifetime_actions=new_actions)
72+
73+
# The updated policy should only have one action
74+
assert len(new_policy.lifetime_actions) == 1, "There should be exactly one rotation policy action"
75+
policy_action = new_policy.lifetime_actions[0]
76+
print(
77+
"\nUpdated rotation policy: {} {} before expiry".format(policy_action.action, policy_action.time_before_expiry)
78+
)
79+
80+
# Finally, you can rotate a key on-demand by creating a new version of the key
81+
rotated_key = await client.rotate_key(key_name)
82+
print("\nRotated the key on-demand; new version is {}".format(rotated_key.properties.version))
83+
84+
# To clean up, delete the key
85+
await client.delete_key(key_name)
86+
print("\nDeleted the key")
87+
88+
await credential.close()
89+
await client.close()
90+
91+
92+
if __name__ == "__main__":
93+
loop = asyncio.get_event_loop()
94+
loop.run_until_complete(run_sample())
95+
loop.close()

0 commit comments

Comments
 (0)