Back to Checks
azure

Secret in RBAC-enabled Key Vault has expiration date set

keyvault_rbac_secret_expiration_set
Service: keyvaultSeverity: medium
OfficialBuilt-inVerified
Categories:secrets
Resource Type:microsoft.keyvault/vaults/secrets

Each enabled secret in an Azure Key Vault (RBAC) is assessed to confirm it has an exp (expiration) date configured.

Risk

Without an expiration, secrets become perpetual credentials. Leaked or abandoned values can grant persistent access, undermining confidentiality and integrity. Attackers can reuse old secrets to maintain footholds, perform unauthorized API calls, and exfiltrate data.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks keyvault_rbac_secret_expiration_set

Recommendation

Set an expiration on all enabled secrets and enforce a regular rotation policy.

Prefer short-lived, identity-based access to reduce secret usage. Apply least privilege for secret access, alert on upcoming expirations, and automate rotation and version cleanup to minimize exposure.

Remediation

CLI

az keyvault secret set-attributes --vault-name <vaultName> --name <secretName> --expires <YYYY-MM-DDTHH:MM:SSZ>

Terraform

resource "azurerm_key_vault_secret" "<example_resource_name>" {
  name         = "<example_resource_name>"
  value        = "<secret_value>"
  key_vault_id = "<example_resource_id>"

  # CRITICAL: sets the secret expiration timestamp
  expiration_date = "2025-01-01T00:00:00Z"
}

NativeIaC

// Set expiration on a Key Vault secret
resource secret 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = {
  name: '<example_resource_name>/<example_resource_name>'
  properties: {
    // CRITICAL: sets the secret expiration timestamp (Unix epoch seconds)
    attributes: {
      exp: 1735689600 // 2025-01-01T00:00:00Z
    }
    value: '<secret_value>'
  }
}

Other

1In Azure Portal, go to Key vaults and open your vault
2Select Secrets, choose the secret, then open its Current version
3Set Expiration date (UTC) and click Save

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_rbac_secret_expiration_set(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 keyvault.properties.enable_rbac_authorization:
                    for secret in keyvault.secrets or []:
                        if not secret.enabled:
                            continue
                        report = Check_Report_Azure(
                            metadata=self.metadata(), resource=secret
                        )
                        report.subscription = subscription
                        if not secret.attributes.expires:
                            report.status = "FAIL"
                            report.status_extended = f"Secret {secret.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"Secret {secret.name} in Key Vault {keyvault.name} from subscription {subscription_name} ({subscription}) has an expiration date set."
                        findings.append(report)
        return findings