Quick Fix: Rotate IAM User API Access Key
Outcome
The IAM user's old API access key will be replaced with a new one. The old key is deactivated and then deleted after confirming the new key works. This limits exposure from a stale or potentially compromised credential while maintaining continuity for applications that depend on the key.
For example, after applying this fix:
- An access key for IAM user
deploy-botthat is 180 days old will be replaced with a fresh key, and the old key will be removed - An access key for IAM user
ci-runnerflagged as stale will be rotated without downtime for the CI pipeline
Fix
Rotation follows a create-update-deactivate-delete sequence so applications keep working throughout the process.
Step 1: Set the target user and identify the old access key
USER_NAME="the-user-to-rotate"
# List the user's current access keys
aws iam list-access-keys \
--user-name "${USER_NAME}" \
--output table
Identify the AccessKeyId to rotate, then set it:
OLD_ACCESS_KEY_ID="AKIA..."
Step 2: Create a new access key
aws iam create-access-key \
--user-name "${USER_NAME}"
Save the AccessKeyId and SecretAccessKey from the output in a secure location. The secret is only shown once.
NEW_ACCESS_KEY_ID="AKIA..."
At this point the user has two active access keys.
Step 3: Update applications to use the new key
Update all applications, scripts, and configurations that use the old key to use the new AccessKeyId and
SecretAccessKey. How you do this depends on where the credentials are stored (e.g. environment variables,
~/.aws/credentials, secrets manager, CI/CD configuration).
Step 4: Verify the new key is in use and the old key is not
Wait for applications to pick up the new key, then confirm the old key is no longer being used:
# Check when the old key was last used
aws iam get-access-key-last-used --access-key-id "${OLD_ACCESS_KEY_ID}"
# Check when the new key was last used
aws iam get-access-key-last-used --access-key-id "${NEW_ACCESS_KEY_ID}"
The new key should show recent usage. The old key's LastUsedDate should not advance past the time you updated
applications.
Step 5: Deactivate the old access key
Once you're confident applications are using the new key, deactivate the old one:
aws iam update-access-key \
--user-name "${USER_NAME}" \
--access-key-id "${OLD_ACCESS_KEY_ID}" \
--status Inactive
Monitor for any application failures. If something breaks, you can reactivate the old key while you fix the application:
# Reactivate if needed (rollback)
aws iam update-access-key \
--user-name "${USER_NAME}" \
--access-key-id "${OLD_ACCESS_KEY_ID}" \
--status Active
Step 6: Delete the old access key
After confirming no applications are affected by the deactivation, delete the old key permanently:
aws iam delete-access-key \
--user-name "${USER_NAME}" \
--access-key-id "${OLD_ACCESS_KEY_ID}"
Verify the fix
Confirm the user has only the new access key:
aws iam list-access-keys \
--user-name "${USER_NAME}" \
--output table
Only the new AccessKeyId should appear, with status Active.
References
- AWS: Update access keys -- the full AWS-recommended rotation procedure
- AWS: Managing access keys for IAM users
- k9 Security Kata 3: Review IAM password and access key credentials
Gotcha
Do not skip the deactivation step and jump straight to deleting the old key. Deactivation is reversible -- deletion is not. If you delete the old key and then discover an application was still using it, you cannot recover the old credentials. The safe sequence is always: create new key, update applications, deactivate old key, confirm nothing breaks, then delete the old key.
Also note that IAM users can have at most two access keys at a time. If the user already has two keys, you must deactivate and delete one before you can create a new one.