Azure Key Vault programming with Python

This article shows how to use the Azure Python SDK to create an Azure Key Vault, and  use it to manage secrets. A simple Python-based password keeper tool is shown as an illustration of how to use the Key Vault API.

Why Azure key vault?

What does it take to safely secure and manage information like certificates, cryptographic keys and passwords? To meet any accepted standard, you’d need to audit all layers of your solution, from the hardware infrastructure up.

Azure Key Vaults provide a way to securely store certificates, cryptographic keys and secrets in the cloud, backed by Hardware Security Modules (HSMs) and FIPS compliant, so you can focus on your app logic without having to manage the secure infrastructure yourself. Azure provides a set of operations to access, monitor and manage the data, but Microsoft is not able to see or extract it.

Creating a key vault with Python

You can manage key vaults using the Azure portal, or CLI/PowerShell, but let’s look at how to do this in Python..

Programmatically creating a key vault requires two important pieces of information:

1. An authenticated key vault management client.

You can authenticate to Azure programmatically without having to interactively log in by creating a service principal account. Here’s a guide: Create an Azure service principal with Azure CLI. This gives you a client ID, secret and tenant ID, which can be used with the Azure Python SDK to authenticate and instantiate a key vault management client like this (note: you also need your Azure subscription ID):

from azure.mgmt.keyvault import KeyVaultManagementClient
from azure.common.credentials import ServicePrincipalCredentials

credentials = ServicePrincipalCredentials(client_id=app_id, secret=app_secret, tenant=tenant_id)

kv_client = KeyVaultManagementClient(credentials, subscription_id)

2. The object ID associated with the user or service principal account who will access the vault.

AAD objects, like users and service principals, have associated object IDs. You can add multiple object IDs to a key vault configuration to specify who has access to it and what rights they have. What can be confusing is you need to call the Microsoft Graph API to find your object ID.

For example, to get the object ID for your user, you can login to the Microsoft Graph Explorer and call GET on “/v1.0/me/”.

To get the object ID for a service principal user, you can create a Graph management client and query details for your service principal. Here is an example Python function to programmatically get an object ID for a service principal account:

from azure.common.credentials import ServicePrincipalCredentials
from azure.graphrbac import GraphRbacManagementClient

def get_object_id(app_id, app_secret, tenant_id):
    '''Get the service principal object ID from Microsoft Graph'''

    # get Graph credentials
    credentials = ServicePrincipalCredentials(client_id=app_id, secret=app_secret, tenant=tenant_id, resource='https://graph.windows.net')

    graph_client = GraphRbacManagementClient(credentials, tenant_id)

    result = list(graph_client.service_principals.list(filter="servicePrincipalNames/any(c:c eq '{}')".format(app_id)))

    if result:
        return result[0].object_id
    else:
        print('Unable to get object_id from client_id')
    return None

Note that the object ID for a service principal cannot be used by an interactive user, and vice versa. I made this mistake by creating a key vault using my regular user’s object ID, and then was unable to add or read secrets with my service principal until I added its object ID to the key vault’s access policy as well (which conveniently you can do from the Azure portal).

Simple key vault create/delete program

To create a key vault, you’ll first need to create an Azure Resource Group, and choose a data center location.

Using the key vault client and the object id for the service principal user, you can create a key vault using the vaults.create_or_update() function:

vault = kv_client.vaults.create_or_update(resource-group-name, key-vault-name, { 'location': 'uswest2', 'properties': { 'sku': { 'name': 'standard' }, 'tenant_id': tenant_id, 'access_policies': [{ 'tenant_id': tenant_id, 'object_id': object_id, 'permissions': { 'keys': ['all'], 'secrets': ['all'] } }] } } )

Putting this together, and adding functionality to both create and delete key vaults using the Azure Python SDK, here’s an example command line tool to create and delete key vaults: kvcreate.py

Writing secrets

Once you’ve created a key vault, it has an access URI with the following format:

https://KEYVAULTNAME.vault.azure.net/

To add a secret to the vault, instantiate a key vault client and call the set_secret() function with the key vault’s URI. Example:

from azure.common.credentials import ServicePrincipalCredentials
from azure.keyvault import KeyVaultAuthentication, KeyVaultClient

# get credentials
credentials = ServicePrincipalCredentials(client_id=app_id, secret=app_secret, tenant=tenant_id)

# instantiate a key vault client
client = KeyVaultClient(credentials)

secret_bundle = client.set_secret(key_vault_uri, SECRET-NAME, SECRET-VALUE)

print('Secret added:', secret_bundle.id)

Similarly a secret can be deleted using delete_secret()

e.g.

client.delete_secret(key_vault_uri, SECRET-NAME)

Simple key vault secrets add/delete program

Putting this together, here’s a simple command line tool to add and remove secrets from a keyvault: kvsecret.py

Further reading

Azure Key vault library Python docs: Azure key vault libraries for Python.

Key vault management example in the Azure Python SDK samples by Laurent Mazuel: Manage key vaults with Python.

Advertisements
This entry was posted in Cloud, Computers and Internet, Cryptography, Graph, Python and tagged , , , . Bookmark the permalink.

1 Response to Azure Key Vault programming with Python

  1. Pingback: Azure Weekly: January 21, 2019 – Build Azure

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s