Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions sdk/keyvault/azure-keyvault-administration/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
### Features Added

- Added support for service API version `2025-07-01` [#46716](https://github.com/Azure/azure-sdk-for-python/pull/46716)
- Added `KeyVaultEkmClient` (sync and async) for managing Managed HSM External Key Manager
(EKM) connections via the `2026-01-01-preview` API. The new client exposes
`get_ekm_connection`, `create_ekm_connection`, `update_ekm_connection`,
`delete_ekm_connection`, `get_ekm_certificate`, and `check_ekm_connection`.
- Added `KeyVaultEkmConnection`, `KeyVaultEkmProxyClientCertificateInfo`, and
`KeyVaultEkmProxyInfo` models supporting the EKM client.

### Breaking Changes

Expand Down
34 changes: 32 additions & 2 deletions sdk/keyvault/azure-keyvault-administration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ authentication as demonstrated below.
* 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].

### Authenticate the client
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.
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.

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

Expand Down Expand Up @@ -109,6 +109,24 @@ client = KeyVaultSettingsClient(vault_url=MANAGED_HSM_URL, credential=credential

> **NOTE:** For an asynchronous client, import `azure.keyvault.administration.aio`'s `KeyVaultSettingsClient` instead.

#### Create a KeyVaultEkmClient
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):

<!-- SNIPPET:ekm_operations.create_a_ekm_client -->

```python
from azure.identity import DefaultAzureCredential
from azure.keyvault.administration import KeyVaultEkmClient

MANAGED_HSM_URL = os.environ["MANAGED_HSM_URL"]
credential = DefaultAzureCredential()
client = KeyVaultEkmClient(vault_url=MANAGED_HSM_URL, credential=credential)
```

<!-- END SNIPPET -->

> **NOTE:** For an asynchronous client, import `azure.keyvault.administration.aio`'s `KeyVaultEkmClient` instead.

## Key concepts

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

A `KeyVaultSettingsClient` manages Managed HSM account settings.

### KeyVaultEkmClient

A `KeyVaultEkmClient` manages the Managed HSM's External Key Manager (EKM) connection.

### EKM Connection

An EKM connection represents the connection of an Azure Managed HSM resource with an external HSM.

## Examples
This section contains code snippets covering common tasks:
* Access control
Expand Down Expand Up @@ -193,7 +219,8 @@ role_definition = client.set_role_definition(scope=scope, role_name=role_name, p
```python
new_permissions = [
KeyVaultPermission(
data_actions=[KeyVaultDataAction.READ_HSM_KEY], not_data_actions=[KeyVaultDataAction.CREATE_HSM_KEY]
data_actions=[KeyVaultDataAction.READ_HSM_KEY],
not_data_actions=[KeyVaultDataAction.CREATE_HSM_KEY]
)
]
unique_definition_name = role_definition.name
Expand Down Expand Up @@ -413,6 +440,7 @@ Several samples are available in the Azure SDK for Python GitHub repository. The
- [Create/update/delete role definitions and role assignments][access_control_operations_sample] ([async version][access_control_operations_async_sample])
- [Full backup and restore][backup_operations_sample] ([async version][backup_operations_async_sample])
- [List and update Key Vault settings][settings_operations_sample] ([async version][settings_operations_async_sample])
- [Retrieve and manage EKM connections][ekm_operations_sample] ([async version][ekm_operations_async_sample])

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

Expand Down
4 changes: 2 additions & 2 deletions sdk/keyvault/azure-keyvault-administration/_metadata.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"apiVersion": "2025-07-01",
"apiVersion": "2026-01-01-preview",
"apiVersions": {
"KeyVault": "2025-07-01"
"KeyVault": "2026-01-01-preview"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"CrossLanguagePackageId": "KeyVault",
"CrossLanguageDefinitionId": {
"azure.keyvault.administration._generated.models.EkmConnection": "KeyVault.EkmConnection",
"azure.keyvault.administration._generated.models.EkmProxyClientCertificateInfo": "KeyVault.EkmProxyClientCertificateInfo",
"azure.keyvault.administration._generated.models.EkmProxyInfo": "KeyVault.EkmProxyInfo",
"azure.keyvault.administration._generated.models.FullBackupOperation": "KeyVault.FullBackupOperation",
"azure.keyvault.administration._generated.models.FullBackupOperationError": "KeyVault.FullBackupOperation.error.anonymous",
"azure.keyvault.administration._generated.models.KeyVaultError": "KeyVaultError",
Expand Down Expand Up @@ -65,6 +68,18 @@
"azure.keyvault.administration._generated.KeyVaultClient.get_setting": "KeyVault.getSetting",
"azure.keyvault.administration._generated.aio.KeyVaultClient.get_setting": "KeyVault.getSetting",
"azure.keyvault.administration._generated.KeyVaultClient.get_settings": "KeyVault.getSettings",
"azure.keyvault.administration._generated.aio.KeyVaultClient.get_settings": "KeyVault.getSettings"
"azure.keyvault.administration._generated.aio.KeyVaultClient.get_settings": "KeyVault.getSettings",
"azure.keyvault.administration._generated.KeyVaultClient.get_ekm_connection": "KeyVault.getEkmConnection",
"azure.keyvault.administration._generated.aio.KeyVaultClient.get_ekm_connection": "KeyVault.getEkmConnection",
"azure.keyvault.administration._generated.KeyVaultClient.get_ekm_certificate": "KeyVault.getEkmCertificate",
"azure.keyvault.administration._generated.aio.KeyVaultClient.get_ekm_certificate": "KeyVault.getEkmCertificate",
"azure.keyvault.administration._generated.KeyVaultClient.check_ekm_connection": "KeyVault.checkEkmConnection",
"azure.keyvault.administration._generated.aio.KeyVaultClient.check_ekm_connection": "KeyVault.checkEkmConnection",
"azure.keyvault.administration._generated.KeyVaultClient.create_ekm_connection": "KeyVault.createEkmConnection",
"azure.keyvault.administration._generated.aio.KeyVaultClient.create_ekm_connection": "KeyVault.createEkmConnection",
"azure.keyvault.administration._generated.KeyVaultClient.update_ekm_connection": "KeyVault.updateEkmConnection",
"azure.keyvault.administration._generated.aio.KeyVaultClient.update_ekm_connection": "KeyVault.updateEkmConnection",
"azure.keyvault.administration._generated.KeyVaultClient.delete_ekm_connection": "KeyVault.deleteEkmConnection",
"azure.keyvault.administration._generated.aio.KeyVaultClient.delete_ekm_connection": "KeyVault.deleteEkmConnection"
}
}
2 changes: 1 addition & 1 deletion sdk/keyvault/azure-keyvault-administration/assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "python",
"TagPrefix": "python/keyvault/azure-keyvault-administration",
"Tag": "python/keyvault/azure-keyvault-administration_007a803c2c"
"Tag": "python/keyvault/azure-keyvault-administration_a1cfcc06db"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
# ------------------------------------
from ._access_control_client import KeyVaultAccessControlClient
from ._backup_client import KeyVaultBackupClient
from ._enums import KeyVaultRoleScope, KeyVaultDataAction, KeyVaultSettingType
from ._ekm_client import KeyVaultEkmClient
from ._enums import KeyVaultDataAction, KeyVaultRoleScope, KeyVaultSettingType
from ._internal.client_base import ApiVersion
from ._models import (
KeyVaultBackupResult,
KeyVaultEkmConnection,
KeyVaultEkmProxyClientCertificateInfo,
KeyVaultEkmProxyInfo,
KeyVaultPermission,
KeyVaultRoleAssignment,
KeyVaultRoleAssignmentProperties,
Expand All @@ -16,13 +20,16 @@
)
from ._settings_client import KeyVaultSettingsClient


__all__ = [
"ApiVersion",
"KeyVaultBackupResult",
"KeyVaultAccessControlClient",
"KeyVaultBackupClient",
"KeyVaultBackupResult",
"KeyVaultDataAction",
"KeyVaultEkmClient",
"KeyVaultEkmConnection",
"KeyVaultEkmProxyClientCertificateInfo",
"KeyVaultEkmProxyInfo",
"KeyVaultPermission",
"KeyVaultRoleAssignment",
"KeyVaultRoleAssignmentProperties",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# ------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# ------------------------------------
from typing import Any

from azure.core.tracing.decorator import distributed_trace

from ._internal import KeyVaultClientBase
from ._models import KeyVaultEkmConnection, KeyVaultEkmProxyClientCertificateInfo, KeyVaultEkmProxyInfo


class KeyVaultEkmClient(KeyVaultClientBase):
"""Provides methods to manage Managed HSM External Key Manager (EKM) connections.

:param str vault_url: URL of the vault on which the client will operate. This is also called the vault's "DNS Name".
You should validate that this URL references a valid Key Vault or Managed HSM resource.
See https://aka.ms/azsdk/blog/vault-uri for details.
:param credential: An object which can provide an access token for the vault, such as a credential from
:mod:`azure.identity`
:type credential: ~azure.core.credentials.TokenCredential

:keyword api_version: Version of the service API to use. EKM operations require service API version
``2026-01-01-preview`` or later.
:paramtype api_version: ~azure.keyvault.administration.ApiVersion or str
:keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key
Vault or Managed HSM domain. Defaults to True.
"""

# pylint:disable=protected-access

@distributed_trace
def get_ekm_connection(self, **kwargs: Any) -> KeyVaultEkmConnection:
"""Gets the configured EKM connection.

:returns: The configured EKM connection.
:rtype: ~azure.keyvault.administration.KeyVaultEkmConnection
:raises ~azure.core.exceptions.HttpResponseError:
"""
result = self._client.get_ekm_connection(**kwargs)
return KeyVaultEkmConnection._from_generated(result)

@distributed_trace
def create_ekm_connection(self, connection: KeyVaultEkmConnection, **kwargs: Any) -> KeyVaultEkmConnection:
"""Creates the EKM connection.

If an EKM connection already exists, this operation fails.

:param connection: The EKM connection to create.
:type connection: ~azure.keyvault.administration.KeyVaultEkmConnection

:returns: The created EKM connection.
:rtype: ~azure.keyvault.administration.KeyVaultEkmConnection
:raises ~azure.core.exceptions.HttpResponseError:
"""
result = self._client.create_ekm_connection(ekm_connection=connection._to_generated(), **kwargs)
return KeyVaultEkmConnection._from_generated(result)

@distributed_trace
def update_ekm_connection(self, connection: KeyVaultEkmConnection, **kwargs: Any) -> KeyVaultEkmConnection:
"""Updates the existing EKM connection.

If no EKM connection exists, this operation fails.

:param connection: The EKM connection to update.
:type connection: ~azure.keyvault.administration.KeyVaultEkmConnection

:returns: The updated EKM connection.
:rtype: ~azure.keyvault.administration.KeyVaultEkmConnection
:raises ~azure.core.exceptions.HttpResponseError:
"""
result = self._client.update_ekm_connection(ekm_connection=connection._to_generated(), **kwargs)
return KeyVaultEkmConnection._from_generated(result)

@distributed_trace
def delete_ekm_connection( # pylint:disable=bad-option-value,delete-operation-wrong-return-type
self, **kwargs: Any
) -> KeyVaultEkmConnection:
"""Deletes the existing EKM connection.

If no EKM connection exists, this operation fails.

:returns: The deleted EKM connection.
:rtype: ~azure.keyvault.administration.KeyVaultEkmConnection
:raises ~azure.core.exceptions.HttpResponseError:
"""
result = self._client.delete_ekm_connection(**kwargs)
return KeyVaultEkmConnection._from_generated(result)

@distributed_trace
def get_ekm_certificate(self, **kwargs: Any) -> KeyVaultEkmProxyClientCertificateInfo:
"""Gets the EKM proxy client certificate information used to authenticate to the EKM proxy.

:returns: The EKM proxy client certificate information.
:rtype: ~azure.keyvault.administration.KeyVaultEkmProxyClientCertificateInfo
:raises ~azure.core.exceptions.HttpResponseError:
"""
result = self._client.get_ekm_certificate(**kwargs)
return KeyVaultEkmProxyClientCertificateInfo._from_generated(result)

@distributed_trace
def check_ekm_connection(self, **kwargs: Any) -> KeyVaultEkmProxyInfo:
"""Checks the EKM connection by pinging the EKM proxy.

:returns: Information about the EKM proxy returned by the connectivity check.
:rtype: ~azure.keyvault.administration.KeyVaultEkmProxyInfo
:raises ~azure.core.exceptions.HttpResponseError:
"""
result = self._client.check_ekm_connection(**kwargs)
return KeyVaultEkmProxyInfo._from_generated(result)

def __enter__(self) -> "KeyVaultEkmClient":
self._client.__enter__()
return self
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ class KeyVaultClient(_KeyVaultClientOperationsMixin):
:type vault_base_url: str
:param credential: Credential used to authenticate requests to the service. Required.
:type credential: ~azure.core.credentials.TokenCredential
:keyword api_version: The API version to use for this operation. Known values are "2025-07-01".
Default value is "2025-07-01". Note that overriding this default value may result in
unsupported behavior.
:keyword api_version: The API version to use for this operation. Known values are
"2026-01-01-preview". Default value is "2026-01-01-preview". Note that overriding this default
value may result in unsupported behavior.
:paramtype api_version: str
:keyword int polling_interval: Default waiting time between two polls for LRO operations if no
Retry-After header is present.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ class KeyVaultClientConfiguration: # pylint: disable=too-many-instance-attribut
:type vault_base_url: str
:param credential: Credential used to authenticate requests to the service. Required.
:type credential: ~azure.core.credentials.TokenCredential
:keyword api_version: The API version to use for this operation. Known values are "2025-07-01".
Default value is "2025-07-01". Note that overriding this default value may result in
unsupported behavior.
:keyword api_version: The API version to use for this operation. Known values are
"2026-01-01-preview". Default value is "2026-01-01-preview". Note that overriding this default
value may result in unsupported behavior.
:paramtype api_version: str
"""

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

if vault_base_url is None:
raise ValueError("Parameter 'vault_base_url' must not be None.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ class KeyVaultClient(_KeyVaultClientOperationsMixin):
:type vault_base_url: str
:param credential: Credential used to authenticate requests to the service. Required.
:type credential: ~azure.core.credentials_async.AsyncTokenCredential
:keyword api_version: The API version to use for this operation. Known values are "2025-07-01".
Default value is "2025-07-01". Note that overriding this default value may result in
unsupported behavior.
:keyword api_version: The API version to use for this operation. Known values are
"2026-01-01-preview". Default value is "2026-01-01-preview". Note that overriding this default
value may result in unsupported behavior.
:paramtype api_version: str
:keyword int polling_interval: Default waiting time between two polls for LRO operations if no
Retry-After header is present.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ class KeyVaultClientConfiguration: # pylint: disable=too-many-instance-attribut
:type vault_base_url: str
:param credential: Credential used to authenticate requests to the service. Required.
:type credential: ~azure.core.credentials_async.AsyncTokenCredential
:keyword api_version: The API version to use for this operation. Known values are "2025-07-01".
Default value is "2025-07-01". Note that overriding this default value may result in
unsupported behavior.
:keyword api_version: The API version to use for this operation. Known values are
"2026-01-01-preview". Default value is "2026-01-01-preview". Note that overriding this default
value may result in unsupported behavior.
:paramtype api_version: str
"""

def __init__(self, vault_base_url: str, credential: "AsyncTokenCredential", **kwargs: Any) -> None:
api_version: str = kwargs.pop("api_version", "2025-07-01")
api_version: str = kwargs.pop("api_version", "2026-01-01-preview")

if vault_base_url is None:
raise ValueError("Parameter 'vault_base_url' must not be None.")
Expand Down
Loading
Loading