Skip to main content
skill CX Codex

azure-keyvault — Claude Code skill for Azure secrets and keys

A skill for Azure Key Vault: stores secrets, keys and certificates, sets up access and wires them into Azure services.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill azure-keyvault -a claude-code
Open on GitHub

What azure-keyvault does

The skill hands your agent ready az commands for Azure Key Vault. Vault creation with RBAC or access policies, writing and reading secrets, versions, expiry dates, soft-delete and recovery, backups. Separate sections cover RSA and EC keys, encryption, rotation and rotation policy, plus certificates: self-signed, .pfx import, PEM download.

Access goes through RBAC or access policies, with role assignments for managed identities. There are also examples of feeding secrets into AKS, App Service and Azure Functions, and working with customer-managed keys. You need Azure CLI (az), a subscription with Contributor or Key Vault Administrator rights, and a managed identity for application access. Without the role and the identity, vault creation and access grants will fail.

Reach for it when secrets already live in Azure and you want them managed in one place instead of scattered across environment variables. The FIPS 140-2 and diagnostics sections matter if key storage has compliance requirements.

What it helps with

  • create a Key Vault with RBAC and soft-delete
  • write and read a secret from the vault
  • set up rotation for an encryption key
  • grant a managed identity access to secrets
  • import a TLS certificate into Key Vault

Example prompts for the agent

  • Create a Key Vault with RBAC authorization and 90-day soft-delete
  • Store the database password in Key Vault and print its value
  • Set a rotation policy for the data-encryption-key

How to install azure-keyvault

1Skills CLI (Vercel)

npx skills add BagelHole/DevOps-Security-Agent-Skills --skill azure-keyvault -a claude-code

2Manually: put the files in place

~/.claude/skills/azure-keyvault/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/azure-keyvault/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about azure-keyvault

How do I install azure-keyvault in Claude?

Run npx skills add BagelHole/DevOps-Security-Agent-Skills --skill azure-keyvault -a claude-code. The skill lands in ~/.claude/skills/azure-keyvault/SKILL.md.

What does azure-keyvault do?

It gives the agent az commands for secrets, keys and certificates in Azure Key Vault: vault creation, access, versions, rotation, backups.

What do I need before using it?

Azure CLI, a subscription with Contributor or Key Vault Administrator rights, and a managed identity for application access.

Source text

SKILL.md · MIT
---
name: azure-keyvault
description: Manage secrets and certificates in Azure Key Vault. Configure access policies, integrate with Azure services, and implement secure secret management. Use when managing secrets in Azure environments.
license: MIT
metadata:
  author: devops-skills
  version: "1.0"
---

# Azure Key Vault

Securely store and manage secrets, keys, and certificates in Azure.

## When to Use This Skill

Use this skill when:
- Managing secrets, encryption keys, or certificates in Azure
- Implementing centralized secret management for Azure services
- Integrating secrets into AKS, App Service, or Azure Functions
- Encrypting data with customer-managed keys (CMK)
- Meeting compliance requirements for key management (FIPS 140-2)

## Prerequisites

- Azure subscription with appropriate permissions
- Azure CLI installed (`az` command)
- Contributor or Key Vault Administrator role for vault management
- Managed identity configured for application access
- Understanding of Azure RBAC vs. Key Vault access policies

## Vault Creation and Configuration

```bash
# Create a resource group
az group create --name rg-secrets --location eastus

# Create Key Vault with RBAC authorization (recommended)
az keyvault create \
  --name myapp-vault-prod \
  --resource-group rg-secrets \
  --location eastus \
  --enable-rbac-authorization true \
  --enable-soft-delete true \
  --retention-days 90 \
  --enable-purge-protection true \
  --sku premium  # Use premium for HSM-backed keys

# Create Key Vault with access policies (legacy)
az keyvault create \
  --name myapp-vault-dev \
  --resource-group rg-secrets \
  --location eastus \
  --enable-soft-delete true \
  --retention-days 30

# Enable private endpoint (no public access)
az keyvault update \
  --name myapp-vault-prod \
  --resource-group rg-secrets \
  --public-network-access Disabled

# Enable diagnostics logging
az monitor diagnostic-settings create \
  --name kv-diagnostics \
  --resource "/subscriptions/{sub}/resourceGroups/rg-secrets/providers/Microsoft.KeyVault/vaults/myapp-vault-prod" \
  --workspace "/subscriptions/{sub}/resourceGroups/rg-monitor/providers/Microsoft.OperationalInsights/workspaces/security-logs" \
  --logs '[{"category":"AuditEvent","enabled":true,"retentionPolicy":{"enabled":true,"days":365}}]'
```

## Secret Management

```bash
# Set a secret
az keyvault secret set \
  --vault-name myapp-vault-prod \
  --name db-password \
  --value "S3cur3P@ssw0rd!" \
  --content-type "text/plain" \
  --tags Environment=production Team=platform

# Set a multi-line secret (JSON credentials)
az keyvault secret set \
  --vault-name myapp-vault-prod \
  --name db-credentials \
  --value '{"username":"dbadmin","password":"S3cur3P@ss!","host":"db.postgres.database.azure.com","port":5432}'

# Get secret value
az keyvault secret show \
  --vault-name myapp-vault-prod \
  --name db-password \
  --query value -o tsv

# Get specific version
az keyvault secret show \
  --vault-name myapp-vault-prod \
  --name db-password \
  --version abc123def456

# List all secrets
az keyvault secret list --vault-name myapp-vault-prod -o table

# List secret versions
az keyvault secret list-versions \
  --vault-name myapp-vault-prod \
  --name db-password -o table

# Set expiration date
az keyvault secret set-attributes \
  --vault-name myapp-vault-prod \
  --name api-key \
  --expires "2026-01-01T00:00:00Z"

# Disable a secret (without deleting)
az keyvault secret set-attributes \
  --vault-name myapp-vault-prod \
  --name old-api-key \
  --enabled false

# Delete a secret (soft-delete)
az keyvault secret delete \
  --vault-name myapp-vault-prod \
  --name old-api-key

# Recover a deleted secret
az keyvault secret recover \
  --vault-name myapp-vault-prod \
  --name old-api-key

# Purge a deleted secret (permanent, requires purge protection to be off)
az keyvault secret purge \
  --vault-name myapp-vault-prod \
  --name old-api-key

# Backup and restore
az keyvault secret backup \
  --vault-name myapp-vault-prod \
  --name db-password \
  --file db-password.backup

az keyvault secret restore \
  --vault-name myapp-vault-prod \
  --file db-password.backup
```

## Key Management

```bash
# Create an RSA key for encryption
az keyvault key create \
  --vault-name myapp-vault-prod \
  --name data-encryption-key \
  --kty RSA \
  --size 4096 \
  --ops encrypt decrypt wrapKey unwrapKey

# Create an EC key for signing
az keyvault key create \
  --vault-name myapp-vault-prod \
  --name signing-key \
  --kty EC \
  --curve P-256 \
  --ops sign verify

# Import an existing key
az keyvault key import \
  --vault-name myapp-vault-prod \
  --name imported-key \
  --pem-file key.pem

# Encrypt data
az keyvault key encrypt \
  --vault-name myapp-vault-prod \
  --name data-encryption-key \
  --algorithm RSA-OAEP-256 \
  --value "base64-encoded-plaintext"

# Rotate a key
az keyvault key rotate \
  --vault-name myapp-vault-prod \
  --name data-encryption-key

# Set key rotation policy
az keyvault key rotation-policy update \
  --vault-name myapp-vault-prod \
  --name data-encryption-key \
  --value '{
    "lifetimeActions": [
      {
        "trigger": {"timeBeforeExpiry": "P30D"},
        "action": {"type": "Notify"}
      },
      {
        "trigger": {"timeAfterCreate": "P90D"},
        "action": {"type": "Rotate"}
      }
    ],
    "attributes": {"expiryTime": "P180D"}
  }'
```

## Certificate Management

```bash
# Create a self-signed certificate
az keyvault certificate create \
  --vault-name myapp-vault-prod \
  --name app-tls-cert \
  --policy '{
    "issuerParameters": {"name": "Self"},
    "keyProperties": {"exportable": true, "keySize": 4096, "keyType": "RSA"},
    "secretProperties": {"contentType": "application/x-pkcs12"},
    "x509CertificateProperties": {
      "subject": "CN=app.example.com",
      "subjectAlternativeNames": {"dnsNames": ["app.example.com", "*.app.example.com"]},
      "validityInMonths": 12,
      "keyUsage": ["digitalSignature", "keyEncipherment"],
      "ekus": ["1.3.6.1.5.5.7.3.1"]
    },
    "lifetimeActions": [
      {"trigger": {"daysBeforeExpiry": 30}, "action": {"actionType": "AutoRenew"}}
    ]
  }'

# Import a certificate
az keyvault certificate import \
  --vault-name myapp-vault-prod \
  --name imported-cert \
  --file certificate.pfx \
  --password "pfx-password"

# Download certificate
az keyvault certificate download \
  --vault-name myapp-vault-prod \
  --name app-tls-cert \
  --file cert.pem \
  --encoding PEM

# List certificates
az keyvault certificate list --vault-name myapp-vault-prod -o table
```

## Access Policies and RBAC

### RBAC (Recommended)

```bash
# Grant secret reader access to a managed identity
az role assignment create \
  --role "Key Vault Secrets User" \
  --assignee-object-id "$(az identity show -g rg-app -n myapp-identity --query principalId -o tsv)" \
  --scope "/subscriptions/{sub}/resourceGroups/rg-secrets/providers/Microsoft.KeyVault/vaults/myapp-vault-prod"

# Grant admin access to security team
az role assignment create \
  --role "Key Vault Administrator" \
  --assignee "[email protected]" \
  --scope "/subscriptions/{sub}/resourceGroups/rg-secrets/providers/Microsoft.KeyVault/vaults/myapp-vault-prod"

# Available Key Vault RBAC roles:
# - Key Vault Administrator (full management)
# - Key Vault Secrets Officer (manage secrets)
# - Key Vault Secrets User (read secrets)
# - Key Vault Certificates Officer (manage certs)
# - Key Vault Crypto Officer (manage keys)
# - Key Vault Crypto User (use keys for encrypt/decrypt)
# - Key Vault Reader (read metadata only)
```

### Access Policies (Legacy)

```bash
# Grant secret access via access policy
az keyvault set-policy \
  --name myapp-vault-prod \
  --object-id "$(az identity show -g rg-app -n myapp-identity --query principalId -o tsv)" \
  --secret-permissions get list

# Grant key access
az keyvault set-policy \
  --name myapp-vault-prod \
  --object-id "$OBJECT_ID" \
  --key-permissions get unwrapKey wrapKey

# Grant certificate access
az keyvault set-policy \
  --name myapp-vault-prod \
  --object-id "$OBJECT_ID" \
  --certificate-permissions get list
```

## Application Integration

### Python SDK

```python
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
from azure.keyvault.secrets import SecretClient
from azure.keyvault.keys import KeyClient
from azure.keyvault.certificates import CertificateClient

# Use DefaultAzureCredential (works locally and in Azure)
credential = DefaultAzureCredential()

vault_url = "https://myapp-vault-prod.vault.azure.net/"

# Secrets
secret_client = SecretClient(vault_url=vault_url, credential=credential)
db_password = secret_client.get_secret("db-password")
print(f"Secret value: {db_password.value}")

# Get specific version
specific = secret_client.get_secret("db-password", version="abc123")

# List secrets
for secret_properties in secret_client.list_properties_of_secrets():
    print(f"Secret: {secret_properties.name}, Enabled: {secret_properties.enabled}")

# Keys
key_client = KeyClient(vault_url=vault_url, credential=credential)
from azure.keyvault.keys.crypto import CryptographyClient, EncryptionAlgorithm

key = key_client.get_key("data-encryption-key")
crypto_client = CryptographyClient(key, credential=credential)

# Encrypt data
plaintext = b"sensitive data"
result = crypto_client.encrypt(EncryptionAlgorithm.rsa_oaep_256, plaintext)
ciphertext = result.ciphertext

# Decrypt data
decrypted = crypto_client.decrypt(EncryptionAlgorithm.rsa_oaep_256, ciphertext)
```

### .NET SDK

```csharp
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;

var credential = new DefaultAzureCredential();
var client = new SecretClient(new Uri("https://myapp-vault-prod.vault.azure.net/"), credential);

KeyVaultSecret secret = await client.GetSecretAsync("db-password");
string password = secret.Value;
```

## Kubernetes Integration (AKS)

### Secrets Store CSI Driver

```yaml
# SecretProviderClass for AKS with managed identity
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: azure-keyvault-secrets
  namespace: production
spec:
  provider: azure
  parameters:
    usePodIdentity: "false"
    useVMManagedIdentity: "true"
    userAssignedIdentityID: "<managed-identity-client-id>"
    keyvaultName: "myapp-vault-prod"
    cloudName: ""
    objects: |
      array:
        - |
          objectName: db-password
          objectType: secret
          objectVersion: ""
        - |
          objectName: api-key
          objectType: secret
        - |
          objectName: app-tls-cert
          objectType: secret
    tenantId: "<azure-tenant-id>"
  secretObjects:
    - secretName: db-secrets
      type: Opaque
      data:
        - objectName: db-password
          key: password
        - objectName: api-key
          key: api-key
    - secretName: tls-secret
      type: kubernetes.io/tls
      data:
        - objectName: app-tls-cert
          key: tls.crt
---
# Pod using the secrets
apiVersion: v1
kind: Pod
metadata:
  name: myapp
  namespace: production
spec:
  serviceAccountName: myapp-sa
  containers:
    - name: myapp
      image: ghcr.io/acme/myapp:v1.0.0
      env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secrets
              key: password
      volumeMounts:
        - name: secrets-store
          mountPath: "/mnt/secrets-store"
          readOnly: true
  volumes:
    - name: secrets-store
      csi:
        driver: secrets-store.csi.k8s.io
        readOnly: true
        volumeAttributes:
          secretProviderClass: "azure-keyvault-secrets"
```

## Terraform Configuration

```hcl
resource "azurerm_key_vault" "main" {
  name                        = "myapp-vault-prod"
  location                    = azurerm_resource_group.main.location
  resource_group_name         = azurerm_resource_group.main.name
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  sku_name                    = "premium"

  enable_rbac_authorization   = true
  purge_protection_enabled    = true
  soft_delete_retention_days  = 90
  public_network_access_enabled = false

  network_acls {
    bypass         = "AzureServices"
    default_action = "Deny"
    ip_rules       = ["203.0.113.0/24"]
    virtual_network_subnet_ids = [azurerm_subnet.app.id]
  }
}

resource "azurerm_key_vault_secret" "db_password" {
  name         = "db-password"
  value        = var.db_password
  key_vault_id = azurerm_key_vault.main.id
  content_type = "text/plain"

  expiration_date = "2026-01-01T00:00:00Z"

  tags = {
    environment = "production"
    rotation    = "enabled"
  }
}

resource "azurerm_role_assignment" "app_secrets_user" {
  scope                = azurerm_key_vault.main.id
  role_definition_name = "Key Vault Secrets User"
  principal_id         = azurerm_user_assigned_identity.app.principal_id
}
```

## Troubleshooting

| Problem | Cause | Solution |
|---------|-------|----------|
| "Access denied" when reading secrets | Missing RBAC role or access policy | Assign `Key Vault Secrets User` role; or add access policy with `get` permission |
| "Vault not found" | Network access restricted | Check firewall rules; enable private endpoint; add IP to allow list |
| Soft-deleted secret blocks creation | Name collision with deleted secret | Recover and update, or purge the deleted secret first |
| Managed identity cannot access vault | Identity not in correct scope | Verify identity principal ID; check role assignment scope matches vault |
| Certificate renewal fails | Auto-renew policy not configured | Set `lifetimeActions` with `AutoRenew` action in certificate policy |
| CSI driver fails to mount secrets | Wrong provider configuration | Verify `tenantId`, `userAssignedIdentityID`, and object names match exactly |
| High latency on secret retrieval | No client-side caching | Implement caching in application; use CSI driver for K8s (syncs on interval) |

## Best Practices

- Use RBAC authorization over access policies for granular control
- Enable soft-delete and purge protection (required for compliance)
- Use managed identities for all service access (no credentials to manage)
- Enable private endpoints to eliminate public network exposure
- Set expiration dates on all secrets and certificates
- Enable diagnostic logging and forward to SIEM
- Use premium SKU for HSM-backed key operations
- Implement key rotation policies for all encryption keys
- Regularly audit access with Azure Activity logs
- Tag all vault resources for cost and ownership tracking

## Related Skills

- [hashicorp-vault](../hashicorp-vault/) - Multi-cloud secrets
- [azure-networking](../../../infrastructure/cloud-azure/azure-networking/) - Network security
- [aws-secrets-manager](../aws-secrets-manager/) - AWS secret management
- [gcp-secret-manager](../gcp-secret-manager/) - GCP secret management

© devops-skills · MIT · BagelHole/DevOps-Security-Agent-Skills

Similar skills

Everything for Security →

From the same set127

gcp-audit-logs A skill that walks you through Cloud Audit Logs in GCP: turning on data access logs, exporting them to BigQuery, and querying suspicious events. CX Codex +1 324installs platform-engineering A skill for building an internal developer platform: Backstage portal, Crossplane self-service infrastructure and golden paths. Useful when teams drown in manual environment setup. CX Codex +1 322installs aws-lambda Build and deploy AWS Lambda serverless functions, attach triggers, configure layers, and manage canary releases through the AWS CLI. CX Codex +1 321installs ebpf-observability Guides the agent in configuring kernel-level tracing and network flows. Useful for deep debugging and security monitoring with Cilium and Tetragon without code changes. CX Codex +1 320installs llm-fine-tuning Configures infrastructure for fine-tuning open LLMs with QLoRA, LoRA, and DeepSpeed. Useful when training models on proprietary domain datasets. CX Codex +1 318installs gcp-cloud-functions Lets the agent deploy serverless functions on Google Cloud Functions: HTTP, Pub/Sub, Cloud Storage and scheduled jobs. CX Codex +1 319installs llm-caching Adds multi-layer LLM request caching across Redis, GPTCache, and provider APIs. Reduces API costs by 30–70% when queries repeat often. CX Codex +1 317installs rag-observability-evals A skill for monitoring and evaluating RAG systems: retrieval quality metrics, groundedness checks, hallucination detection and regression testing. CX Codex +1 318installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor