Access Policies vs RBAC

Overview

Azure Key Vault supports two authorization models: Vault Access Policies (legacy) and Azure RBAC (recommended). Understanding both is essential for securing Key Vault and migrating existing deployments to the modern model.


Comparison

FeatureAccess PoliciesAzure RBAC
GranularityVault-level (all secrets or none)Individual secret/key/certificate
ManagementPer-vault configurationAzure-wide IAM
AuditLimitedFull Azure Activity Log
Conditional AccessNot supportedSupported
Max assignments1024 per vaultAzure subscription limits
RecommendationLegacyPreferred

Vault Access Policies

Access policies grant permissions at the vault level. A principal gets access to all secrets, keys, or certificates within the granted permission set.

Assign via CLI

az keyvault set-policy \
  --name my-vault \
  --object-id <principal-object-id> \
  --secret-permissions get list \
  --key-permissions get unwrapKey wrapKey \
  --certificate-permissions get list

Permission Types

  • Secret: get, list, set, delete, backup, restore, recover, purge
  • Key: get, list, create, delete, encrypt, decrypt, wrapKey, unwrapKey, sign, verify
  • Certificate: get, list, create, delete, import, update, managecontacts, manageissuers

Limitations

  • Cannot restrict access to a specific secret — all-or-nothing per type.
  • No integration with Conditional Access policies.
  • Harder to audit across multiple vaults.

Azure RBAC (Recommended)

Azure RBAC uses role assignments scoped to the vault, resource group, or individual data objects.

Built-in Roles

RolePermissions
Key Vault AdministratorFull control
Key Vault Secrets OfficerCRUD on secrets
Key Vault Secrets UserRead secrets only
Key Vault Certificates OfficerCRUD on certificates
Key Vault Crypto OfficerCRUD on keys
Key Vault Crypto UserEncrypt/decrypt/sign/verify
Key Vault ReaderRead vault metadata only

Assign via CLI

# Grant read-only access to secrets
az role assignment create \
  --role "Key Vault Secrets User" \
  --assignee <principal-id> \
  --scope /subscriptions/{sub}/resourceGroups/my-rg/providers/Microsoft.KeyVault/vaults/my-vault

# Grant access to a specific secret
az role assignment create \
  --role "Key Vault Secrets User" \
  --assignee <principal-id> \
  --scope /subscriptions/{sub}/resourceGroups/my-rg/providers/Microsoft.KeyVault/vaults/my-vault/secrets/DbPassword

Enabling RBAC on a Vault

# New vault with RBAC
az keyvault create \
  --name my-vault \
  --resource-group my-rg \
  --enable-rbac-authorization true

# Convert existing vault to RBAC
az keyvault update \
  --name my-vault \
  --resource-group my-rg \
  --enable-rbac-authorization true

Warning: Enabling RBAC disables all access policies. Ensure RBAC roles are assigned before switching.


Least-Privilege Patterns

Application Pattern

# App only needs to read secrets
az role assignment create \
  --role "Key Vault Secrets User" \
  --assignee <app-managed-identity> \
  --scope /subscriptions/{sub}/resourceGroups/my-rg/providers/Microsoft.KeyVault/vaults/my-vault

DevOps Pipeline Pattern

# Pipeline needs to set secrets during deployment
az role assignment create \
  --role "Key Vault Secrets Officer" \
  --assignee <pipeline-service-principal> \
  --scope /subscriptions/{sub}/resourceGroups/my-rg/providers/Microsoft.KeyVault/vaults/my-vault

Migration from Access Policies to RBAC

Step-by-Step

  1. Audit current access policies:
az keyvault show --name my-vault --query "properties.accessPolicies"
  1. Map policies to RBAC roles:
Access Policy PermissionEquivalent RBAC Role
secrets: get, listKey Vault Secrets User
secrets: get, list, set, deleteKey Vault Secrets Officer
keys: allKey Vault Crypto Officer
certificates: allKey Vault Certificates Officer
  1. Create RBAC role assignments for each principal.

  2. Enable RBAC authorization:

az keyvault update --name my-vault --enable-rbac-authorization true
  1. Verify access — test all applications and pipelines.

Terraform Example

resource "azurerm_key_vault" "main" {
  name                       = "my-vault"
  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                   = "standard"
  enable_rbac_authorization  = true
  soft_delete_retention_days = 90
  purge_protection_enabled   = true
}

resource "azurerm_role_assignment" "app_secrets" {
  scope                = azurerm_key_vault.main.id
  role_definition_name = "Key Vault Secrets User"
  principal_id         = azurerm_linux_web_app.main.identity[0].principal_id
}

Best Practices

  1. Use Azure RBAC for all new vaults — it's the modern, recommended model.
  2. Apply least privilege — use Secrets User for apps, Secrets Officer for pipelines.
  3. Scope narrowly — assign roles at the vault level or individual secret level.
  4. Migrate existing vaults to RBAC during maintenance windows with pre-assigned roles.
  5. Enable Conditional Access for human users accessing sensitive vaults.
  6. Audit regularly with Azure Activity Log and Access Reviews.
  7. Separate vaults by environment (dev/staging/prod) with different RBAC assignments.

Summary

Azure RBAC is the recommended authorization model for Key Vault. It provides granular, auditable, and centrally managed access control. Migrate from access policies by mapping existing permissions to built-in roles, assigning them, then enabling RBAC authorization on the vault.