Stockio

GitHub Actions OIDC: Deploy to AWS Without Access Keys

Replace stored AWS access keys with GitHub Actions OIDC, narrowly scoped trust policies, protected environments, and auditable short-lived deployment sessions.

By Ravi Desai

DevOps & Security Engineer ·

On this page

A deployment workflow needs authority to publish software, but it rarely needs a permanent cloud access key. GitHub Actions can exchange an identity token for a short-lived AWS session. That removes one rotation burden while making the trust policy, rather than possession of a stored string, the critical security boundary.

Understand what OIDC actually replaces

OpenID Connect does not remove permissions or eliminate secrets everywhere. It lets a cloud provider verify claims about a workflow before issuing temporary credentials. The identity provider, role trust policy, role permissions, and workflow event must agree on which workload is authorized.

Use the JSON Formatter to inspect a sanitized IAM trust policy. Expand the condition block and check the audience and subject individually. Valid JSON is only syntax validation; an overly broad subject remains dangerous even when perfectly formatted.

Begin with a deployment inventory: repository, branch or protected environment, cloud account, role, and permitted resources. Separate staging and production roles. A test deployment should not gain production authority merely because both jobs live in the same repository.

For background on credential handling, read secure token generation. OIDC changes credential delivery, not the obligation to minimize access or keep application secrets out of logs.

Constrain the AWS trust relationship

Register GitHub's OIDC provider in the intended AWS account, then create a role that accepts web identity federation. The GitHub AWS OIDC guide describes the provider setup and supported claims.

A simplified trust policy for one repository's production environment is:

{
"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",
      "token.actions.githubusercontent.com:sub": "repo:example/site:environment:production"
    }
  }
}]
}

Replace the account and repository with your own values. The subject claim changes when an environment is used; do not copy a branch-based subject into an environment-based job and expect it to match. Special characters can also affect claim encoding, so inspect documented claim formats rather than guessing.

Avoid wildcard repository subjects for convenience. A broad trust relationship can turn a low-risk repository into a route to sensitive infrastructure. Review trust changes independently from ordinary application changes.

Limit what the assumed role can do

The trust policy answers who can assume the role. A separate permissions policy answers what that role can do afterward. Both must be narrow. Authorize only the deployment APIs and resource identifiers required by the publishing mechanism.

For example, publishing static assets may need writes to a particular bucket prefix and a separate invalidation operation. It should not automatically receive permission to edit IAM roles, read unrelated secrets, or delete other projects. Some APIs require broader resource syntax; document those exceptions instead of hiding them in a universal administrator policy.

Use a distinct role for infrastructure provisioning if provisioning needs more authority than application deployment. Decide whether the deployment job can delete resources and whether that capability is genuinely necessary for routine releases.

The AWS IAM documentation explains roles, policy evaluation, and explicit denies. Test both an allowed action and a deliberately disallowed action in a nonproduction account before relying on the boundary.

Connect the workflow to a protected environment

Grant id-token: write only to the job that must request a token. This permission enables token issuance; it does not itself grant access to AWS. The cloud role still checks the claims and decides whether to issue a session.

Configure the job to reference the exact production environment named in the trust policy. Protect that environment with appropriate reviewers and deployment branch restrictions. Otherwise, a matching environment name may provide less protection than the policy author intended.

Use an official, reviewed credential configuration action, pinned according to your dependency policy, to request and exchange the token. Set the intended role ARN and region explicitly. Then run a harmless identity check and verify the resulting account before publishing artifacts.

Keep untrusted pull-request execution outside this job. Approval should cover the code and artifact being deployed, not merely a workflow label. If the release downloads an artifact from another run, verify its provenance and intended commit instead of trusting a familiar file name.

Migrate safely and retain useful evidence

Move staging first. Record the expected account, role session, repository, and release identifier in the deployment record without logging the token or credential values. Choose a recognizable session name so cloud audit events can be correlated with the workflow run.

Deliberately attempt deployment from a nonmatching branch or environment and confirm that role assumption fails. Also test a valid assumption followed by an unauthorized API request. Those are different failure modes and demonstrate different controls.

Once production uses the federated path successfully, revoke the old access keys rather than leaving them as an undocumented fallback. Search repository settings, organization settings, deployment integrations, and incident runbooks for stale references. A backup permanent key undermines the migration if nobody owns its lifecycle.

Do not confuse application runtime secrets with CI identity. Database passwords and third-party tokens still need a managed delivery and rotation process. Avoid sending them through build arguments or artifacts. The DevOps guides cover release workflows, while account-level policy should remain owned by your organization's cloud security process.

Schedule periodic reviews after repository renames, environment changes, and workflow refactors. Trust policies tend to become stale at organizational boundaries. A clear owner and a small negative test are often more valuable than a complicated policy nobody can explain.

Troubleshoot the exchange in layers

When deployment fails, distinguish token issuance, role assumption, and the deployment API call. If the workflow cannot request an identity token, check the job permission and execution context first. If AWS rejects assumption, compare the configured provider, audience, and subject against the documented values for that job. An environment-based subject does not also prove that the job came from the release branch; environment deployment restrictions must enforce that rule.

If assumption succeeds but publishing fails, investigate permission boundaries, resource policies, organization policies, and the role's own permissions. Do not widen the trust policy to fix an authorization error that happens after credentials have already been issued. Record the denied action and resource, then make the smallest reviewed permissions change.

Plan for session expiry during long releases. Acquire credentials close to the deployment step, and choose a bounded duration consistent with organizational policy and expected runtime. Avoid copying credentials to later jobs or persisting them in artifacts. If a release outlasts its session, make recovery explicit: verify which resources were already updated before restarting. Short-lived identity reduces exposure, but it does not make partially completed deployments atomic.

Key takeaways

  • OIDC replaces stored deployment keys with short-lived sessions, not unrestricted trust.
  • Match audience and subject to the exact repository and deployment environment.
  • Review role trust separately from the role's resource permissions.
  • Protect token-requesting jobs from untrusted code execution.
  • Revoke old keys and verify audit trails after migration.
Featured sponsor

Reach designers & developers at work

Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.

Become a sponsor

Keep reading

Related articles

More in DevOps & Deployment
DevOps & Deployment

Container Image Scanning and SBOMs in CI

Plan container supply-chain checks with concrete configuration, failure tests, narrowly scoped permissions, measurable rollout gates, and a recovery procedure your team can rehearse.

Includes: JSON formatterRavi DesaiRavi Desai
DevOps & Deployment

Deploy to Cloudflare Workers: An Edge Release Checklist

Plan edge releases with concrete configuration, failure tests, narrowly scoped permissions, measurable rollout gates, and a recovery procedure your team can rehearse.

Includes: JSON formatterRavi DesaiRavi Desai
DevOps & Deployment

Production Error Tracking: Source Maps and Alert Triage

Plan error tracking with concrete configuration, failure tests, narrowly scoped permissions, measurable rollout gates, and a recovery procedure your team can rehearse.

Includes: JSON formatterRavi DesaiRavi Desai
DevOps & Deployment

Structured Logging Best Practices for Production Apps

Plan structured logs with concrete configuration, failure tests, narrowly scoped permissions, measurable rollout gates, and a recovery procedure your team can rehearse.

Includes: JSON formatterRavi DesaiRavi Desai
DevOps & Deployment

Feature Flag Best Practices: Targeting and Kill Switches

Plan feature flag management with concrete configuration, failure tests, narrowly scoped permissions, measurable rollout gates, and a recovery procedure your team can rehearse.

Includes: JSON formatterRavi DesaiRavi Desai
DevOps & Deployment

Zero-Downtime Database Migrations: Expand and Contract

Plan migration sequencing with concrete configuration, failure tests, narrowly scoped permissions, measurable rollout gates, and a recovery procedure your team can rehearse.

Includes: JSON formatterRavi DesaiRavi Desai