Microsoft Defender for Cloud · Key Vault
Key Vault secrets should have an expiration date
Written and reviewed by Emnode · Last reviewed
What does the recommendation "Key Vault secrets should have an expiration date" check?
Flags any secret in a standard Key Vault whose 'expires' attribute is unset, meaning the secret is valid forever by default. It evaluates each secret object individually using the Microsoft.KeyVault.Data policy mode, so a vault is non-compliant the moment one secret lacks an expiry. It does not check keys or certificates, which have their own separate expiration recommendations, and it does not cover Managed HSM. It also does not verify that an expiry date is sensible or that the secret is actually rotated before that date arrives: it only confirms a date exists, so a secret set to expire ten years out passes just as cleanly as one rotated quarterly.
Why does "Key Vault secrets should have an expiration date" matter?
Secrets stored in Key Vault are connection strings, API keys and passwords that grant standing access to databases, storage and third-party services. A secret with no expiry can sit unrotated for years, so a value leaked through a log, a stale backup or a departed contractor stays live indefinitely and the blast radius of any single compromise keeps growing. An expiry date forces a rotation conversation on a known schedule, caps how long a stolen credential is useful, and gives monitoring a concrete signal to alert on as the date approaches. Without one, you have no automated way to tell a healthy credential apart from an abandoned one, and audit reviewers cannot prove that long-lived secrets are under any rotation discipline at all.
How do I fix "Key Vault secrets should have an expiration date"?
- Set an expiration on existing secrets: az keyvault secret set-attributes --vault-name <vault> --name <secret> --expires 2027-06-17T00:00:00Z. When you create or update a secret, pass --expires (or the expires attribute in Bicep) so the date is part of the value's lifecycle from the start.
- Pair the expiry with rotation so the secret is replaced before it lapses: use Event Grid 'near expiry' notifications on the vault, or automatic rotation where the upstream service supports it, to avoid an outage when the date hits.
- Assign the built-in audit policy by display name so you do not hardcode a GUID, then enforce it on new secrets: pid=$(az policy definition list --query "[?displayName=='Key Vault secrets should have an expiration date'].name" -o tsv); az policy assignment create --name kv-secret-expiry --policy "$pid" --scope <scope>.
Remediation script · bash
# Enable purge protection on every vault that lacks it. Note: this CANNOT be undone.
for kv in $(az keyvault list \
--query "[?properties.enablePurgeProtection==null].name" -o tsv); do
az keyvault update --name "$kv" --enable-purge-protection true
echo "$kv: purge protection enabled (irreversible)"
done
# Give a key an expiration date and a rotation policy so it rotates before it lapses.
az keyvault key set-attributes --vault-name kv-payments-prod \
--name db-encryption-key --expires "$(date -u -d '+1 year' +%Y-%m-%dT%H:%M:%SZ)"
az keyvault key rotation-policy update --vault-name kv-payments-prod \
--name db-encryption-key --value @rotation-policy.json
# Ratchet it shut: deny any future vault created without deletion protection.
az policy assignment create \
--name deny-kv-no-purge \
--policy 0b60c0b2-2dc2-4e1c-b5c9-abbed971de53 \
--scope "/subscriptions/00000000-0000-0000-0000-000000000000" Full walkthrough (console steps, edge cases and verification) in the lesson Harden Key Vault data protection.
Is "Key Vault secrets should have an expiration date" a false positive?
A vault holding a long-lived value that genuinely cannot expire, for example a third-party licence key the vendor issues without an end date, will flag because the control demands a date on every secret. Rather than leave it permanent, set --expires to a far-future review date that triggers a deliberate human check, or scope the policy assignment to exclude that one resource so the exception is recorded and intentional instead of an oversight.
More Key Vault controls
- Azure Key Vault should have firewall enabled or public network access disabled
- Azure Key Vaults should use private link
- Key Vault keys should have an expiration date
- Key vaults should have purge protection enabled
- Key vaults should have soft delete enabled
- Role-Based Access Control should be used on Keyvault Services
- Validity period of certificates stored in Azure Key Vault should not exceed 12 months