· 5 min read

Stop Using AWS Access Keys

This article was auto-translated from Chinese. Some nuances may be lost in translation.

This article explains why using AWS Access Keys is a practice you should phase out as early as possible, and how to replace them with OIDC + IAM Roles.

The scope covers GitHub Actions CI/CD, services running on EC2/ECS, and local development environments.

What’s Wrong with Access Keys

An AWS Access Key is a set of long-term credentials consisting of an Access Key ID and a Secret Access Key.

Once created, they remain valid indefinitely unless manually deleted or deactivated.

When creating an Access Key in the AWS Console, you will also notice that AWS does everything it can to discourage you from creating one.

Once an Access Key is leaked, attackers can use these credentials to do virtually anything before you even notice—such as launching EC2 instances for crypto mining, downloading customer data from S3, or deleting RDS snapshots.

AWS itself explicitly states in its IAM Best Practices:

Where possible, we recommend relying on temporary credentials instead of creating long-term credentials such as access keys.

Leaks Happen More Easily Than You Think

There are many ways Access Keys can leak:

  • Git history: Accidental commits of .env or config files—even if deleted in a later commit, they remain visible in git log.
  • CI/CD logs: Echoing environment variables during debugging, or a library dumping full environment variables in an error stack trace.
  • Employee offboarding: If a key is tied to an IAM User, forgetting to revoke it upon departure poses a security risk.
  • Shared accounts: Teams sharing the same key make it impossible to audit who performed what action when an incident occurs.

GitHub offers secret scanning, and AWS has automated detection for aws:SecretAccessKey. However, these are merely reactive remedies, not root-cause solutions.

Management Overhead

Even without leaks, maintaining Access Keys comes with overhead:

  • Periodic rotation: AWS recommends rotating keys at least every 90 days. Every rotation requires updating everywhere the key is used, including GitHub Secrets, other CI systems, and local development environments.
  • Permission audits: Periodically verifying whether the IAM Policies attached to the key are over-permissioned.
  • Usage tracking: Who is using it? Which workflows depend on it? Is it still in use? If a key was created six months ago and hasn’t been touched, should it be deleted?

These tasks might seem negligible for a team of three to five people, but as the team grows and projects multiply, Access Key management gradually turns into an ongoing burden. The mindset of “it won’t happen to us” will eventually come back to bite you.

Replacing Access Keys with OIDC + IAM Roles

GitHub Actions proves its identity to AWS via OIDC (OpenID Connect). After verification, AWS issues a set of temporary credentials that expire in minutes. The entire process requires storing zero secrets.

This article uses GitHub Actions as an example, but platforms like GitLab CI and CircleCI offer similar OIDC integration mechanisms.

How OIDC Works

OIDC is an authentication protocol based on JWT. In GitHub Actions, the workflow proceeds as follows:

GitHub Actions Runner

    │ 1. 向 GitHub 的 OIDC Provider 請求 JWT token
    │    (token 裡包含 repo 名稱、branch、workflow 等資訊)


AWS STS (Security Token Service,負責發放臨時憑證的服務)

    │ 2. 驗證 JWT token 的簽章(透過 GitHub 的公開金鑰)
    │ 3. 檢查 token 的 claims 是否符合 IAM Role 的信任條件
    │ 4. 回傳臨時憑證(Access Key + Secret Key + Session Token)


GitHub Actions Runner

    │ 5. 用臨時憑證執行 AWS 操作
    │    (憑證在指定時間後自動過期)


  完成,憑證失效

Each workflow execution obtains a fresh token that automatically invalidates once expired. There is no need for rotation, and it is impossible to dig out and reuse from Git history.

Another critical difference lies in the trust model.

The security of an Access Key relies entirely on the secret itself never being leaked; once leaked, legitimate usage cannot be distinguished from malicious usage.

OIDC verifies identity through JWT signatures. AWS can independently verify token authenticity via GitHub’s JWKS endpoint without sharing any secrets.

Comparison with Access Keys

Access KeyOIDC + IAM Role
Credential LifetimeIndefinitely validMinutes to hours
Leak RiskCan be used indefinitely once leakedInvalid upon expiration
Secret ManagementMust be stored in GitHub SecretsNo secrets required
RotationManual, at least every 90 daysAutomatic, fresh on every run
AuditingOnly traceable to IAM UserTraceable to specific repo and workflow
Offboarding HandlingMust remember to revokeNot needed, as no long-term credentials exist

In terms of security risks and management overhead, IAM Roles are clearly the superior choice. The AWS console also provides guidance for handling different scenarios:

  • CLI: Use AWS CLI v2 or CloudShell. It is recommended to use aws sso login to avoid storing permanent credentials locally.
  • Local Code: Use IDEs integrated with AWS Toolkit, authenticating via existing console credentials or IAM Identity Center.
  • Compute resources on AWS: Use IAM Roles.
  • Third-party services: Use temporary credentials instead of long-term credentials.
  • Non-AWS applications: Use IAM Roles Anywhere to issue temporary credentials.
    • IAM Roles Anywhere requires a Certificate Authority (such

Related Posts

Explore Other Topics