Skip to content

Commit 9dc6cc8

Browse files
authored
[Key Vault] Update tests to only record with Managed Identity (#35859)
1 parent b50ee9e commit 9dc6cc8

10 files changed

+207
-191
lines changed

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

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,30 @@ client = KeyVaultAccessControlClient(vault_url=MANAGED_HSM_URL, credential=crede
6565
> **NOTE:** For an asynchronous client, import `azure.keyvault.administration.aio`'s `KeyVaultAccessControlClient` instead.
6666
6767
#### Create a KeyVaultBackupClient
68-
After configuring your environment for the [DefaultAzureCredential][default_cred_ref] to use a suitable method of authentication, you can do the following to create a backup client (replacing the value of `vault_url` with your Managed HSM's URL):
68+
After creating a user-assigned [managed identity][managed_identity] and
69+
[granting it access to your Managed HSM][managed_identity_backup_setup], you can do the following to create a backup
70+
client (setting the value of `CLIENT_ID` to your managed identity's client ID):
6971

7072
<!-- SNIPPET:backup_restore_operations.create_a_backup_restore_client -->
7173

7274
```python
73-
from azure.identity import DefaultAzureCredential
75+
from azure.identity import ManagedIdentityCredential
7476
from azure.keyvault.administration import KeyVaultBackupClient
7577

7678
MANAGED_HSM_URL = os.environ["MANAGED_HSM_URL"]
77-
credential = DefaultAzureCredential()
79+
MANAGED_IDENTITY_CLIENT_ID = os.environ["CLIENT_ID"]
80+
credential = ManagedIdentityCredential(client_id=MANAGED_IDENTITY_CLIENT_ID)
7881
client = KeyVaultBackupClient(vault_url=MANAGED_HSM_URL, credential=credential)
7982
```
8083

8184
<!-- END SNIPPET -->
8285

86+
Using the `ManagedIdentityCredential` is preferred in order to enable authenticating backup and restore operations with
87+
Managed Identity. Any other `azure-identity` credential could be provided instead if SAS tokens are used in these
88+
operations.
89+
90+
See [azure-identity][managed_identity_ref] documentation for more information on Managed Identity authentication.
91+
8392
> **NOTE:** For an asynchronous client, import `azure.keyvault.administration.aio`'s `KeyVaultBackupClient` instead.
8493
8594
#### Create a KeyVaultSettingsClient
@@ -265,7 +274,11 @@ client.delete_role_assignment(scope=scope, name=role_assignment.name)
265274

266275
### Perform a full key backup
267276
The `KeyVaultBackupClient` can be used to back up your entire collection of keys. The backing store for full key
268-
backups is a blob storage container using Shared Access Signature (SAS) authentication.
277+
backups is a blob storage container using either Managed Identity (which is preferred) or Shared Access Signature (SAS)
278+
authentication.
279+
280+
If using Managed Identity, first make sure your user-assigned managed identity has the correct access to your Storage
281+
account and Managed HSM per [the service's guidance][managed_identity_backup_setup].
269282

270283
For more details on creating a SAS token using a `BlobServiceClient` from [`azure-storage-blob`][storage_blob], refer
271284
to the library's [credential documentation][sas_docs]. Alternatively, it is possible to
@@ -275,9 +288,8 @@ to the library's [credential documentation][sas_docs]. Alternatively, it is poss
275288

276289
```python
277290
CONTAINER_URL = os.environ["CONTAINER_URL"]
278-
SAS_TOKEN = os.environ["SAS_TOKEN"]
279291

280-
backup_result: KeyVaultBackupResult = client.begin_backup(CONTAINER_URL, sas_token=SAS_TOKEN).result()
292+
backup_result: KeyVaultBackupResult = client.begin_backup(CONTAINER_URL, use_managed_identity=True).result()
281293
print(f"Azure Storage Blob URL of the backup: {backup_result.folder_url}")
282294
```
283295

@@ -289,8 +301,12 @@ the operation is complete without returning an object.
289301

290302
### Perform a full key restore
291303
The `KeyVaultBackupClient` can be used to restore your entire collection of keys from a backup. The data source for a
292-
full key restore is a storage blob accessed using Shared Access Signature authentication. You will also need the URL of
293-
the backup (`KeyVaultBackupResult.folder_url`) from the [above snippet](#perform-a-full-key-backup).
304+
full key restore is a storage blob accessed using either Managed Identity (which is preferred) or Shared Access
305+
Signature (SAS) authentication. You will also need the URL of the backup (`KeyVaultBackupResult.folder_url`) from the
306+
[above snippet](#perform-a-full-key-backup).
307+
308+
If using Managed Identity, first make sure your user-assigned managed identity has the correct access to your Storage
309+
account and Managed HSM per [the service's guidance][managed_identity_backup_setup].
294310

295311
For more details on creating a SAS token using a `BlobServiceClient` from [`azure-storage-blob`][storage_blob], refer
296312
to the library's [credential documentation][sas_docs]. Alternatively, it is possible to
@@ -299,10 +315,8 @@ to the library's [credential documentation][sas_docs]. Alternatively, it is poss
299315
<!-- SNIPPET:backup_restore_operations.begin_restore -->
300316

301317
```python
302-
SAS_TOKEN = os.environ["SAS_TOKEN"]
303-
304318
# `backup_result` is the KeyVaultBackupResult returned by `begin_backup`
305-
client.begin_restore(backup_result.folder_url, sas_token=SAS_TOKEN).wait()
319+
client.begin_restore(backup_result.folder_url, use_managed_identity=True).wait()
306320
print("Vault restored successfully.")
307321
```
308322

@@ -398,7 +412,9 @@ contact [email protected] with any additional questions or comments.
398412

399413
[managed_hsm]: https://docs.microsoft.com/azure/key-vault/managed-hsm/overview
400414
[managed_hsm_cli]: https://docs.microsoft.com/azure/key-vault/managed-hsm/quick-create-cli
401-
[managed_identity]: https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview
415+
[managed_identity]: https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview
416+
[managed_identity_backup_setup]: https://learn.microsoft.com/azure/key-vault/managed-hsm/backup-restore#prerequisites-if-backing-up-and-restoring-using-user-assigned-managed-identity
417+
[managed_identity_ref]: https://aka.ms/azsdk/python/identity/docs#azure.identity.ManagedIdentityCredential
402418

403419
[pip]: https://pypi.org/project/pip/
404420
[pypi_package_administration]: https://pypi.org/project/azure-keyvault-administration

sdk/keyvault/azure-keyvault-administration/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "python",
44
"TagPrefix": "python/keyvault/azure-keyvault-administration",
5-
"Tag": "python/keyvault/azure-keyvault-administration_3353e6edf1"
5+
"Tag": "python/keyvault/azure-keyvault-administration_df93633a52"
66
}

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@
1313
# 2. azure-keyvault-administration and azure-identity libraries (pip install these)
1414
#
1515
# 3. Set environment variable MANAGED_HSM_URL with the URL of your managed HSM
16-
#
17-
# 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure
18-
# the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential
1916
#
20-
# 5. A storage account containing a blob storage container
17+
# 4. A user-assigned managed identity that has access to your managed HSM. For more information about how to create a
18+
# user-assigned managed identity, refer to
19+
# https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview
20+
#
21+
# 5. A storage account, that your managed identity has access to, containing a blob storage container
2122
# (See https://docs.microsoft.com/azure/storage/blobs/storage-blobs-introduction)
2223
#
23-
# 6. Set environment variables CONTAINER_URL and SAS_TOKEN corresponding to your blob container's URI and SAS
24-
# (See https://docs.microsoft.com/azure/storage/common/storage-sas-overview)
24+
# 6. Set environment variables CONTAINER_URL and CLIENT_ID, corresponding to your blob container's URI and your
25+
# user-assigned managed identity's client ID, respectively.
2526
#
2627
# For more details, see https://docs.microsoft.com/azure/key-vault/managed-hsm/backup-restore
2728
#
@@ -34,13 +35,15 @@
3435
# ----------------------------------------------------------------------------------------------------------
3536

3637
# Instantiate a backup client that will be used to call the service.
37-
# Here we use the DefaultAzureCredential, but any azure-identity credential can be used.
38+
# Here we use the ManagedIdentityCredential to use Managed Identity, but any azure-identity credential can be used if
39+
# opting for SAS token authentication.
3840
# [START create_a_backup_restore_client]
39-
from azure.identity import DefaultAzureCredential
41+
from azure.identity import ManagedIdentityCredential
4042
from azure.keyvault.administration import KeyVaultBackupClient
4143

4244
MANAGED_HSM_URL = os.environ["MANAGED_HSM_URL"]
43-
credential = DefaultAzureCredential()
45+
MANAGED_IDENTITY_CLIENT_ID = os.environ["CLIENT_ID"]
46+
credential = ManagedIdentityCredential(client_id=MANAGED_IDENTITY_CLIENT_ID)
4447
client = KeyVaultBackupClient(vault_url=MANAGED_HSM_URL, credential=credential)
4548
# [END create_a_backup_restore_client]
4649

@@ -50,9 +53,8 @@
5053
print("\n.. Back up the vault")
5154
# [START begin_backup]
5255
CONTAINER_URL = os.environ["CONTAINER_URL"]
53-
SAS_TOKEN = os.environ["SAS_TOKEN"]
5456

55-
backup_result: KeyVaultBackupResult = client.begin_backup(CONTAINER_URL, sas_token=SAS_TOKEN).result()
57+
backup_result: KeyVaultBackupResult = client.begin_backup(CONTAINER_URL, use_managed_identity=True).result()
5658
print(f"Azure Storage Blob URL of the backup: {backup_result.folder_url}")
5759
# [END begin_backup]
5860
print("Vault backed up successfully.")
@@ -63,9 +65,7 @@
6365
# To restore a single key from the backed up vault instead, pass the key_name keyword argument.
6466
print("\n.. Restore the full vault")
6567
# [START begin_restore]
66-
SAS_TOKEN = os.environ["SAS_TOKEN"]
67-
6868
# `backup_result` is the KeyVaultBackupResult returned by `begin_backup`
69-
client.begin_restore(backup_result.folder_url, sas_token=SAS_TOKEN).wait()
69+
client.begin_restore(backup_result.folder_url, use_managed_identity=True).wait()
7070
print("Vault restored successfully.")
7171
# [END begin_restore]

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import os
77

88
from azure.keyvault.administration.aio import KeyVaultBackupClient
9-
from azure.identity.aio import DefaultAzureCredential
9+
from azure.identity.aio import ManagedIdentityCredential
1010

1111
# ----------------------------------------------------------------------------------------------------------
1212
# Prerequisites:
@@ -15,15 +15,16 @@
1515
# 2. azure-keyvault-administration and azure-identity libraries (pip install these)
1616
#
1717
# 3. Set environment variable MANAGED_HSM_URL with the URL of your managed HSM
18-
#
19-
# 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure
20-
# the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential
2118
#
22-
# 5. A storage account containing a blob storage container
19+
# 4. A user-assigned managed identity that has access to your managed HSM. For more information about how to create a
20+
# user-assigned managed identity, refer to
21+
# https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview
22+
#
23+
# 5. A storage account, that your managed identity has access to, containing a blob storage container
2324
# (See https://docs.microsoft.com/azure/storage/blobs/storage-blobs-introduction)
2425
#
25-
# 6. Set environment variables CONTAINER_URL and SAS_TOKEN corresponding to your blob container's URI and SAS
26-
# (See https://docs.microsoft.com/azure/storage/common/storage-sas-overview)
26+
# 6. Set environment variables CONTAINER_URL and CLIENT_ID, corresponding to your blob container's URI and your
27+
# user-assigned managed identity's client ID, respectively.
2728
#
2829
# For more details, see https://docs.microsoft.com/azure/key-vault/managed-hsm/backup-restore
2930
#
@@ -38,18 +39,18 @@
3839
async def run_sample():
3940
MANAGED_HSM_URL = os.environ["MANAGED_HSM_URL"]
4041
CONTAINER_URL = os.environ["CONTAINER_URL"]
41-
SAS_TOKEN = os.environ["SAS_TOKEN"]
42+
MANAGED_IDENTITY_CLIENT_ID = os.environ["CLIENT_ID"]
4243

4344
# Instantiate a backup client that will be used to call the service.
4445
# Here we use the DefaultAzureCredential, but any azure-identity credential can be used.
45-
credential = DefaultAzureCredential()
46+
credential = ManagedIdentityCredential(client_id=MANAGED_IDENTITY_CLIENT_ID)
4647
client = KeyVaultBackupClient(vault_url=MANAGED_HSM_URL, credential=credential)
4748

4849
# Let's back up the vault with begin_backup, which returns a poller. Calling result() on the poller will return
4950
# a KeyVaultBackupResult that contains the URL of the backup after the operation completes. Calling wait() on
5051
# the poller will wait until the operation is complete.
5152
print("\n.. Back up the vault")
52-
backup_poller = await client.begin_backup(CONTAINER_URL, sas_token=SAS_TOKEN)
53+
backup_poller = await client.begin_backup(CONTAINER_URL, use_managed_identity=True)
5354
backup_result = await backup_poller.result()
5455
print("Vault backed up successfully.")
5556
assert backup_result.folder_url
@@ -58,7 +59,7 @@ async def run_sample():
5859
# return None after the operation completes. Calling wait() on the poller will wait until the operation is
5960
# complete. To restore a single key from the backed up vault instead, pass the key_name keyword argument.
6061
print("\n.. Restore the full vault")
61-
restore_poller = await client.begin_restore(backup_result.folder_url, sas_token=SAS_TOKEN)
62+
restore_poller = await client.begin_restore(backup_result.folder_url, use_managed_identity=True)
6263
await restore_poller.wait()
6364
print("Vault restored successfully.")
6465

sdk/keyvault/azure-keyvault-administration/tests/_async_test_case.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import pytest
88
from azure.keyvault.administration import ApiVersion
99
from azure.keyvault.administration._internal.client_base import DEFAULT_VERSION
10+
from azure.identity.aio import ManagedIdentityCredential
1011
from devtools_testutils import AzureRecordedTestCase
1112

1213

@@ -30,6 +31,7 @@ def __init__(self, **kwargs) -> None:
3031
self.container_uri = container_playback_uri
3132
self.sas_token = playback_sas_token
3233

34+
self.managed_identity_client_id = os.environ.get("MANAGED_IDENTITY_CLIENT_ID")
3335
use_pwsh = os.environ.get("AZURE_TEST_USE_PWSH_AUTH", "false")
3436
use_cli = os.environ.get("AZURE_TEST_USE_CLI_AUTH", "false")
3537
use_vscode = os.environ.get("AZURE_TEST_USE_VSCODE_AUTH", "false")
@@ -52,6 +54,30 @@ def _set_mgmt_settings_real_values(self):
5254

5355

5456
class KeyVaultBackupClientPreparer(BaseClientPreparer):
57+
def __call__(self, fn):
58+
async def _preparer(test_class, api_version, **kwargs):
59+
self._skip_if_not_configured(api_version)
60+
kwargs["container_uri"] = self.container_uri
61+
kwargs["managed_hsm_url"] = self.managed_hsm_url
62+
client = self.create_backup_client(self.managed_identity_client_id, api_version=api_version, **kwargs)
63+
64+
async with client:
65+
await fn(test_class, client, **kwargs)
66+
return _preparer
67+
68+
def create_backup_client(self, managed_identity_client_id, **kwargs):
69+
from azure.keyvault.administration.aio import KeyVaultBackupClient
70+
71+
if self.is_live:
72+
credential = ManagedIdentityCredential(client_id=managed_identity_client_id)
73+
else:
74+
credential = self.get_credential(KeyVaultBackupClient, is_async=True)
75+
return self.create_client_from_credential(
76+
KeyVaultBackupClient, credential=credential, vault_url=self.managed_hsm_url, **kwargs
77+
)
78+
79+
80+
class KeyVaultBackupClientSasPreparer(BaseClientPreparer):
5581
def __call__(self, fn):
5682
async def _preparer(test_class, api_version, **kwargs):
5783
self._skip_if_not_configured(api_version)

sdk/keyvault/azure-keyvault-administration/tests/_test_case.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from azure.keyvault.administration import ApiVersion
1010
from azure.keyvault.administration._internal.client_base import DEFAULT_VERSION
11+
from azure.identity import ManagedIdentityCredential
1112
from devtools_testutils import AzureRecordedTestCase
1213

1314

@@ -31,6 +32,7 @@ def __init__(self, **kwargs) -> None:
3132
self.container_uri = container_playback_uri
3233
self.sas_token = playback_sas_token
3334

35+
self.managed_identity_client_id = os.environ.get("MANAGED_IDENTITY_CLIENT_ID")
3436
use_pwsh = os.environ.get("AZURE_TEST_USE_PWSH_AUTH", "false")
3537
use_cli = os.environ.get("AZURE_TEST_USE_CLI_AUTH", "false")
3638
use_vscode = os.environ.get("AZURE_TEST_USE_VSCODE_AUTH", "false")
@@ -56,6 +58,33 @@ class KeyVaultBackupClientPreparer(BaseClientPreparer):
5658
def __init__(self, **kwargs) -> None:
5759
super().__init__(**kwargs)
5860

61+
def __call__(self, fn):
62+
def _preparer(test_class, api_version, **kwargs):
63+
self._skip_if_not_configured(api_version)
64+
kwargs["container_uri"] = self.container_uri
65+
kwargs["managed_hsm_url"] = self.managed_hsm_url
66+
client = self.create_backup_client(self.managed_identity_client_id, api_version=api_version, **kwargs)
67+
68+
with client:
69+
fn(test_class, client, **kwargs)
70+
return _preparer
71+
72+
def create_backup_client(self, managed_identity_client_id, **kwargs):
73+
from azure.keyvault.administration import KeyVaultBackupClient
74+
75+
if self.is_live:
76+
credential = ManagedIdentityCredential(client_id=managed_identity_client_id)
77+
else:
78+
credential = self.get_credential(KeyVaultBackupClient)
79+
return self.create_client_from_credential(
80+
KeyVaultBackupClient, credential=credential, vault_url=self.managed_hsm_url, **kwargs
81+
)
82+
83+
84+
class KeyVaultBackupClientSasPreparer(BaseClientPreparer):
85+
def __init__(self, **kwargs) -> None:
86+
super().__init__(**kwargs)
87+
5988
def __call__(self, fn):
6089
def _preparer(test_class, api_version, **kwargs):
6190
self._skip_if_not_configured(api_version)

0 commit comments

Comments
 (0)