Skip to main content

Three Ways to Stop Using Long-Term AWS Credentials

A long-term access key is like a password on a sticky note. Whoever finds it gets the permissions attached to it, with no second factor and no automatic expiry. A leaked key can sit unused for six months; by then, you may not even remember where you exposed it. I have seen that happen. Three safer options avoid this risk, and you can start with one in a couple of minutes.

Static Keys Keep Working Until You Delete Them
#

An access key ID and secret access key form a single permanent credential. AWS does not rotate it for you or ask for a second factor when software uses it. The key also works from any machine with internet access.

The permissions often make matters worse. I regularly find old IAM users with AdministratorAccess because someone needed to get a project working and planned to reduce the permissions later. If that key ends up in a committed file, a Docker layer, a backup, or a compromised laptop, whoever finds it keeps the same access until you revoke it.

AWS addresses this directly in the Well-Architected security practice SEC02-BP02: Use temporary credentials. Temporary credentials have an expiry time, so a forgotten copy cannot remain useful for years.

The right way to obtain those credentials depends on who needs them. For your own terminal, start with IAM Identity Center. If your personal account still uses an IAM user, aws login provides a useful fallback. Your deployment pipeline can assume a role through OIDC.

Start With IAM Identity Center for Your Own Access
#

AWS IAM Identity Center, previously called AWS SSO, is the cleanest choice for regular access. You sign in through the browser and choose an AWS account and permission set. The AWS CLI then obtains temporary credentials when it needs them.

Identity Center becomes especially useful once your personal setup has more than one account. A small AWS Organization with a management account and a workload account is enough to benefit from one login and centrally managed permission sets.

Configure Your CLI Profile Once
#

Run the interactive setup:

aws configure sso

The CLI asks for your Identity Center start URL and AWS Region, then opens a browser for authentication. After you choose an account and permission set, it creates a named profile in ~/.aws/config:

[profile dev-identity-center]
sso_session = my-sso
sso_account_id = 123456789012
sso_role_name = PowerUserAccess
region = eu-west-1

[sso-session my-sso]
sso_start_url = https://my-org.awsapps.com/start
sso_region = eu-west-1
sso_registration_scopes = sso:account:access

This sso-session configuration lets compatible AWS tools refresh authentication automatically during the configured session. The AWS CLI setup guide explains each field and also covers environments where you cannot open a browser directly.

Sign In Before You Start Work
#

Use the profile like any other AWS CLI profile:

aws sso login --profile dev-identity-center
aws sts get-caller-identity --profile dev-identity-center
aws s3 ls --profile dev-identity-center

A permission set can have a session duration from 1 to 12 hours. Match that duration to the access it grants. One hour may suit an administrator permission set, while a longer session can be reasonable for limited development access. When the session ends, run aws sso login again.

Your local cache still deserves the same protection as the rest of your user account, but there is no static IAM access key to rotate or forget.

Use aws login When You Still Have an IAM User
#

Identity Center may not be in place yet. Perhaps you have one personal AWS account and still sign in to the console with an IAM user. This is where a lesser-known AWS CLI v2 feature helps.

The aws login command uses your existing console sign-in to set up temporary credentials for local development. It gives you a safer path away from IAM access keys without first changing how the whole account is organized.

Turn Your Console Sign-In Into a CLI Session
#

Start a named session from the terminal:

aws login --profile dev-iam-user

The CLI asks for an AWS Region when the profile is new, then opens the AWS sign-in page in your browser. After you authenticate and choose the session, check which identity the profile uses:

aws sts get-caller-identity --profile dev-iam-user

The CLI refreshes the temporary credentials as needed. The overall session lasts for the session duration of the IAM principal, up to 12 hours. You can let it expire or end it yourself:

aws logout --profile dev-iam-user

Grant Access to Local Sign-In
#

You need AWS CLI version 2.32.0 or newer. The IAM user, role, or group also needs the AWS-managed SignInLocalDevelopmentAccess policy. The aws login documentation includes the prerequisites and the policy details.

Do not use aws login with the root user for routine work. The command supports root, but that session has unrestricted access to the account. A short expiry does not make routine root access safe. Reserve it for the rare account-recovery task that explicitly requires root, then sign out immediately.

Use the IAM user as a temporary bridge while you prepare a move to Identity Center. aws login removes the long-term key from your laptop today. Identity Center remains the better destination because it manages access across accounts through users, groups, and permission sets. Still, we present this option because it is preferable to keeping long-term access keys.

Let Your CI/CD Pipeline Assume a Role With OIDC
#

So far, a person has been present to complete a browser sign-in. Your deployment pipeline needs a different route. On a personal AWS account, that usually means GitHub Actions or GitLab CI deploying a project after you push a change.

At this point, many AWS engineers will reach for IAM Roles Anywhere. It is a useful enterprise option, but it needs a certificate authority and certificate lifecycle management. AWS Private CA pricing starts at $50 per month, which already exceeds the personal AWS budget targeted here.

For a CI/CD pipeline, there is a simpler option that not everyone knows about. GitHub Actions and GitLab CI can issue OpenID Connect (OIDC) identity tokens to individual jobs. AWS verifies the token and lets that job assume a narrowly scoped IAM role. You get temporary credentials for the deployment without saving an IAM access key as a repository variable.

Connect GitHub Actions to an IAM Role
#

Create an OIDC identity provider in the AWS account:

aws iam create-open-id-connect-provider \
  --url https://token.actions.githubusercontent.com \
  --client-id-list sts.amazonaws.com \
  --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1

Next, create a role with a trust policy that accepts tokens only from the repository and branch that should deploy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:ref:refs/heads/main"
        }
      }
    }
  ]
}

The sub condition matters. Without it, a role that trusts GitHub’s provider could accept tokens from repositories you never intended to authorize. Change my-org/my-repo to your repository and attach only the deployment permissions that workflow needs.

On the GitHub side, allow the workflow to request an identity token with id-token: write, then use aws-actions/configure-aws-credentials to assume the role. That workflow permission only enables the OIDC token request. The IAM role still controls what the temporary AWS session can do. GitHub documents the complete pipeline configuration in Configuring OpenID Connect in Amazon Web Services.

Connect GitLab CI to an IAM Role
#

GitLab follows the same trust model. Register GitLab as the OIDC provider:

aws iam create-open-id-connect-provider \
  --url https://gitlab.com \
  --client-id-list https://gitlab.com \
  --thumbprint-list afb360caa4b00e4f091e3b3bc0b9c66d1e569e0f

Then limit the role trust policy to your project and its main branch:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/gitlab.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "gitlab.com:aud": "https://gitlab.com"
        },
        "StringLike": {
          "gitlab.com:sub": "project_path:my-group/my-project:ref_type:branch:ref:main"
        }
      }
    }
  ]
}

In GitLab, request an identity token with the expected audience and exchange it through sts:AssumeRoleWithWebIdentity. STS checks the token against the provider and role trust policy before returning temporary credentials. GitLab’s guide, Configure OpenID Connect in AWS to retrieve temporary credentials, contains the current pipeline definition.

Replace the Key You Already Have
#

Choose the route that matches the caller:

Caller Use
You, across one or more AWS accounts IAM Identity Center
You, with an existing IAM console user aws login
A GitHub Actions or GitLab CI job OIDC federation and an IAM role

For a personal AWS setup, the exposure risk usually outweighs the inconvenience of briefly breaking a script or deployment. Treat every long-term key as something to replace now.

If the key only gives your laptop terminal access, configure aws login straight away and verify the new profile with aws sts get-caller-identity. Revoke the old key as soon as that works. You can move from this safe starting point to a fine-grained Identity Center setup without leaving the permanent credential active in the meantime.

If a system uses the key, reduce its permissions immediately to the exact actions and resources it needs. Then check whether that system can present an OIDC identity or use another federation mechanism to assume an IAM role. For GitHub Actions or GitLab CI, follow the examples above and remove the stored access key today. A brief interruption is easy to fix in a personal setup, and you finish with a deployment that no longer depends on a permanent secret.

Temporary does not mean harmless. Automated attackers can use exposed credentials within minutes, long before they expire. Keep every permission set and IAM role minimally privileged so a leaked session has limited reach. Accidentally committing credentials remains a common exposure path, so add Gitleaks as a pre-commit hook to catch many secrets before they enter Git history or reach a public repository. Temporary credentials reduce the exposure window; careful handling and least privilege manage the risk that remains.

References
#

Related