Skip to content

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-bot that 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-runner flagged 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

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.


Last update: February 5, 2026