Skip to main content
compliance · aws

IAM users whose access key was created more than 90 days ago

resource types
1
rule IDs covered
1
severity
medium

What does ZopNight detect here?

ZopNight flags an IAM user whose oldest active access key is more than 90 days old, measured from the key creation date AWS reports in `ListAccessKeys`. Long-lived keys are the main standing credential in most AWS accounts, and rotating them limits how long a leaked key stays useful. The finding carries a $0 saving.

Signal and threshold

How ZopNight evaluates IAM users whose access key was created more than 90 days ago.
Field Value
Rule IDsRC-082
Categorycompliance
Severitymedium
Metricaccess key age
Thresholdmore than 90 days
Evaluation window90d
SourceZopNight
Permissions usediam:ListUsers · iam:ListAccessKeys · iam:GetAccessKeyLastUsed

Why key age matters more than key use

An IAM access key is a long-term credential: it works until someone deactivates or deletes it. Keys end up in CI variables, laptops, container images and old scripts, and every copy is a place it can leak from. The longer a key lives, the more copies exist and the less anyone remembers where they are.

AWS itself flags the category: IAM users with access keys are an account security risk, and each user can have a maximum of two access keys, which is exactly what makes zero-downtime rotation possible.

Finding old keys across the account

For one user:

Terminal window
aws iam list-access-keys --user-name my-user \
--query 'AccessKeyMetadata[].[AccessKeyId,Status,CreateDate]' --output table

For the whole account, the credential report is faster. It can be generated at most once every four hours, and its access_key_1_last_rotated and access_key_2_last_rotated columns record when each key was created or last changed:

Terminal window
aws iam generate-credential-report
aws iam get-credential-report --query 'Content' --output text | base64 --decode

The 90-day line

ZopNight records the age in days of each user’s oldest active access key during discovery and fires when that age is strictly greater than 90. A key created exactly 90 days ago does not trigger it; one created 91 days ago does.

Users the check currently skips

Only active keys count. A user whose keys are all set to Inactive has no age on record, because those keys are already out of use, so the rule stays silent for that user; delete such keys when you are sure nothing needs them. A user holding two active keys is judged by the older one. Users with no access keys are never flagged, and when the age is missing or not a number, no finding is produced.

The value is a shorter exposure window

The finding carries a $0 saving. What rotation buys is a hard cap on how long a copied key keeps working.

Rotating a key without breaking anything

  1. Create the second key: aws iam create-access-key --user-name my-user.
  2. Update every application, pipeline and script that uses the old key, then confirm with aws iam get-access-key-last-used --access-key-id AKIA... that the old key has stopped being used.
  3. Deactivate the old key and watch for errors:
Terminal window
aws iam update-access-key --user-name my-user \
--access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive
  1. After a quiet period, delete it with aws iam delete-access-key.
  2. Where possible, replace the key with a role: instance profiles, IAM Roles Anywhere or OIDC federation for CI remove the long-term key altogether.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

472 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

472 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·