Azure Key Vault: Purge Rights on Service Principals
Terraform or ARM templates copy an administrator access policy that grants CI/CD service principals the Purge permission on secrets, keys, or certificates. A compromised pipeline can then permanently destroy vault objects during the soft-delete window with no MFA, approval, or recovery path.
At a glance
- Unsafe setting
- Service principal access policy includes secret/key/certificate Purge permission without purge protection enforced
- Failure trigger
- Compromised or over-scoped CI/CD identity runs az keyvault secret purge or equivalent key/certificate call
- Blast radius
- Permanent, unrecoverable loss of secrets, certificates, or HSM-backed keys, potentially crypto-shredding encrypted data instantly.
- Recommended control
- Enable purge protection, strip Purge from pipeline policies, migrate to RBAC with scoped roles, gate purge behind PIM and MFA
Fix commands and configuration
az keyvault update --name <vault> --enable-purge-protection trueaz keyvault set-policy --name <vault> --spn <appId> --secret-permissions get list set delete --key-permissions get list create delete --certificate-permissions get list create delete--enable-rbac-authorization trueThe Trap
An access policy on an Azure Key Vault grants the Purge permission (secrets, keys, or certificates) to an application service principal, most commonly a CI/CD identity such as a GitHub Actions OIDC principal or a Terraform apply account.
The Default State
Terraform and ARM quickstart snippets for azurerm_key_vault frequently list secret_permissions = ["get","list","set","delete","purge"] because the example was lifted from an “administrator” policy block rather than a scoped one. Soft-delete is enabled by default in current API versions, but purge protection (enablePurgeProtection) is not enforced unless explicitly set, so the Purge permission is live and unguarded from the moment the vault is created.
The Blast Radius
A compromised or over-scoped pipeline identity can issue az keyvault secret purge or the equivalent key/certificate call and permanently remove an object during what should be its 7-to-90-day soft-delete retention window. There is no recovery, no approval gate, and no MFA check, because service principals cannot be interactively challenged. If the purged object is an HSM-backed key used for encryption at rest, the data it protected becomes unrecoverable the instant the key is gone, functionally a self-inflicted crypto-shred. Because purge protection cannot be retrofitted onto already-purged objects, this failure is discovered only after the secret, certificate, or key is unrecoverable, typically during an incident response window when the team is trying to rotate or restore exactly the material that no longer exists.
The Lead Mechanic Fix
Enable purge protection immediately: az keyvault update --name <vault> --enable-purge-protection true. Strip Purge from every service principal’s access policy: az keyvault set-policy --name <vault> --spn <appId> --secret-permissions get list set delete --key-permissions get list create delete --certificate-permissions get list create delete. Migrate the vault to RBAC authorization with --enable-rbac-authorization true and assign scoped roles like Key Vault Secrets Officer, never Key Vault Administrator, to pipeline identities. Reserve the purge action for a PIM-eligible human role requiring MFA and approval, and alert on PurgeSecret, PurgeKey, and PurgeCertificate entries in the AuditEvent diagnostic category.