A deployment job needs permission to change a cloud resource. A stored access key can provide that permission, but it also gives the repository a credential that must be created, copied into a secret, rotated, and eventually removed. GitHub’s OpenID Connect overview describes another path: the job presents a token that identifies its workflow run, and the cloud provider issues short-lived access for that run.
How the exchange works
OpenID Connect (OIDC) gives the job a way to prove its identity. GitHub issues a JSON Web Token with claims about the job. The cloud provider checks those claims against a trust policy. If they match, the provider issues a short-lived credential for the assigned cloud role. The deployment command then uses that credential. GitHub documents the sequence.
The identity token and the cloud credential have different jobs. The GitHub token says which workflow is asking. The cloud credential authorizes specific cloud operations. AWS Identity and Access Management (IAM) uses a role trust policy to decide who may assume a role, and a separate permissions policy to decide what that role may do. AWS explains those two policies. This separation matters when a deploy should write to one destination.
Set the AWS trust boundary
For an AWS example, register GitHub’s issuer, https://token.actions.githubusercontent.com, as an OIDC identity provider in IAM. Set its audience to sts.amazonaws.com when using the AWS credentials action. Then create a web identity role. GitHub’s AWS guide gives these values, and AWS describes the role setup.
The role’s trust policy should require that audience and an exact sub value for the intended repository and branch. Here is the core of that policy. Replace the account ID and subject placeholder with values from your setup:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::YOUR_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "YOUR_EXACT_SUBJECT"
}
}
}]
}
The placeholder is deliberate. GitHub documents more than one default subject format. Some repositories use a subject with owner and repository IDs; others use names. An environment changes the subject context as well. Match the actual format for your repository instead of copying a sample string. GitHub’s OIDC reference shows the formats. AWS recommends restricting sub to specific repositories or branches and warns that a broad value can expose the role to repositories you do not control. AWS details the trust check.
Attach a permissions policy that grants only the cloud actions and resources the deployment needs. For an object upload, the role needs permission to write the intended object path. The trust policy answers which job can enter; the permissions policy limits what it can change after entry. AWS describes the split.
Give the job permission to request a token
A GitHub Actions job needs id-token: write to request its OIDC token. That setting does not give the job write access to repository content or AWS resources. The AWS credentials action uses the token to request AWS credentials for the role. GitHub’s AWS guide shows the job permissions and exchange.
name: Deploy site
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v6
- uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502
with:
role-to-assume: arn:aws:iam::YOUR_ACCOUNT_ID:role/YOUR_DEPLOY_ROLE
aws-region: YOUR_REGION
- run: aws s3 cp ./index.html s3://YOUR_BUCKET/index.html
This is a small upload example. Replace the role, region, bucket, and file path. The AWS role still needs a permissions policy for the target. contents: read supports checkout; id-token: write lets the job request an identity token. The action revisions and upload command follow GitHub’s AWS workflow example. Review action revisions when maintaining the workflow.
Check the boundary around deployment
A branch filter on the workflow and the role’s subject condition should agree. If the job uses a GitHub environment, the subject must reference that environment, and the environment should restrict which branches or tags may deploy. GitHub’s AWS guide explains the changed subject, while GitHub’s environment guide shows deployment branch rules.
If role assumption fails, inspect the expected audience and subject before widening trust. GitHub provides an OIDC claim debugging method that shows the claims a job would send. Compare those claims with the IAM role policy. A mismatch can result from the repository’s subject format or an environment context. Keep the condition precise once the values match.
What to do
- Pick one deployment job and identify the exact cloud actions and resource paths it needs.
- Register GitHub’s OIDC provider in IAM. Create a role with a narrow permissions policy and a trust policy that matches the job’s actual
audandsubclaims. - Give that job
id-token: write, configure the AWS credentials action with the role ARN, and run the deploy from the intended branch. - Confirm the deploy succeeds, then check that a job outside the allowed subject cannot assume the role. Remove the old stored cloud key from this deployment path after the new path works.

The Campfire
No commentsNobody has pulled up a log by this one yet. Be the first to say what you make of it.
Held for the desk. It appears after a look.