Skip to content
Learni
View all tutorials
Azure

How to Master Azure Key Vault in 2026

Lire en français

Introduction

Azure Key Vault is Microsoft's essential service for centrally managing secrets, cryptographic keys, and certificates in hybrid cloud environments. In 2026, with rising zero-trust attacks and regulations like GDPR 2.0, skipping Key Vault risks massive data leaks. This expert tutorial guides you step-by-step to create an HSM-compliant vault, set up granular RBAC access, integrate via SDKs in Node.js and Python, automate secret rotation, and monitor access. Every step includes complete, functional code ready to copy-paste after adapting variables (like resource group names). By the end, you'll master advanced patterns like Managed Identities and Purview auditing, making your deployments production-ready. Ideal for cloud architects managing critical workloads.

Prerequisites

  • Active Azure account with a paid subscription (free sandbox limited for HSM).
  • Azure CLI 2.65+ installed and logged in (az login).
  • PowerShell 7+ with Az.Accounts and Az.KeyVault modules (install via Install-Module -Name Az -Scope CurrentUser).
  • Node.js 20+ and Python 3.12+ for SDKs.
  • Visual Studio Code with Azure and TypeScript extensions.
  • Advanced knowledge of Azure IAM and cryptography (RSA/ECDSA).

Create the Resource Group and Key Vault

create-keyvault.sh
#!/bin/bash

# Variables - ADAPT THEM
RESOURCE_GROUP="rg-kv-expert-2026"
LOCATION="francecentral"
VAULT_NAME="kv-expert-$(date +%s)"  # Unique!
SKU="premium"  # For HSM

# Create RG
az group create --name $RESOURCE_GROUP --location $LOCATION --tags Environment=Production Owner=Expert

# Create Key Vault with purge protection and soft-delete
az keyvault create \
  --name $VAULT_NAME \
  --resource-group $RESOURCE_GROUP \
  --location $LOCATION \
  --sku $SKU \
  --enable-rbac-authorization true \
  --enable-purge-protection true \
  --retention-days 90 \
  --network-acarding default \
  --public-network-access Disabled  # Secure by default

# Output
az keyvault show --name $VAULT_NAME --resource-group $RESOURCE_GROUP

This script creates a premium Key Vault (hardware HSM) with RBAC enabled, purge protection, and soft-delete for compliance. Use --public-network-access Disabled to enforce VNet/private endpoint. Ensure VAULT_NAME uniqueness with timestamp. Run in bash or Git Bash.

Configure Advanced RBAC Access

For granular control, use Azure RBAC instead of legacy access policies (deprecated in 2026). Assign custom roles like 'Key Vault Crypto User' for decryption without secret reads. Analogy: RBAC is like a safe with specific RFID badges, avoiding overly permissive master keys.

Assign RBAC Roles to a Managed Identity

rbac-roles.sh
#!/bin/bash

# Variables
RESOURCE_GROUP="rg-kv-expert-2026"
VAULT_NAME="kv-expert-[TIMESTAMP]"  # Replace with your vault
PRINCIPAL_ID="$(az identity create --resource-group $RESOURCE_GROUP --name mi-kv-app --query principalId -o tsv)"  # Create Managed Identity

# RBAC roles (vault scope)
ROLE_SCOPE="/subscriptions/[SUB_ID]/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/$VAULT_NAME"  # Replace SUB_ID

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "Key Vault Secrets User" \
  --scope $ROLE_SCOPE

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "Key Vault Administrator" \
  --scope $ROLE_SCOPE

# List assignments
az role assignment list --scope $ROLE_SCOPE --assignee $PRINCIPAL_ID

Creates a User Assigned Managed Identity and assigns RBAC roles for secrets/keys. Replace SUB_ID with az account show --query id -o tsv. Principle of least privilege: 'Secrets User' for read-only. Verify with az role assignment list.

Store Secrets and Create an RSA Key

store-secrets.sh
#!/bin/bash

VAULT_NAME="kv-expert-[TIMESTAMP]"
RESOURCE_GROUP="rg-kv-expert-2026"

# Store a secret (e.g., DB password)
az keyvault secret set \
  --vault-name $VAULT_NAME \
  --name "db-password" \
  --value "P@ssw0rdEx3mple2026!" \
  --expires "2027-01-01" \
  --tags Environment=Prod

# Create RSA 4096 key for encryption
az keyvault key create \
  --vault-name $VAULT_NAME \
  --name "rsa-sign-key" \
  --kty RSA \
  --size 4096 \
  --ops sign verify \
  --expires "2027-01-01"

# Retrieve and display (latest version)
az keyvault secret show --vault-name $VAULT_NAME --name "db-password" --query value -o tsv
echo "Key URI: $(az keyvault key show --vault-name $VAULT_NAME --name "rsa-sign-key" --query key.kid -o tsv)"

Stores a secret with expiration and creates an RSA key for signing. Always set --expires for forced rotation. Use tags for traceability. Avoid --disabled except for staging.

Integrate Key Vault into a Node.js App

Use the official SDK with DefaultAzureCredential for zero-config auth (MI, CLI fallback). Analogy: Like a valet retrieving your key without you seeing it. For production, deploy to AKS/App Service with assigned MI.

TypeScript App Retrieving Secret and Signing

keyvault-app.ts
import { DefaultAzureCredential } from '@azure/identity';
import { SecretClient } from '@azure/keyvault-secrets';
import { CryptographyClient, KeyClient } from '@azure/keyvault-keys';
import { SignResult } from '@azure/keyvault-keys';

async function main() {
  const vaultUrl = 'https://kv-expert-[TIMESTAMP].vault.azure.net/';
  const credential = new DefaultAzureCredential();

  // Retrieve secret
  const secretClient = new SecretClient(vaultUrl, credential);
  const secret = await secretClient.getSecret('db-password');
  console.log('Secret value:', secret.value);

  // Sign with key
  const keyClient = new KeyClient(vaultUrl, credential);
  const cryptoClient = new CryptographyClient(keyClient.getKey('rsa-sign-key'), credential);
  const dataToSign = Buffer.from('Message à signer 2026');
  const signResult: SignResult = await cryptoClient.sign('RS256', dataToSign);
  console.log('Signature:', signResult.signature?.toString('base64'));
}

main().catch(console.error);

Complete code using DefaultAzureCredential (MI/CLI). Install deps: npm i @azure/identity @azure/keyvault-secrets @azure/keyvault-keys. Replace vaultUrl. Handles async errors implicitly. Test locally with az login.

Python Script for Rotation and Purge

rotate-purge.py
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
from azure.keyvault.administration import KeyVaultPurgeProtectionClient, AccessControlClient
from datetime import datetime, timedelta

credential = DefaultAzureCredential()
kv_client = SecretClient(vault_url="https://kv-expert-[TIMESTAMP].vault.azure.net/", credential=credential)

# New secret version (rotation)
new_secret = "NewP@ss2026!" + str(datetime.now())
kv_client.set_secret("db-password", new_secret, expires=datetime.utcnow() + timedelta(days=365))
print("Secret rotated.")

# Purge soft-deleted (admin only)
purge_client = KeyVaultPurgeProtectionClient(vault_url="https://kv-expert-[TIMESTAMP].vault.azure.net/", credential=credential)
# purge_client.begin_purge_secret("db-password-old")  # Uncomment for purge

# List versions
versions = kv_client.list_properties_of_secrets("db-password")
for v in versions:
    print(f"Version: {v.version}, Expires: {v.expires_on}")

Automates rotation by setting a new version and lists history. Use pip install azure-identity azure-keyvault-secrets azure-keyvault-administration. For purge, require 'Key Vault Purge' role. Avoid immediate purge in production.

Best Practices

  • Always use Managed Identities: Avoid static client secrets; prefer system/user MI for zero-creds.
  • Enable Private Link + Firewall: Block public access, integrate VNet for zero-exposure.
  • Automated Rotation: Set up Event Grid + Logic App to rotate secrets >90 days.
  • HSM premium SKU: For FIPS 140-2 Level 3 in finance/healthcare.
  • Audit logs to Log Analytics: Query with KQL for anomaly detection.

Common Errors to Avoid

  • Legacy Access Policies: Migrate to RBAC or face throttling at 10 ops/sec.
  • No Versioning: Always get latest, but log versions for debugging.
  • Forget Purge Protection: Soft-deleted secrets unrecoverable after 90 days; set --retention-days.
  • Credential Fallback: DefaultAzureCredential tries MI>CLI>Env; test in CI/CD.

Next Steps