Back to Checks
aws

Secrets Manager secret has been accessed within the last 90 days

secretsmanager_secret_unused
Service: secretsmanagerSeverity: medium
OfficialBuilt-inVerified
Categories:secrets
Resource Type:AwsSecretsManagerSecret

AWS Secrets Manager secrets with no retrieval activity beyond a configured window (default 90 days) are identified as unused based on their most recent access timestamp

Risk

Unused yet valid secrets jeopardize confidentiality and integrity:

  • Reuse by ex-users or leaked code enables unauthorized access
  • Limited rotation/revocation increases stealth persistence and data exfiltration
  • Secret sprawl adds operational risk and extra cost

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks secretsmanager_secret_unused

Recommendation

Apply a lifecycle policy for secrets:

  • Require ownership tags and periodic reviews
  • Rotate or disable, then retire secrets unused beyond policy
  • Enforce least privilege and monitor retrievals with alerts
  • Automate cleanup using recovery windows to prevent accidental loss

Remediation

CLI

aws secretsmanager delete-secret --secret-id <example_resource_id>

Other

1In the AWS Console, go to Secrets Manager
2Select the unused secret
3If the secret has replicas: in Replicate secret, select each replica and choose Actions > Delete replica
4Choose Actions > Delete secret
5Keep the default recovery window (or set one) and select Schedule deletion

Check Code

from datetime import datetime, timedelta, timezone

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.secretsmanager.secretsmanager_client import (
    secretsmanager_client,
)


class secretsmanager_secret_unused(Check):
    def execute(self):
        findings = []
        for secret in secretsmanager_client.secrets.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=secret)
            report.status = "PASS"
            report.status_extended = f"Secret {secret.name} has been accessed recently, last accessed on {secret.last_accessed_date.strftime('%B %d, %Y')}."

            if (datetime.now(timezone.utc) - secret.last_accessed_date) > timedelta(
                days=secretsmanager_client.audit_config.get(
                    "max_days_secret_unused", 90
                )
            ):
                report.status = "FAIL"
                if secret.last_accessed_date == datetime.min.replace(
                    tzinfo=timezone.utc
                ):
                    report.status_extended = (
                        f"Secret {secret.name} has never been accessed."
                    )
                else:
                    report.status_extended = f"Secret {secret.name} has not been accessed since {secret.last_accessed_date.strftime('%B %d, %Y')}, you should review if it is still needed."

            findings.append(report)

        return findings