Key in non-RBAC Key Vault has expiration date set
Each enabled key in an Azure Key Vault using access policies (non-RBAC) is assessed to confirm it has an expiration (exp) attribute defined.
Risk
Non-expiring keys enable indefinite use, degrading confidentiality and integrity. Stale or compromised keys can decrypt data, forge signatures, and maintain persistence. Absent lifetimes weaken rotation discipline and impede timely revocation, increasing exposure to cryptographic and operational drift.
Run this check with Prowler
Run in Prowler Cloudprowler azure --checks keyvault_key_expiration_set_in_non_rbacRecommendation
Set an expiration on all keys and enforce automated rotation with advance alerts. Retire or disable old versions promptly and rotate after any suspected exposure. Apply least privilege and separation of duties for key administration. Prefer standardized lifecycle policies (e.g., RBAC-based governance) to enforce consistent control.
Remediation
CLI
az keyvault key set-attributes --vault-name <example_resource_name> --name <example_resource_name> --expires 2030-01-01T00:00:00ZTerraform
resource "azurerm_key_vault_key" "<example_resource_name>" {
name = "<example_resource_name>"
key_vault_id = "<example_resource_id>"
key_type = "RSA"
expires_on = "2030-01-01T00:00:00Z" # CRITICAL: sets key expiration to pass the check
}NativeIaC
// Set expiration on a Key Vault key
resource kv 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
name: '<example_resource_name>'
}
resource key 'Microsoft.KeyVault/vaults/keys@2023-07-01' = {
name: '<example_resource_name>'
parent: kv
properties: {
kty: 'RSA'
attributes: {
exp: 1893456000 // CRITICAL: sets the key expiration (Unix epoch seconds) to pass the check
}
}
}Other
Check Code
from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.keyvault.keyvault_client import keyvault_client
class keyvault_key_expiration_set_in_non_rbac(Check):
def execute(self) -> Check_Report_Azure:
findings = []
for subscription, key_vaults in keyvault_client.key_vaults.items():
subscription_name = keyvault_client.subscriptions.get(
subscription, subscription
)
for keyvault in key_vaults:
if not keyvault.properties.enable_rbac_authorization:
for key in keyvault.keys or []:
if not key.enabled:
continue
report = Check_Report_Azure(
metadata=self.metadata(), resource=key
)
report.subscription = subscription
if not key.attributes.expires:
report.status = "FAIL"
report.status_extended = f"Key {key.name} in Key Vault {keyvault.name} from subscription {subscription_name} ({subscription}) does not have an expiration date set."
else:
report.status = "PASS"
report.status_extended = f"Key {key.name} in Key Vault {keyvault.name} from subscription {subscription_name} ({subscription}) has an expiration date set."
findings.append(report)
return findings