IAM users whose access key was created more than 90 days ago
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
| Field | Value |
|---|---|
| Rule IDs | RC-082 |
| Category | compliance |
| Severity | medium |
| Metric | access key age |
| Threshold | more than 90 days |
| Evaluation window | 90d |
| Source | ZopNight |
| Permissions used | iam:ListUsers · iam:ListAccessKeys · iam:GetAccessKeyLastUsed |
Where it applies
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:
aws iam list-access-keys --user-name my-user \ --query 'AccessKeyMetadata[].[AccessKeyId,Status,CreateDate]' --output tableFor 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:
aws iam generate-credential-reportaws iam get-credential-report --query 'Content' --output text | base64 --decodeThe 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
- Create the second key:
aws iam create-access-key --user-name my-user. - 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. - Deactivate the old key and watch for errors:
aws iam update-access-key --user-name my-user \ --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive- After a quiet period, delete it with
aws iam delete-access-key. - Where possible, replace the key with a role: instance profiles, IAM Roles Anywhere or OIDC federation for CI remove the long-term key altogether.