Overview
The OIDC provider template creates the infrastructure for GitHub Actions to authenticate with AWS using OpenID Connect. This eliminates long-lived AWS access keys, providing secure authentication for CI/CD pipelines.
Resources created
| Resource | Description |
|---|---|
| OIDC Provider | Establishes trust between AWS IAM and GitHub Actions |
| IAM Role | Service role that GitHub Actions assumes during workflow execution |
| Trust Policy | Controls which repositories and branches can assume the role |
Template location
templates/oidc-provider.yml
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| GithubActionsThumbprint | CommaDelimitedList | 6938fd4d98bab03faadb97b34396831e3780aea1 | Thumbprint for GitHub Actions OIDC tokens |
| AudienceList | CommaDelimitedList | sts.amazonaws.com | Allowed audiences for OIDC tokens |
| SubjectClaimFilters | CommaDelimitedList | Required | Controls which repositories/branches can assume the role |
| Path | String | / | IAM path for the service role |
| ManagedPolicyARNs | CommaDelimitedList | AdministratorAccess | AWS managed policies to attach |
SubjectClaimFilters (most important)
Controls which repositories and branches can assume the IAM role.
Format patterns:
# Allow entire repository (any branch)
SubjectClaimFilters: repo:owner/repository:*
# Allow only main branch
SubjectClaimFilters: repo:owner/repository:ref:refs/heads/main
# Allow specific branch
SubjectClaimFilters: repo:owner/repository:ref:refs/heads/develop
# Allow any release branch
SubjectClaimFilters: repo:owner/repository:ref:refs/heads/release/*
# Allow pull requests
SubjectClaimFilters: repo:owner/repository:pull_request
# Allow GitHub Environment deployments
SubjectClaimFilters: repo:owner/repository:environment:production
# Multiple filters
SubjectClaimFilters:
- repo:owner/repository:ref:refs/heads/main
- repo:owner/repository:ref:refs/heads/develop
Important: Use the most restrictive filter that meets your needs. For production, limit to specific branches.
ManagedPolicyARNs
Controls what the GitHub Actions workflow can do in your AWS account.
# Full access (default)
ManagedPolicyARNs: arn:aws:iam::aws:policy/AdministratorAccess
# Power user (everything except IAM)
ManagedPolicyARNs: arn:aws:iam::aws:policy/PowerUserAccess
# CloudFormation only
ManagedPolicyARNs: arn:aws:iam::aws:policy/AWSCloudFormationFullAccess
# Multiple policies
ManagedPolicyARNs:
- arn:aws:iam::aws:policy/AWSCloudFormationFullAccess
- arn:aws:iam::aws:policy/AmazonS3FullAccess
# Custom policy
ManagedPolicyARNs: arn:aws:iam::123456789012:policy/GitHubActionsCustomPolicy
Outputs
ServiceRoleARN
Returns the ARN of the created service role. Use in your GitHub Actions workflow:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsServiceRole
aws-region: us-east-1
Parameter file examples
Single repository, main branch only
# parameters/production/oidc-provider.yml
SubjectClaimFilters: repo:towardsthecloud/infrastructure:ref:refs/heads/main
ManagedPolicyARNs: arn:aws:iam::aws:policy/AdministratorAccess
Multiple branches
# parameters/test/oidc-provider.yml
SubjectClaimFilters:
- repo:towardsthecloud/infrastructure:ref:refs/heads/main
- repo:towardsthecloud/infrastructure:ref:refs/heads/develop
ManagedPolicyARNs: arn:aws:iam::aws:policy/AdministratorAccess
Multiple repositories
# parameters/shared/oidc-provider.yml
SubjectClaimFilters:
- repo:towardsthecloud/app1:ref:refs/heads/main
- repo:towardsthecloud/app2:ref:refs/heads/main
- repo:towardsthecloud/infrastructure:ref:refs/heads/main
ManagedPolicyARNs: arn:aws:iam::aws:policy/PowerUserAccess
Deployment
Initial deployment
Deploy the OIDC provider template first, before any other infrastructure:
# Deploy to test environment
rain deploy templates/oidc-provider.yml --config parameters/test/oidc-provider.yml
# Deploy to production
rain deploy templates/oidc-provider.yml --config parameters/production/oidc-provider.yml
Verification
# Check stack status
aws cloudformation describe-stacks --stack-name oidc-provider
# Get the service role ARN
aws cloudformation describe-stacks \
--stack-name oidc-provider \
--query 'Stacks[0].Outputs[?OutputKey==`ServiceRoleARN`].OutputValue' \
--output text
Testing the role
# .github/workflows/test-oidc.yml
name: Test OIDC Authentication
on: workflow_dispatch
permissions:
id-token: write
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ vars.TEST_AWS_ACCOUNT_ID }}:role/GitHubActionsServiceRole
aws-region: ${{ vars.AWS_REGION }}
- name: Test AWS access
run: |
aws sts get-caller-identity
aws cloudformation list-stacks
Security best practices
1. Use restrictive SubjectClaimFilters
# Good: Specific branch
SubjectClaimFilters: repo:owner/repo:ref:refs/heads/main
# Bad: Too permissive
SubjectClaimFilters: repo:owner/repo:*
2. Separate roles per environment
Create different OIDC stacks for each environment:
parameters/
├── test/
│ └── oidc-provider.yml # GitHubActionsServiceRole-Test
├── staging/
│ └── oidc-provider.yml # GitHubActionsServiceRole-Staging
└── production/
└── oidc-provider.yml # GitHubActionsServiceRole-Production
3. Use least-privilege policies
Instead of AdministratorAccess, create custom policies with only required permissions.
4. Enable CloudTrail logging
Monitor all actions taken by the GitHub Actions role:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=Username,AttributeValue=GitHubActionsServiceRole \
--max-results 50
Troubleshooting
"Not authorized to perform sts:AssumeRoleWithWebIdentity"
Cause: SubjectClaimFilters doesn't match the GitHub Actions context.
Solution: Check your filter matches the repository and branch:
- name: Debug OIDC token
run: |
echo "Repository: ${{ github.repository }}"
echo "Ref: ${{ github.ref }}"
"OpenIDConnect provider not found"
Cause: OIDC provider stack not deployed or deployed to wrong account.
Solution: Verify the stack exists:
aws cloudformation describe-stacks --stack-name oidc-provider
"Role does not have sufficient permissions"
Cause: Attached policies don't include required permissions.
Solution: Update ManagedPolicyARNs to include necessary permissions.
Next steps
- Environments - Multi-environment setup
- CI/CD Workflows - How GitHub Actions uses OIDC
- Parameters reference - Parameter file structure