Skip to content
AWSIAM user access key

How to rotate AWS access keys without downtime

Reissue an IAM user's access key with AWS's two-key overlap: create the second key, switch every program, check last use, deactivate, then delete the old one.

AWSIAM user access key

Starts with: AKIA…
Where to issue a new one
console.aws.amazon.com/iam
What a leaked key reaches
Whatever the IAM user's policies allow in the AWS account, for as long as the key stays active. Both keys of a user carry the same rights.
Can be scoped
Partly

Some key types can be limited, others carry full rights.

Expires
None: a long-term credential until you deactivate or delete it
Switching keys
Overlap windowDelayed revocation

The old key keeps working for a while after you revoke it.

What Crunu does here

Crunu doesn't reissue keys at providers. It shows which values to replace and keeps the new one.

Build the list for a departure with the offboarding checklist
On this page

Create a second access key for the same IAM user while the first one is still active, move every program to it, check when the old key was last used, deactivate it, and delete it only after nothing has complained for a while. IAM allows two access keys per user, which is exactly the room this needs, and a deactivated key can be switched back on if you missed a consumer (AWS IAM User Guide). Done in this order, nothing goes down.

Crunu can't create, deactivate or delete AWS keys: it has no AWS integration. Its part is knowing which AWS values a person or a leak exposed, holding the new key pair as a new environment version, and restarting what reads it.

An access key is two values

An access key has an access key ID, such as AKIAIOSFODNN7EXAMPLE, and a secret access key. Requests need both together, and AWS shows the secret only once, at creation (AWS docs). So a reissue always changes two values at once: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in an env file, or the aws_access_key_id and aws_secret_access_key fields of a profile in ~/.aws/credentials.

A few limits shape the procedure:

  • Two keys per user, no more. If the user already has two, one of them probably sits unused. Delete that pair first, or there is no slot for the replacement.
  • No expiry. Access keys are long-term credentials. The only end date is the one you give them by deactivating or deleting.
  • The rights belong to the user. A key can do whatever the IAM user's policies allow. You can't give one of the two keys narrower rights than the other.

AWS itself recommends temporary credentials, such as IAM roles, over access keys, and warns never to create access keys for the root user. If a reissue is the moment to move a workload off long-term keys, take it.

Reissue without downtime

  1. In the IAM console, open Users, the user, then Security credentials, and choose Create access key. On the page about best practices and alternatives choose Other. Save the secret with Show or Download .csv file: this is the only chance.
  2. In Crunu, open the environment that holds the pair, for example data-pipeline / production, replace both values and save. The environment now has a new version, and its history names the changed fields without their values.
  3. Bring every consumer onto the new pair. Programs started with crunu run --restart on-change restart when the version changes. Where a program reads ~/.aws/credentials, run crunu pull on that machine to rewrite the file, then restart the program.
  4. Check that the old key has gone quiet. The Last used information in the console, or aws iam get-access-key-last-used, shows its most recent use. AWS suggests waiting several days before you go on.
  5. Deactivate the old key, not delete it. Watch the programs that use the new pair. If something fails, set the old key back to Active, fix that consumer and repeat. Delete the old key once you're confident.

The same sequence from the AWS CLI, with the old key ID in place of the example:

Shell
aws iam create-access-key --user-name etl-worker
aws iam get-access-key-last-used --access-key-id AKIAIOSFODNN7EXAMPLE
aws iam update-access-key --user-name etl-worker --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive
aws iam delete-access-key --user-name etl-worker --access-key-id AKIAIOSFODNN7EXAMPLE

IAM is eventually consistent: AWS notes that changes take time to become visible from every endpoint (AWS troubleshooting). Expect a short lag between deactivating a key and the last request with it failing, and don't build a deploy step that depends on the change being instant.

When to reissue an AWS key

AWS lists an employee leaving the company as a reason to update access keys. Two other triggers are just as common.

  • A departure. Anyone who could read the pair could still sign requests with it. Removing the person in Crunu shows whether they received a version containing the current values, and the reissue checklist lists ~/.aws/credentials or the variables by name.
  • A leak. Shorten every wait above. Create the new key, deploy it, deactivate the old one within the hour, and use CloudTrail, which AWS recommends for monitoring key usage, to look for calls you didn't make. Deactivating the key doesn't end temporary credentials someone already obtained with it: AWS says they stay valid until they expire, up to 36 hours, unless you also change the user's permissions (AWS docs).
  • Age. The Access key age column in the IAM users list shows how many days ago a user's oldest active key was created. Old keys are the ones most likely to have been copied somewhere you forgot.

The wider order of work for a departure is in What to rotate when a developer leaves, and the offboarding checklist turns it into a list for your stack.

Files on disk and keys in memory

AWS warns that the shared credentials file stores keys in plaintext. If a machine needs that file, crunu pull writes it with mode 0600 and keeps the previous version next to it as .prev, so the old pair stays on that disk until the next pull. One more reason the old key has to be deactivated at AWS. Programs that can read variables instead are better served by crunu run, which passes the pair through the process environment and writes nothing to disk:

Shell
crunu run --env data-pipeline/production --restart on-change -- /opt/etl/bin/worker

Either way, the AWS side of the reissue stays in the IAM console or CLI. Crunu records who saved the new pair and when, and the old pair remains readable in the environment's history until it is pushed out by newer versions, so the provider step is what actually ends its use.

Frequently asked questions

Something else? Write to support@crunu.com

How many access keys can one IAM user have?

Two. That is exactly the room a rotation needs: the old key keeps working while you create and roll out the new one. If both slots are taken, for example by a forgotten inactive key, delete one pair before you create another.

Should I delete the old AWS key or deactivate it first?

Deactivate it first. AWS recommends this even when Last used shows no activity. A deactivated key can be switched back to Active if a program you missed starts failing. Delete it only after a quiet period.

Do AWS access keys expire on their own?

No. Access keys are long-term credentials and stay valid until you deactivate or delete them. AWS recommends temporary credentials, such as IAM roles, wherever a workload can use them.

Can Crunu create or deactivate AWS access keys?

No. Crunu has no AWS integration and never calls IAM. It lists the AWS values a departing person received, stores the new key pair as a new environment version, and can restart the programs that use it.

Sources

Every source this page relies on, with the date we last checked it.

  1. AWS IAM User Guide: Update access keys · checked October 30, 2026
  2. AWS IAM User Guide: Manage access keys for IAM users · checked October 30, 2026
  3. AWS IAM User Guide: Disabling permissions for temporary security credentials · checked October 30, 2026
  4. AWS IAM User Guide: Troubleshoot IAM · checked October 30, 2026
  • Bitbucket

    API token with scopes

    Expiry: 1 to 365 days; one year by default

    Scoped keys

  • Cloudflare

    API token

    Expiry: Optional TTL chosen when the token is created

    cfut_…Scoped keys

  • DigitalOcean

    Personal access token

    Expiry: Chosen at creation; an expired token disappears from the account

    dop_v1_…Scoped keys

  • Docker

    Personal access token

    Expiry: None by default; 30 or 90 days, or a custom date up to a year ahead

    dckr_pat_…Partly scoped

  • GitHub

    Fine-grained personal access token

    Expiry: Set at creation; no expiry is allowed unless an org lifetime policy blocks it

    github_pat_…Scoped keys

  • GitLab

    Personal, project or group access token

    Expiry: Required by default, at most 365 days unless an admin changes the limit

    glpat-…Scoped keys

Know which values to replace

Free during early access. When someone leaves, Crunu lists the values they received, changes the environment keys, and keeps each new value as a new version.