Active IAM access keys past the 90-day rotation mark
What does ZopNight detect here?
IAM users carrying an active access key older than 90 days are flagged for rotation by ZopNight rule RC-082. Age is measured from the oldest active key's CreateDate, stamped at discovery. Users whose keys are all inactive produce no age signal, so the rule abstains instead of inventing one.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-082 |
| Category | compliance |
| Severity | medium |
| Metric | none — pure configuration read |
| Source | iam_unused_key.go |
Where it applies
Where the 90-day clock starts
The clock starts at the key’s CreateDate and never resets. An access key is a static
credential: unlike a session token it does not expire on its own, so any copy that ever
leaked (into a laptop backup, a CI log, a git history) stays valid until the key is
rotated. The 90-day bar comes from NIST and AWS rotation guidance, and the rule fires only
when the age is strictly greater than 90, so a key rotated on schedule never trips it.
Note what is being measured: creation age, not last use. A key used every hour and a key untouched for months both fire at day 91, because exposure risk accrues with age either way.
The oldest active key sets the age
AWS allows a user up to 2 access keys precisely so rotation can overlap: create the new key, migrate consumers, retire the old one. During that overlap ZopNight scores the user by the oldest key that is still marked Active, which is the honest reading: an old key kept active mid-rotation is still a live credential.
Users whose keys are all Inactive get no age stamped at discovery, and the rule abstains for them rather than fabricating a number. Deactivated keys cannot authenticate, so there is nothing left to rotate.
Listing key ages per user
aws iam list-access-keys --user-name alice \ --query 'AccessKeyMetadata[?Status==`Active`].[AccessKeyId,CreateDate]' \ --output tableAnything with a CreateDate more than 90 days back is what the finding is pointing at.
A key rotation nothing notices
The two-key allowance is the whole playbook. Create the second key, update every application, script and CI/CD pipeline that used the old one, and verify traffic on the new key. Then deactivate the old key, do not delete it, and watch for authentication errors; deactivation is reversible in seconds, deletion is not. Only after a quiet interval delete it for good. Done in that order, rotation is invisible to everything that depends on the user.