1# Azure Key Vault Certificates client library for Python 2Azure Key Vault helps solve the following problems: 3- Certificate management (this library) - create, manage, and deploy public and private SSL/TLS certificates 4- Cryptographic key management 5([azure-keyvault-keys](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/keyvault/azure-keyvault-keys)) - create, store, and control access to the keys used to encrypt your data 6- Secrets management 7([azure-keyvault-secrets](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/keyvault/azure-keyvault-secrets)) - 8securely store and control access to tokens, passwords, certificates, API keys, 9and other secrets 10- Vault administration ([azure-keyvault-administration](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/keyvault/azure-keyvault-administration)) - role-based access control (RBAC), and vault-level backup and restore options 11 12[Source code][certificates_client_src] | [Package (PyPI)][pypi_package_certificates] | [API reference documentation][reference_docs] | [Product documentation][keyvault_docs] | [Samples][certificates_samples] 13 14## Getting started 15### Install the package 16Install [azure-keyvault-certificates][pypi_package_certificates] and 17[azure-identity][azure_identity_pypi] with [pip][pip]: 18```Bash 19pip install azure-keyvault-certificates azure-identity 20``` 21[azure-identity][azure_identity] is used for Azure Active Directory 22authentication as demonstrated below. 23 24### Prerequisites 25* An [Azure subscription][azure_sub] 26* Python 2.7, 3.5.3, or later 27* A Key Vault. If you need to create one, you can use the 28[Azure Cloud Shell][azure_cloud_shell] to create one with these commands 29(replace `"my-resource-group"` and `"my-key-vault"` with your own, unique 30names): 31 32 (Optional) if you want a new resource group to hold the Key Vault: 33 ```sh 34 az group create --name my-resource-group --location westus2 35 ``` 36 37 Create the Key Vault: 38 ```Bash 39 az keyvault create --resource-group my-resource-group --name my-key-vault 40 ``` 41 42 Output: 43 ```json 44 { 45 "id": "...", 46 "location": "westus2", 47 "name": "my-key-vault", 48 "properties": { 49 "accessPolicies": [...], 50 "createMode": null, 51 "enablePurgeProtection": null, 52 "enableSoftDelete": null, 53 "enabledForDeployment": false, 54 "enabledForDiskEncryption": null, 55 "enabledForTemplateDeployment": null, 56 "networkAcls": null, 57 "provisioningState": "Succeeded", 58 "sku": { "name": "standard" }, 59 "tenantId": "...", 60 "vaultUri": "https://my-key-vault.vault.azure.net/" 61 }, 62 "resourceGroup": "my-resource-group", 63 "type": "Microsoft.KeyVault/vaults" 64 } 65 ``` 66 67 > The `"vaultUri"` property is the `vault_url` used by [CertificateClient][certificate_client_docs] 68 69### Authenticate the client 70This document demonstrates using [DefaultAzureCredential][default_cred_ref] 71to authenticate as a service principal. However, [CertificateClient][certificate_client_docs] 72accepts any [azure-identity][azure_identity] credential. See the 73[azure-identity][azure_identity] documentation for more information about other 74credentials. 75 76#### Create a service principal (optional) 77This [Azure Cloud Shell][azure_cloud_shell] snippet shows how to create a 78new service principal. Before using it, replace "your-application-name" with 79a more appropriate name for your service principal. 80 81Create a service principal: 82```Bash 83az ad sp create-for-rbac --name http://my-application --skip-assignment 84``` 85 86> Output: 87> ```json 88> { 89> "appId": "generated app id", 90> "displayName": "my-application", 91> "name": "http://my-application", 92> "password": "random password", 93> "tenant": "tenant id" 94> } 95> ``` 96 97Use the output to set **AZURE_CLIENT_ID** ("appId" above), **AZURE_CLIENT_SECRET** 98("password" above) and **AZURE_TENANT_ID** ("tenant" above) environment variables. 99The following example shows a way to do this in Bash: 100```Bash 101export AZURE_CLIENT_ID="generated app id" 102export AZURE_CLIENT_SECRET="random password" 103export AZURE_TENANT_ID="tenant id" 104``` 105 106Authorize the service principal to perform certificate operations in your Key Vault: 107```Bash 108az keyvault set-policy --name my-key-vault --spn $AZURE_CLIENT_ID --certificate-permissions backup create delete get import list purge recover restore update 109``` 110> Possible certificate permissions: backup, create, delete, deleteissuers, get, getissuers, import, list, listissuers, managecontacts, manageissuers, purge, recover, restore, setissuers, update 111 112If you have enabled role-based access control (RBAC) for Key Vault instead, you can find roles like "Key Vault Certificates Officer" in our [RBAC guide][rbac_guide]. 113 114#### Create a client 115Once the **AZURE_CLIENT_ID**, **AZURE_CLIENT_SECRET** and 116**AZURE_TENANT_ID** environment variables are set, 117[DefaultAzureCredential][default_cred_ref] will be able to authenticate the 118[CertificateClient][certificate_client_docs]. 119 120Constructing the client also requires your vault's URL, which you can 121get from the Azure CLI or the Azure Portal. In the Azure Portal, this URL is 122the vault's "DNS Name". 123 124```python 125from azure.identity import DefaultAzureCredential 126from azure.keyvault.certificates import CertificateClient 127 128credential = DefaultAzureCredential() 129 130certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 131``` 132 133## Key concepts 134### Certificate Client 135With a [CertificateClient][certificate_client_docs] you can get certificates from the vault, create new certificates and 136new versions of existing certificates, update certificate metadata, and delete certificates. You 137can also manage certificate issuers, contacts, and management policies of certificates. This is 138illustrated in the [examples](#examples) below. 139 140## Examples 141This section contains code snippets covering common tasks: 142* [Create a Certificate](#create-a-certificate "Create a Certificate") 143* [Retrieve a Certificate](#retrieve-a-certificate "Retrieve a Certificate") 144* [Update Properties of an existing Certificate](#update-properties-of-an-existing-certificate "Update Properties of an existing Certificate") 145* [Delete a Certificate](#delete-a-certificate "Delete a Certificate") 146* [List Properites of Certificates](#list-properties-of-certificates "List Properties of Certificates") 147* [Asynchronously create a Certificate](#asynchronously-create-a-certificate "Asynchronously create a Certificate") 148* [Asynchronously list properties of Certificates](#asynchronously-list-properties-of-certificates "Asynchronously list properties of Certificates") 149 150### Create a Certificate 151[begin_create_certificate](https://aka.ms/azsdk/python/keyvault-certificates/docs#azure.keyvault.certificates.CertificateClient.begin_create_certificate) 152creates a certificate to be stored in the Azure Key Vault. If a certificate with the same name already exists, a new 153version of the certificate is created. Before creating a certificate, a management policy for the certificate can be 154created or our default policy will be used. This method returns a long running operation poller. 155```python 156from azure.identity import DefaultAzureCredential 157from azure.keyvault.certificates import CertificateClient, CertificatePolicy 158 159credential = DefaultAzureCredential() 160 161certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 162 163create_certificate_poller = certificate_client.begin_create_certificate( 164 certificate_name="cert-name", policy=CertificatePolicy.get_default() 165) 166print(create_certificate_poller.result()) 167``` 168If you would like to check the status of your certificate creation, you can call `status()` on the poller or 169[get_certificate_operation](https://aka.ms/azsdk/python/keyvault-certificates/docs#azure.keyvault.certificates.CertificateClient.get_certificate_operation) 170with the name of the certificate. 171 172### Retrieve a Certificate 173[get_certificate](https://aka.ms/azsdk/python/keyvault-certificates/docs#azure.keyvault.certificates.CertificateClient.get_certificate) 174retrieves the latest version of a certificate previously stored in the Key Vault. 175```python 176from azure.identity import DefaultAzureCredential 177from azure.keyvault.certificates import CertificateClient 178 179credential = DefaultAzureCredential() 180 181certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 182 183certificate = certificate_client.get_certificate("cert-name") 184 185print(certificate.name) 186print(certificate.properties.version) 187print(certificate.policy.issuer_name) 188``` 189 190[get_certificate_version](https://aka.ms/azsdk/python/keyvault-certificates/docs#azure.keyvault.certificates.CertificateClient.get_certificate_version) 191retrieves a specific version of a certificate. 192```python 193from azure.identity import DefaultAzureCredential 194from azure.keyvault.certificates import CertificateClient 195 196credential = DefaultAzureCredential() 197 198certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 199certificate = certificate_client.get_certificate_version(certificate_name="cert-name", version="cert-version") 200 201print(certificate.name) 202print(certificate.properties.version) 203``` 204 205### Update properties of an existing Certificate 206[update_certificate_properties](https://aka.ms/azsdk/python/keyvault-certificates/docs#azure.keyvault.certificates.CertificateClient.update_certificate_properties) 207updates a certificate previously stored in the Key Vault. 208```python 209from azure.identity import DefaultAzureCredential 210from azure.keyvault.certificates import CertificateClient 211 212credential = DefaultAzureCredential() 213 214certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 215 216# we will now disable the certificate for further use 217updated_certificate= certificate_client.update_certificate_properties( 218 certificate_name="cert-name", enabled=False 219) 220 221print(updated_certificate.name) 222print(updated_certificate.properties.enabled) 223``` 224 225### Delete a Certificate 226[begin_delete_certificate](https://aka.ms/azsdk/python/keyvault-certificates/docs#azure.keyvault.certificates.CertificateClient.begin_delete_certificate) 227requests Key Vault delete a certificate, returning a poller which allows you to wait for the deletion to finish. 228Waiting is helpful when the vault has [soft-delete][soft_delete] enabled, and you want to purge 229(permanently delete) the certificate as soon as possible. When [soft-delete][soft_delete] is disabled, 230`begin_delete_certificate` itself is permanent. 231 232```python 233from azure.identity import DefaultAzureCredential 234from azure.keyvault.certificates import CertificateClient 235 236credential = DefaultAzureCredential() 237 238certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 239 240deleted_certificate_poller = certificate_client.begin_delete_certificate("cert-name") 241 242deleted_certificate = deleted_certificate_poller.result() 243print(deleted_certificate.name) 244print(deleted_certificate.deleted_on) 245``` 246### List properties of Certificates 247[list_properties_of_certificates](https://aka.ms/azsdk/python/keyvault-certificates/docs#azure.keyvault.certificates.CertificateClient.list_properties_of_certificates) 248lists the properties of all certificates in the specified Key Vault. 249```python 250from azure.identity import DefaultAzureCredential 251from azure.keyvault.certificates import CertificateClient 252 253credential = DefaultAzureCredential() 254 255certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 256 257certificates = certificate_client.list_properties_of_certificates() 258 259for certificate in certificates: 260 # this list doesn't include versions of the certificates 261 print(certificate.name) 262``` 263 264### Async operations 265This library includes a complete async API supported on Python 3.5+. To use it, you must 266first install an async transport, such as [aiohttp](https://pypi.org/project/aiohttp/). 267See 268[azure-core documentation](https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/core/azure-core/CLIENT_LIBRARY_DEVELOPER.md#transport) 269for more information. 270 271Async clients and credentials should be closed when they're no longer needed. These 272objects are async context managers and define async `close` methods. For 273example: 274 275```py 276from azure.identity.aio import DefaultAzureCredential 277from azure.keyvault.certificates.aio import CertificateClient 278 279credential = DefaultAzureCredential() 280 281# call close when the client and credential are no longer needed 282client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 283... 284await client.close() 285await credential.close() 286 287# alternatively, use them as async context managers (contextlib.AsyncExitStack can help) 288client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 289async with client: 290 async with credential: 291 ... 292``` 293 294### Asynchronously create a Certificate 295[create_certificate](https://aka.ms/azsdk/python/keyvault-certificates/aio/docs#azure.keyvault.certificates.aio.CertificateClient.create_certificate) 296creates a certificate to be stored in the Azure Key Vault. If a certificate with the same name already exists, a new 297version of the certificate is created. Before creating a certificate, a management policy for the certificate can be 298created or our default policy will be used. Awaiting `create_certificate` returns your created certificate if creation 299is successful, and a 300[CertificateOperation](https://aka.ms/azsdk/python/keyvault-certificates/docs#azure.keyvault.certificates.CertificateOperation) 301if it is not. 302```python 303from azure.identity.aio import DefaultAzureCredential 304from azure.keyvault.certificates.aio import CertificateClient 305from azure.keyvault.certificates import CertificatePolicy 306 307credential = DefaultAzureCredential() 308 309certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 310 311create_certificate_result = await certificate_client.create_certificate( 312 certificate_name="cert-name", policy=CertificatePolicy.get_default() 313) 314print(create_certificate_result) 315``` 316 317### Asynchronously list properties of Certificates 318[list_properties_of_certificates](https://aka.ms/azsdk/python/keyvault-certificates/aio/docs#azure.keyvault.certificates.aio.CertificateClient.list_properties_of_certificates) 319lists all the properties of the certificates in the client's vault: 320```python 321from azure.identity.aio import DefaultAzureCredential 322from azure.keyvault.certificates.aio import CertificateClient 323 324credential = DefaultAzureCredential() 325 326certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 327 328certificates = certificate_client.list_properties_of_certificates() 329async for certificate in certificates: 330 print(certificate.name) 331``` 332 333## Troubleshooting 334### General 335Key Vault clients raise exceptions defined in [azure-core][azure_core_exceptions]. 336For example, if you try to get a key that doesn't exist in the vault, [CertificateClient][certificate_client_docs] 337raises [ResourceNotFoundError](https://aka.ms/azsdk-python-core-exceptions-resource-not-found-error): 338```python 339from azure.identity import DefaultAzureCredential 340from azure.keyvault.certificates import CertificateClient 341from azure.core.exceptions import ResourceNotFoundError 342 343credential = DefaultAzureCredential() 344certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential) 345 346try: 347 certificate_client.get_certificate("which-does-not-exist") 348except ResourceNotFoundError as e: 349 print(e.message) 350``` 351### Logging 352This library uses the standard 353[logging](https://docs.python.org/3.5/library/logging.html) library for logging. 354Basic information about HTTP sessions (URLs, headers, etc.) is logged at INFO 355level. 356 357Detailed DEBUG level logging, including request/response bodies and unredacted 358headers, can be enabled on a client with the `logging_enable` argument: 359```py 360from azure.identity import DefaultAzureCredential 361from azure.keyvault.certificates import CertificateClient 362import sys 363import logging 364 365# Create a logger for the 'azure' SDK 366logger = logging.getLogger('azure') 367logger.setLevel(logging.DEBUG) 368 369# Configure a console output 370handler = logging.StreamHandler(stream=sys.stdout) 371logger.addHandler(handler) 372 373credential = DefaultAzureCredential() 374 375# This client will log detailed information about its HTTP sessions, at DEBUG level 376client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential, logging_enable=True) 377``` 378 379Network trace logging can also be enabled for any single operation: 380 ```python 381certificate = certificate_client.get_certificate(certificate_name="cert-name", logging_enable=True) 382``` 383 384## Next steps 385Several samples are available in the Azure SDK for Python GitHub repository. These samples provide example code for additional Key Vault scenarios: 386* [hello_world.py][hello_world_sample] and [hello_world_async.py][hello_world_async_sample] - create/get/update/delete certificates 387* [backup_restore_operations.py][backup_operations_sample] and [backup_restore_operations_async.py][backup_operations_async_sample] - backup and 388recover certificates 389* [list_operations.py][list_operations_sample] and [list_operations_async.py][list_operations_async_sample] - list certificates 390* [recover_purge_operations.py][recover_purge_operations_sample] and [recover_purge_operations_async.py][recover_purge_operations_async_sample] - recover and purge certificates 391* [issuers.py][issuers_sample] and [issuers_async.py][issuers_async_sample] - manage certificate issuers 392* [contacts.py][contacts_sample] and [contacts_async.py][contacts_async_sample] - manage certificate contacts 393 394### Additional Documentation 395For more extensive documentation on Azure Key Vault, see the [API reference documentation][reference_docs]. 396 397## Contributing 398This project welcomes contributions and suggestions. Most contributions require 399you to agree to a Contributor License Agreement (CLA) declaring that you have 400the right to, and actually do, grant us the rights to use your contribution. 401For details, visit https://cla.microsoft.com. 402 403When you submit a pull request, a CLA-bot will automatically determine whether 404you need to provide a CLA and decorate the PR appropriately (e.g., label, 405comment). Simply follow the instructions provided by the bot. You will only 406need to do this once across all repos using our CLA. 407 408This project has adopted the [Microsoft Open Source Code of Conduct][code_of_conduct]. 409For more information, see the 410[Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 411contact opencode@microsoft.com with any additional questions or comments. 412 413[default_cred_ref]: https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential 414[azure_cloud_shell]: https://shell.azure.com/bash 415[azure_core_exceptions]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/core/azure-core#azure-core-library-exceptions 416[azure_identity]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/identity/azure-identity 417[azure_identity_pypi]: https://pypi.org/project/azure-identity/ 418[azure_sub]: https://azure.microsoft.com/free/ 419[code_of_conduct]: https://opensource.microsoft.com/codeofconduct/ 420[backup_operations_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/backup_restore_operations.py 421[backup_operations_async_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/backup_restore_operations_async.py 422[hello_world_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/hello_world.py 423[hello_world_async_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/hello_world_async.py 424[keyvault_docs]: https://docs.microsoft.com/azure/key-vault/ 425[list_operations_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/list_operations.py 426[list_operations_async_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/list_operations_async.py 427[recover_purge_operations_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/recover_purge_operations.py 428[recover_purge_operations_async_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/recover_purge_operations_async.py 429[contacts_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/contacts.py 430[contacts_async_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/contacts_async.py 431[issuers_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/issuers.py 432[issuers_async_sample]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/keyvault/azure-keyvault-certificates/samples/issuers_async.py 433[pip]: https://pypi.org/project/pip/ 434[pypi_package_certificates]: https://pypi.org/project/azure-keyvault-certificates/ 435[certificate_client_docs]: https://aka.ms/azsdk/python/keyvault-certificates/docs#azure.keyvault.certificates.CertificateClient 436[rbac_guide]: https://docs.microsoft.com/azure/key-vault/general/rbac-guide 437[reference_docs]: https://aka.ms/azsdk/python/keyvault-certificates/docs 438[certificates_client_src]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/keyvault/azure-keyvault-certificates/azure/keyvault/certificates 439[certificates_samples]: https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/keyvault/azure-keyvault-certificates/samples 440[soft_delete]: https://docs.microsoft.com/azure/key-vault/key-vault-ovw-soft-delete 441 442![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-python%2Fsdk%2Fkeyvault%2Fazure-keyvault-certificates%2FREADME.png) 443