Skip to content

Policy Migration: Vault Policies to Azure RBAC and Azure Policy

Status: Authored 2026-04-30 Audience: Security Engineers, IAM Architects, Platform Engineers Purpose: Guide for migrating HashiCorp Vault ACL policies and Sentinel policies to Azure RBAC role assignments, Entra ID groups, PIM just-in-time access, and Azure Policy for Key Vault governance


Overview

HashiCorp Vault uses a path-based ACL policy model. Policies define capabilities (create, read, update, delete, list, sudo, deny) on specific paths within Vault. Vault Enterprise adds Sentinel policies for policy-as-code enforcement with business logic beyond simple ACLs.

Azure Key Vault uses Azure RBAC for authorization. Built-in roles (Key Vault Secrets User, Key Vault Crypto Officer, etc.) are assigned to Entra ID principals at specific scopes. Azure Policy provides governance guardrails (equivalent to Vault Sentinel) for enforcing organizational standards on Key Vault configuration.

This guide maps Vault policy patterns to Azure RBAC assignments and Azure Policy definitions.


1. Vault policy model vs Azure RBAC

Vault: path-based capabilities

# Vault policy: read secrets for app1 in production
path "secret/data/app1/prod/*" {
  capabilities = ["read", "list"]
}

# Deny access to admin secrets
path "secret/data/admin/*" {
  capabilities = ["deny"]
}

# Full access to app1 KV engine
path "secret/data/app1/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}
path "secret/metadata/app1/*" {
  capabilities = ["read", "list", "delete"]
}

Azure RBAC: role-based, scope-based

# Equivalent: read secrets in a specific Key Vault
az role assignment create \
  --role "Key Vault Secrets User" \
  --assignee-object-id <principal-id> \
  --scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/kv-app1-prod

# Equivalent: full access to secrets in a Key Vault
az role assignment create \
  --role "Key Vault Secrets Officer" \
  --assignee-object-id <principal-id> \
  --scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/kv-app1-prod

Key architectural difference

Vault uses a single cluster with path isolation. Multiple applications share one Vault instance, and policies separate access by path prefix.

Azure Key Vault uses separate vault instances for isolation. Each application or team gets its own Key Vault, and RBAC roles control access at the vault level. This is a stronger isolation model -- compromising one vault's RBAC does not expose another vault's secrets.


2. Policy mapping reference

Common Vault policies mapped to Azure RBAC

Vault policy pattern Azure RBAC role Scope Notes
path "secret/data/*" { capabilities = ["read"] } Key Vault Secrets User Key Vault instance Read secret values
path "secret/data/*" { capabilities = ["read", "list"] } Key Vault Secrets User + Key Vault Reader Key Vault instance Read values + list metadata
path "secret/data/*" { capabilities = ["create", "read", "update", "delete", "list"] } Key Vault Secrets Officer Key Vault instance Full CRUD on secrets
path "transit/encrypt/*" { capabilities = ["update"] } Key Vault Crypto User Key Vault instance (keys vault) Encrypt/decrypt operations
path "transit/*" { capabilities = ["create", "read", "update", "delete", "list"] } Key Vault Crypto Officer Key Vault instance (keys vault) Full key management
path "pki/issue/*" { capabilities = ["update"] } Key Vault Certificates Officer Key Vault instance Certificate issuance
path "sys/*" { capabilities = ["read", "list"] } Key Vault Reader Key Vault instance Read metadata only
path "sys/*" { capabilities = ["sudo"] } Key Vault Administrator Key Vault instance Full vault management
path "auth/*" { capabilities = ["create", "read", "update", "delete", "list", "sudo"] } N/A (Entra ID admin) Entra ID Auth config is in Entra ID, not Key Vault
Deny policy on specific path Remove role assignment; or use deny assignment (Azure Blueprints) Specific scope Azure RBAC is deny-by-default

Built-in Key Vault RBAC roles

Role Description Secret perms Key perms Cert perms
Key Vault Administrator Full management All All All
Key Vault Reader Read metadata (no values) List, metadata List, metadata List, metadata
Key Vault Secrets Officer Manage secrets All None None
Key Vault Secrets User Read secret values Get, List None None
Key Vault Crypto Officer Manage keys None All None
Key Vault Crypto User Use keys for crypto ops None Encrypt, Decrypt, Sign, Verify, Wrap, Unwrap None
Key Vault Crypto Service Encryption User Wrap/Unwrap only (for service encryption) None Wrap, Unwrap None
Key Vault Certificates Officer Manage certificates None None All

3. Entra ID groups for policy organization

Vault: entity groups

Vault uses entities and identity groups to organize policy assignments:

# Create identity group and assign policy
vault write identity/group name="app1-team" policies="app1-prod-read"
vault write identity/group/name/app1-team member_entity_ids="entity-id-1,entity-id-2"

Azure: Entra ID security groups

# Create Entra ID security group
az ad group create \
  --display-name "KV-App1-Prod-Readers" \
  --mail-nickname "kv-app1-prod-readers" \
  --description "Read access to app1 production Key Vault secrets"

# Add members
az ad group member add \
  --group "KV-App1-Prod-Readers" \
  --member-id <user-or-sp-object-id>

# Assign RBAC role to the group
az role assignment create \
  --role "Key Vault Secrets User" \
  --assignee-object-id $(az ad group show -g "KV-App1-Prod-Readers" --query id -o tsv) \
  --assignee-principal-type Group \
  --scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/kv-app1-prod
KV-{Application}-{Environment}-{Role}

Examples:
  KV-WebApp-Prod-SecretsUser       (read secrets)
  KV-WebApp-Prod-SecretsOfficer    (manage secrets)
  KV-Platform-Prod-CryptoOfficer   (manage encryption keys)
  KV-PKI-Prod-CertsOfficer         (manage certificates)
  KV-All-Prod-Admins               (full admin, break-glass only)

4. PIM for just-in-time access

Vault: response wrapping and short-lived tokens

Vault provides just-in-time access through:

  • Short-lived tokens with configurable TTL
  • Response wrapping (single-use wrapped tokens)
  • Auth method configurations with max TTL

Azure: Privileged Identity Management (PIM)

PIM provides a formal just-in-time (JIT) access workflow:

sequenceDiagram
    participant User as Security Engineer
    participant PIM as Entra PIM
    participant Approver as Approval Workflow
    participant KV as Key Vault

    User->>PIM: Request "Key Vault Secrets Officer" activation
    PIM->>PIM: Check eligibility assignment
    PIM->>Approver: Send approval request
    Approver->>PIM: Approve (with justification)
    PIM->>PIM: Activate role (time-limited, 1-8 hours)
    PIM-->>User: Role active until expiration
    User->>KV: Access secrets (elevated role)
    Note over PIM: After time limit...
    PIM->>PIM: Auto-deactivate role
    Note over User: Access revoked automatically

Configure PIM for Key Vault roles

# Make Key Vault Secrets Officer eligible (not permanently assigned)
# This is configured in the Azure portal or via Microsoft Graph API

# Microsoft Graph API example:
# POST /roleManagement/directory/roleEligibilityScheduleRequests
# {
#   "action": "AdminAssign",
#   "justification": "Eligible for JIT Key Vault admin access",
#   "roleDefinitionId": "<Key Vault Secrets Officer role ID>",
#   "directoryScopeId": "/subscriptions/.../providers/Microsoft.KeyVault/vaults/kv-prod",
#   "principalId": "<user-or-group-id>",
#   "scheduleInfo": {
#     "startDateTime": "2026-01-01T00:00:00Z",
#     "expiration": {
#       "type": "noExpiration"
#     }
#   }
# }

PIM configuration recommendations

Setting Recommended value Rationale
Maximum activation duration 4 hours (8 hours for complex operations) Limits exposure window
Require justification Yes Audit trail for access requests
Require approval Yes (for Officer/Admin roles) Peer review for elevated access
Require MFA Yes Prevent credential-based elevation
Send notification on activation Yes (to security team) Real-time awareness of elevated access
Eligible assignment expiration 6 months (renewable) Forces periodic review of eligibility

5. Azure Policy for Key Vault governance

Vault: Sentinel policies (Enterprise)

Vault Enterprise Sentinel policies enforce business logic:

# Vault Sentinel policy: enforce minimum secret TTL
import "time"
import "strings"

precond = rule {
    request.operation in ["create", "update"] and
    strings.has_prefix(request.path, "secret/data/")
}

main = rule when precond {
    # Require secret TTL of at least 24 hours
    request.data.ttl >= time.hour * 24
}

Azure Policy: built-in and custom policies

Azure Policy provides equivalent governance. Azure includes built-in Key Vault policies and supports custom policy definitions.

Built-in Key Vault policies

Policy Description Vault Sentinel equivalent
Key Vault should use private endpoint Enforces private endpoint connectivity Network restriction policies
Key Vault keys should have expiration date All keys must have expiry set TTL enforcement
Key Vault secrets should have expiration date All secrets must have expiry set TTL enforcement
Key Vault should have soft-delete enabled Prevents accidental permanent deletion Data protection policy
Key Vault should have purge protection enabled Prevents purge during retention Data protection policy
Keys should be backed by HSM Enforce HSM backing for all keys Key protection policy
Keys using RSA should have minimum key size Enforce minimum 2048-bit RSA Key strength policy
Certificates should have specified lifetime action triggers Enforce auto-renewal Certificate management policy

Assign built-in policies

# Require secrets to have expiration dates
az policy assignment create \
  --name "kv-secrets-expiry" \
  --display-name "Key Vault secrets must have expiration dates" \
  --policy "/providers/Microsoft.Authorization/policyDefinitions/98728c90-32c7-4049-8429-847dc0f4fe37" \
  --scope /subscriptions/<sub-id> \
  --enforcement-mode Default

# Require Key Vault to use private endpoints
az policy assignment create \
  --name "kv-private-endpoint" \
  --display-name "Key Vault must use private endpoint" \
  --policy "/providers/Microsoft.Authorization/policyDefinitions/a6abeaec-4d90-4a02-805f-6b26c4d3fbe9" \
  --scope /subscriptions/<sub-id>

# Require HSM backing for keys
az policy assignment create \
  --name "kv-keys-hsm" \
  --display-name "Key Vault keys must use HSM" \
  --policy "/providers/Microsoft.Authorization/policyDefinitions/587c79fe-dd04-4a5e-9d0b-f89598c7261b" \
  --scope /subscriptions/<sub-id>

Custom policy: enforce minimum secret expiration

{
    "mode": "Microsoft.KeyVault.Data",
    "policyRule": {
        "if": {
            "allOf": [
                {
                    "field": "type",
                    "equals": "Microsoft.KeyVault.Data/vaults/secrets"
                },
                {
                    "anyOf": [
                        {
                            "field": "Microsoft.KeyVault.Data/vaults/secrets/attributes.expiresOn",
                            "exists": false
                        },
                        {
                            "field": "Microsoft.KeyVault.Data/vaults/secrets/attributes.expiresOn",
                            "greater": "[addDays(utcNow(), 365)]"
                        }
                    ]
                }
            ]
        },
        "then": {
            "effect": "deny"
        }
    }
}

Custom policy: enforce naming convention

{
    "mode": "Microsoft.KeyVault.Data",
    "policyRule": {
        "if": {
            "allOf": [
                {
                    "field": "type",
                    "equals": "Microsoft.KeyVault.Data/vaults/secrets"
                },
                {
                    "not": {
                        "field": "name",
                        "match": "??*-??*-*"
                    }
                }
            ]
        },
        "then": {
            "effect": "deny"
        }
    }
}

6. Conditional Access for Key Vault

Entra ID Conditional Access provides context-aware access control that Vault does not natively support:

Example: require MFA and compliant device for Key Vault admin access

{
    "displayName": "Key Vault Admin - Require MFA + Compliant Device",
    "conditions": {
        "applications": {
            "includeApplications": ["cfa8b339-82a2-471a-a3c9-0fc0be7a4093"]
        },
        "users": {
            "includeGroups": ["<KV-Admins-Group-ID>"]
        }
    },
    "grantControls": {
        "operator": "AND",
        "builtInControls": ["mfa", "compliantDevice"]
    }
}

Example: block Key Vault access from untrusted locations

{
    "displayName": "Key Vault - Block untrusted locations",
    "conditions": {
        "applications": {
            "includeApplications": ["cfa8b339-82a2-471a-a3c9-0fc0be7a4093"]
        },
        "locations": {
            "includeLocations": ["All"],
            "excludeLocations": ["<trusted-locations-id>"]
        }
    },
    "grantControls": {
        "operator": "OR",
        "builtInControls": ["block"]
    }
}

7. Policy migration checklist

For each Vault policy, complete these steps:

  • Identify the Vault policy paths and capabilities
  • Map to the appropriate Key Vault RBAC role (see mapping table)
  • Determine the scope: specific vault, resource group, or subscription
  • Create Entra ID security group for the policy assignment
  • Assign RBAC role to the group at the appropriate scope
  • Configure PIM for privileged roles (Officer, Admin)
  • Validate access: principals can access what they need and cannot access what they should not
  • Deploy Azure Policy for governance guardrails
  • Configure Conditional Access for administrative roles
  • Document the mapping in the migration inventory

Post-migration governance validation

  • All Key Vault instances have RBAC authorization enabled (not legacy access policies)
  • No permanent assignments for privileged roles (use PIM eligible assignments)
  • Azure Policy compliance reports show no violations
  • Conditional Access policies are active for Key Vault admin access
  • Diagnostic logging captures all access events
  • Break-glass procedures are documented and tested


Maintainers: csa-inabox core team Last updated: 2026-04-30