Replacing Static AWS Keys with OIDC: A CI/CD Publisher Walkthrough
How to harden GitHub Actions CI/CD by migrating from static AWS credentials to OIDC, scoped to specific S3 prefixes and branches.
Static AWS credentials stored in GitHub Secrets represent a significant security liability. If compromised, they provide persistent access until manually revoked. A more secure approach is to migrate to OIDC (OpenID Connect), which provides temporary, scoped-down credentials for CI/CD workflows.
This walkthrough demonstrates how to implement a generic OIDC pattern scoped to a specific S3 prefix and a single branch.
The Problem: Persistent Credentials
Traditionally, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are used for automation. These keys are often overly permissive and valid indefinitely, making them high-value targets for attackers.
The Solution: GitHub Actions OIDC
With OIDC, GitHub acts as an Identity Provider (IdP). AWS is configured to trust GitHub, allowing specific repositories, branches, or environments to assume a dedicated IAM role.
Step 1: The IAM Trust Policy
The trust policy is the primary guardrail. It should be restricted to a specific repository and branch.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:my-organization/my-repository:ref:refs/heads/main"
}
}
}
]
}
Step 2: Scoping S3 Permissions
To adhere to the principle of least privilege, the IAM role should only have access to the necessary S3 prefix.
1
2
3
4
5
6
7
8
9
10
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetObject"],
"Resource": "arn:aws:s3:::my-artifact-bucket/artifacts/*"
}
]
}
Step 3: Workflow Configuration
In the GitHub Actions workflow, the id-token permission must be requested to enable the use of the OIDC token.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
permissions:
id-token: write # Required for requesting the JWT
contents: read # Required for actions/checkout
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/ArtifactPublisherRole
aws-region: us-east-1
- name: Publish Artifacts
run: ./publish.sh --bucket my-artifact-bucket --prefix artifacts
Benefits
- Elimination of Secret Rotation: There is no need to manually rotate static keys.
- Branch-Level Security: Access can be restricted so that only the
mainbranch (or other protected branches) can publish artifacts. - Temporal Access: Credentials are valid only for the duration of the job, significantly reducing the blast radius of a potential compromise.
Conclusion
Migrating to OIDC replaces static, high-risk credentials with a dynamic and verifiable identity flow. This shift significantly improves the security posture of any CI/CD pipeline.