Skip to content

Commit 1e8a307

Browse files
ncamillucciNicola Camillucci
andauthored
[Key Vault] Added API 2026-01-01-preview with EkmClient and EkmConnection (#46895)
* Autogenerated Administration SDK * Started implementation of EKM * Added samples and tests * Fixed CI issues * Updated changelog and cspell * Applied suggestions from code review --------- Co-authored-by: Nicola Camillucci <ncamillucci@microsoft.com>
1 parent df9589b commit 1e8a307

38 files changed

Lines changed: 2800 additions & 127 deletions

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
# Release History
22

3-
## 4.7.1 (Unreleased)
3+
## 4.8.0b1 (2026-05-29)
44

55
### Features Added
66

7-
### Breaking Changes
8-
9-
### Bugs Fixed
7+
- Added support for service API version `2026-01-01-preview` [#46895](https://github.com/Azure/azure-sdk-for-python/pull/46895)
8+
- Added `KeyVaultEkmClient` for managing Managed HSM External Key Manager (EKM) connections. This new client exposes `get_ekm_connection`,
9+
`create_ekm_connection`, `update_ekm_connection`, `delete_ekm_connection`, `get_ekm_certificate`, and `check_ekm_connection`.
10+
- Added `KeyVaultEkmConnection`, `KeyVaultEkmProxyClientCertificateInfo`, and `KeyVaultEkmProxyInfo` models supporting the EKM client.
1011

1112
### Other Changes
1213

13-
## 4.7.0 (2026-05-18)
14+
- Python 3.9 is no longer supported. Please use Python version 3.10 or later.
15+
- Key Vault API version `2026-01-01-preview` is now the default.
16+
17+
## 4.7.0 (2026-05-19)
1418

1519
### Features Added
1620

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ authentication as demonstrated below.
4242
* An existing [Key Vault Managed HSM][managed_hsm]. If you need to create one, you can do so using the Azure CLI by following the steps in [this document][managed_hsm_cli].
4343

4444
### Authenticate the client
45-
In order to interact with the Azure Key Vault service, you will need an instance of either a [KeyVaultAccessControlClient](#create-a-keyvaultaccesscontrolclient) or [KeyVaultBackupClient](#create-a-keyvaultbackupclient), as well as a **vault url** (which you may see as "DNS Name" in the Azure Portal) and a credential object. This document demonstrates using a [DefaultAzureCredential][default_cred_ref], which is appropriate for most scenarios, including local development and production environments. We recommend using a [managed identity][managed_identity] for authentication in production environments.
45+
In order to interact with the Azure Key Vault service, you will need an instance of either a [KeyVaultAccessControlClient](#create-a-keyvaultaccesscontrolclient), [KeyVaultBackupClient](#create-a-keyvaultbackupclient), [KeyVaultSettingsClient](#create-a-keyvaultsettingsclient), or [KeyVaultEkmClient](#create-a-keyvaultekmclient) as well as a **vault url** (which you may see as "DNS Name" in the Azure Portal) and a credential object. This document demonstrates using a [DefaultAzureCredential][default_cred_ref], which is appropriate for most scenarios, including local development and production environments. We recommend using a [managed identity][managed_identity] for authentication in production environments.
4646

4747
See [azure-identity][azure_identity] documentation for more information about other methods of authentication and their corresponding credential types.
4848

@@ -109,6 +109,24 @@ client = KeyVaultSettingsClient(vault_url=MANAGED_HSM_URL, credential=credential
109109

110110
> **NOTE:** For an asynchronous client, import `azure.keyvault.administration.aio`'s `KeyVaultSettingsClient` instead.
111111
112+
#### Create a KeyVaultEkmClient
113+
After configuring your environment for the [DefaultAzureCredential][default_cred_ref] to use a suitable method of authentication, you can do the following to create an EKM client (replacing the value of `vault_url` with your Managed HSM's URL):
114+
115+
<!-- SNIPPET:ekm_operations.create_a_ekm_client -->
116+
117+
```python
118+
from azure.identity import DefaultAzureCredential
119+
from azure.keyvault.administration import KeyVaultEkmClient
120+
121+
MANAGED_HSM_URL = os.environ["MANAGED_HSM_URL"]
122+
credential = DefaultAzureCredential()
123+
client = KeyVaultEkmClient(vault_url=MANAGED_HSM_URL, credential=credential)
124+
```
125+
126+
<!-- END SNIPPET -->
127+
128+
> **NOTE:** For an asynchronous client, import `azure.keyvault.administration.aio`'s `KeyVaultEkmClient` instead.
129+
112130
## Key concepts
113131

114132
### Role definition
@@ -141,6 +159,14 @@ A restore operation represents a long-running operation for both a full key and
141159

142160
A `KeyVaultSettingsClient` manages Managed HSM account settings.
143161

162+
### KeyVaultEkmClient
163+
164+
A `KeyVaultEkmClient` manages the Managed HSM's External Key Manager (EKM) connection.
165+
166+
### EKM Connection
167+
168+
An EKM connection represents the connection of an Azure Managed HSM resource with an external HSM.
169+
144170
## Examples
145171
This section contains code snippets covering common tasks:
146172
* Access control
@@ -413,6 +439,7 @@ Several samples are available in the Azure SDK for Python GitHub repository. The
413439
- [Create/update/delete role definitions and role assignments][access_control_operations_sample] ([async version][access_control_operations_async_sample])
414440
- [Full backup and restore][backup_operations_sample] ([async version][backup_operations_async_sample])
415441
- [List and update Key Vault settings][settings_operations_sample] ([async version][settings_operations_async_sample])
442+
- [Retrieve and manage EKM connections][ekm_operations_sample] ([async version][ekm_operations_async_sample])
416443

417444
### Additional documentation
418445
For more extensive documentation on Azure Key Vault, see the [API reference documentation][reference_docs].
@@ -474,6 +501,8 @@ contact opencode@microsoft.com with any additional questions or comments.
474501
[sas_docs]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/storage/azure-storage-blob/README.md#types-of-credentials
475502
[settings_operations_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-administration/samples/settings_operations.py
476503
[settings_operations_async_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-administration/samples/settings_operations_async.py
504+
[ekm_operations_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-administration/samples/ekm_operations.py
505+
[ekm_operations_async_sample]: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-administration/samples/ekm_operations_async.py
477506
[storage_blob]: https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/storage/azure-storage-blob/README.md
478507
[storage_explorer]: https://learn.microsoft.com/azure/vs-azure-tools-storage-manage-with-storage-explorer
479508

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"apiVersion": "2025-07-01",
2+
"apiVersion": "2026-01-01-preview",
33
"apiVersions": {
4-
"KeyVault": "2025-07-01"
4+
"KeyVault": "2026-01-01-preview"
55
}
66
}

sdk/keyvault/azure-keyvault-administration/apiview-properties.json

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
22
"CrossLanguagePackageId": "KeyVault",
33
"CrossLanguageDefinitionId": {
4+
"azure.keyvault.administration._generated.models.EkmConnection": "KeyVault.EkmConnection",
5+
"azure.keyvault.administration._generated.models.EkmProxyClientCertificateInfo": "KeyVault.EkmProxyClientCertificateInfo",
6+
"azure.keyvault.administration._generated.models.EkmProxyInfo": "KeyVault.EkmProxyInfo",
47
"azure.keyvault.administration._generated.models.FullBackupOperation": "KeyVault.FullBackupOperation",
58
"azure.keyvault.administration._generated.models.FullBackupOperationError": "KeyVault.FullBackupOperation.error.anonymous",
69
"azure.keyvault.administration._generated.models.KeyVaultError": "KeyVaultError",
@@ -65,6 +68,19 @@
6568
"azure.keyvault.administration._generated.KeyVaultClient.get_setting": "KeyVault.getSetting",
6669
"azure.keyvault.administration._generated.aio.KeyVaultClient.get_setting": "KeyVault.getSetting",
6770
"azure.keyvault.administration._generated.KeyVaultClient.get_settings": "KeyVault.getSettings",
68-
"azure.keyvault.administration._generated.aio.KeyVaultClient.get_settings": "KeyVault.getSettings"
69-
}
71+
"azure.keyvault.administration._generated.aio.KeyVaultClient.get_settings": "KeyVault.getSettings",
72+
"azure.keyvault.administration._generated.KeyVaultClient.get_ekm_connection": "KeyVault.getEkmConnection",
73+
"azure.keyvault.administration._generated.aio.KeyVaultClient.get_ekm_connection": "KeyVault.getEkmConnection",
74+
"azure.keyvault.administration._generated.KeyVaultClient.get_ekm_certificate": "KeyVault.getEkmCertificate",
75+
"azure.keyvault.administration._generated.aio.KeyVaultClient.get_ekm_certificate": "KeyVault.getEkmCertificate",
76+
"azure.keyvault.administration._generated.KeyVaultClient.check_ekm_connection": "KeyVault.checkEkmConnection",
77+
"azure.keyvault.administration._generated.aio.KeyVaultClient.check_ekm_connection": "KeyVault.checkEkmConnection",
78+
"azure.keyvault.administration._generated.KeyVaultClient.create_ekm_connection": "KeyVault.createEkmConnection",
79+
"azure.keyvault.administration._generated.aio.KeyVaultClient.create_ekm_connection": "KeyVault.createEkmConnection",
80+
"azure.keyvault.administration._generated.KeyVaultClient.update_ekm_connection": "KeyVault.updateEkmConnection",
81+
"azure.keyvault.administration._generated.aio.KeyVaultClient.update_ekm_connection": "KeyVault.updateEkmConnection",
82+
"azure.keyvault.administration._generated.KeyVaultClient.delete_ekm_connection": "KeyVault.deleteEkmConnection",
83+
"azure.keyvault.administration._generated.aio.KeyVaultClient.delete_ekm_connection": "KeyVault.deleteEkmConnection"
84+
},
85+
"CrossLanguageVersion": "a3023239f547"
7086
}

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_007a803c2c"
5+
"Tag": "python/keyvault/azure-keyvault-administration_60fd5d77a0"
66
}

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/__init__.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
# ------------------------------------
55
from ._access_control_client import KeyVaultAccessControlClient
66
from ._backup_client import KeyVaultBackupClient
7-
from ._enums import KeyVaultRoleScope, KeyVaultDataAction, KeyVaultSettingType
7+
from ._ekm_client import KeyVaultEkmClient
8+
from ._enums import KeyVaultDataAction, KeyVaultRoleScope, KeyVaultSettingType
89
from ._internal.client_base import ApiVersion
910
from ._models import (
1011
KeyVaultBackupResult,
12+
KeyVaultEkmConnection,
13+
KeyVaultEkmProxyClientCertificateInfo,
14+
KeyVaultEkmProxyInfo,
1115
KeyVaultPermission,
1216
KeyVaultRoleAssignment,
1317
KeyVaultRoleAssignmentProperties,
@@ -16,13 +20,16 @@
1620
)
1721
from ._settings_client import KeyVaultSettingsClient
1822

19-
2023
__all__ = [
2124
"ApiVersion",
22-
"KeyVaultBackupResult",
2325
"KeyVaultAccessControlClient",
2426
"KeyVaultBackupClient",
27+
"KeyVaultBackupResult",
2528
"KeyVaultDataAction",
29+
"KeyVaultEkmClient",
30+
"KeyVaultEkmConnection",
31+
"KeyVaultEkmProxyClientCertificateInfo",
32+
"KeyVaultEkmProxyInfo",
2633
"KeyVaultPermission",
2734
"KeyVaultRoleAssignment",
2835
"KeyVaultRoleAssignmentProperties",
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# ------------------------------------
2+
# Copyright (c) Microsoft Corporation.
3+
# Licensed under the MIT License.
4+
# ------------------------------------
5+
from typing import Any
6+
7+
from azure.core.tracing.decorator import distributed_trace
8+
9+
from ._internal import KeyVaultClientBase
10+
from ._models import KeyVaultEkmConnection, KeyVaultEkmProxyClientCertificateInfo, KeyVaultEkmProxyInfo
11+
12+
13+
class KeyVaultEkmClient(KeyVaultClientBase):
14+
"""Provides methods to manage Managed HSM External Key Manager (EKM) connections.
15+
16+
:param str vault_url: URL of the vault on which the client will operate. This is also called the vault's "DNS Name".
17+
You should validate that this URL references a valid Key Vault or Managed HSM resource.
18+
See https://aka.ms/azsdk/blog/vault-uri for details.
19+
:param credential: An object which can provide an access token for the vault, such as a credential from
20+
:mod:`azure.identity`
21+
:type credential: ~azure.core.credentials.TokenCredential
22+
23+
:keyword api_version: Version of the service API to use. EKM operations require service API version
24+
``2026-01-01-preview`` or later.
25+
:paramtype api_version: ~azure.keyvault.administration.ApiVersion or str
26+
:keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key
27+
Vault or Managed HSM domain. Defaults to True.
28+
"""
29+
30+
# pylint:disable=protected-access
31+
32+
@distributed_trace
33+
def get_ekm_connection(self, **kwargs: Any) -> KeyVaultEkmConnection:
34+
"""Gets the configured EKM connection.
35+
36+
:returns: The configured EKM connection.
37+
:rtype: ~azure.keyvault.administration.KeyVaultEkmConnection
38+
:raises ~azure.core.exceptions.HttpResponseError:
39+
"""
40+
result = self._client.get_ekm_connection(**kwargs)
41+
return KeyVaultEkmConnection._from_generated(result)
42+
43+
@distributed_trace
44+
def create_ekm_connection(self, connection: KeyVaultEkmConnection, **kwargs: Any) -> KeyVaultEkmConnection:
45+
"""Creates the EKM connection.
46+
47+
If an EKM connection already exists, this operation fails.
48+
49+
:param connection: The EKM connection to create.
50+
:type connection: ~azure.keyvault.administration.KeyVaultEkmConnection
51+
52+
:returns: The created EKM connection.
53+
:rtype: ~azure.keyvault.administration.KeyVaultEkmConnection
54+
:raises ~azure.core.exceptions.HttpResponseError:
55+
"""
56+
result = self._client.create_ekm_connection(ekm_connection=connection._to_generated(), **kwargs)
57+
return KeyVaultEkmConnection._from_generated(result)
58+
59+
@distributed_trace
60+
def update_ekm_connection(self, connection: KeyVaultEkmConnection, **kwargs: Any) -> KeyVaultEkmConnection:
61+
"""Updates the existing EKM connection.
62+
63+
If no EKM connection exists, this operation fails.
64+
65+
:param connection: The EKM connection to update.
66+
:type connection: ~azure.keyvault.administration.KeyVaultEkmConnection
67+
68+
:returns: The updated EKM connection.
69+
:rtype: ~azure.keyvault.administration.KeyVaultEkmConnection
70+
:raises ~azure.core.exceptions.HttpResponseError:
71+
"""
72+
result = self._client.update_ekm_connection(ekm_connection=connection._to_generated(), **kwargs)
73+
return KeyVaultEkmConnection._from_generated(result)
74+
75+
@distributed_trace
76+
def delete_ekm_connection( # pylint:disable=bad-option-value,delete-operation-wrong-return-type
77+
self, **kwargs: Any
78+
) -> KeyVaultEkmConnection:
79+
"""Deletes the existing EKM connection.
80+
81+
If no EKM connection exists, this operation fails.
82+
83+
:returns: The deleted EKM connection.
84+
:rtype: ~azure.keyvault.administration.KeyVaultEkmConnection
85+
:raises ~azure.core.exceptions.HttpResponseError:
86+
"""
87+
result = self._client.delete_ekm_connection(**kwargs)
88+
return KeyVaultEkmConnection._from_generated(result)
89+
90+
@distributed_trace
91+
def get_ekm_certificate(self, **kwargs: Any) -> KeyVaultEkmProxyClientCertificateInfo:
92+
"""Gets the EKM proxy client certificate information used to authenticate to the EKM proxy.
93+
94+
:returns: The EKM proxy client certificate information.
95+
:rtype: ~azure.keyvault.administration.KeyVaultEkmProxyClientCertificateInfo
96+
:raises ~azure.core.exceptions.HttpResponseError:
97+
"""
98+
result = self._client.get_ekm_certificate(**kwargs)
99+
return KeyVaultEkmProxyClientCertificateInfo._from_generated(result)
100+
101+
@distributed_trace
102+
def check_ekm_connection(self, **kwargs: Any) -> KeyVaultEkmProxyInfo:
103+
"""Checks the EKM connection by pinging the EKM proxy.
104+
105+
:returns: Information about the EKM proxy returned by the connectivity check.
106+
:rtype: ~azure.keyvault.administration.KeyVaultEkmProxyInfo
107+
:raises ~azure.core.exceptions.HttpResponseError:
108+
"""
109+
result = self._client.check_ekm_connection(**kwargs)
110+
return KeyVaultEkmProxyInfo._from_generated(result)
111+
112+
def __enter__(self) -> "KeyVaultEkmClient":
113+
self._client.__enter__()
114+
return self

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_client.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
# --------------------------------------------------------------------------
88

99
from copy import deepcopy
10+
import sys
1011
from typing import Any, TYPE_CHECKING
11-
from typing_extensions import Self
1212

1313
from azure.core import PipelineClient
1414
from azure.core.pipeline import policies
@@ -18,6 +18,11 @@
1818
from ._utils.serialization import Deserializer, Serializer
1919
from .operations import RoleAssignmentsOperations, RoleDefinitionsOperations, _KeyVaultClientOperationsMixin
2020

21+
if sys.version_info >= (3, 11):
22+
from typing import Self
23+
else:
24+
from typing_extensions import Self # type: ignore
25+
2126
if TYPE_CHECKING:
2227
from azure.core.credentials import TokenCredential
2328

@@ -37,9 +42,10 @@ class KeyVaultClient(_KeyVaultClientOperationsMixin):
3742
:type vault_base_url: str
3843
:param credential: Credential used to authenticate requests to the service. Required.
3944
:type credential: ~azure.core.credentials.TokenCredential
40-
:keyword api_version: The API version to use for this operation. Known values are "2025-07-01".
41-
Default value is "2025-07-01". Note that overriding this default value may result in
42-
unsupported behavior.
45+
:keyword api_version: The API version to use for this operation. Known values are
46+
"2026-01-01-preview" and None. Default value is None. If not set, the operation's default API
47+
version will be used. Note that overriding this default value may result in unsupported
48+
behavior.
4349
:paramtype api_version: str
4450
:keyword int polling_interval: Default waiting time between two polls for LRO operations if no
4551
Retry-After header is present.

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_configuration.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@ class KeyVaultClientConfiguration: # pylint: disable=too-many-instance-attribut
2727
:type vault_base_url: str
2828
:param credential: Credential used to authenticate requests to the service. Required.
2929
:type credential: ~azure.core.credentials.TokenCredential
30-
:keyword api_version: The API version to use for this operation. Known values are "2025-07-01".
31-
Default value is "2025-07-01". Note that overriding this default value may result in
32-
unsupported behavior.
30+
:keyword api_version: The API version to use for this operation. Known values are
31+
"2026-01-01-preview" and None. Default value is None. If not set, the operation's default API
32+
version will be used. Note that overriding this default value may result in unsupported
33+
behavior.
3334
:paramtype api_version: str
3435
"""
3536

3637
def __init__(self, vault_base_url: str, credential: "TokenCredential", **kwargs: Any) -> None:
37-
api_version: str = kwargs.pop("api_version", "2025-07-01")
38+
api_version: str = kwargs.pop("api_version", "2026-01-01-preview")
3839

3940
if vault_base_url is None:
4041
raise ValueError("Parameter 'vault_base_url' must not be None.")

sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_patch.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
88
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
99
"""
10+
1011
from typing import List
1112

1213
__all__: List[str] = [] # Add all objects you want publicly available to users at this package level

0 commit comments

Comments
 (0)