OIDC Provider

Complete reference for the GitHub Actions OIDC provider CloudFormation template.


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

ResourceDescription
OIDC ProviderEstablishes trust between AWS IAM and GitHub Actions
IAM RoleService role that GitHub Actions assumes during workflow execution
Trust PolicyControls which repositories and branches can assume the role

Template location

templates/oidc-provider.yml

Parameters

ParameterTypeDefaultDescription
GithubActionsThumbprintCommaDelimitedList6938fd4d98bab03faadb97b34396831e3780aea1Thumbprint for GitHub Actions OIDC tokens
AudienceListCommaDelimitedListsts.amazonaws.comAllowed audiences for OIDC tokens
SubjectClaimFiltersCommaDelimitedListRequiredControls which repositories/branches can assume the role
PathString/IAM path for the service role
ManagedPolicyARNsCommaDelimitedListAdministratorAccessAWS 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