Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

6 Commits

Repository files navigation

AWS OIDC Setup for GitHub Actions

Bash scripts to configure AWS IAM for GitHub Actions OIDC authentication — no long-lived access keys needed.

What This Creates

ResourceDescription
OIDC Identity Providertoken.actions.githubusercontent.com in your AWS account
IAM RoleAssumable by GitHub Actions via OIDC federation
IAM PolicyPermissions granted to the role (S3, ECR, ECS, CloudFormation, CloudWatch Logs by default)

Prerequisites

  • AWS CLI v2 installed
  • Sufficient IAM permissions to create OIDC providers, roles, and policies
  • bash 4+

Quick Start

  1. Setup Environment:

    cp .env.example .env
    nano .env

    Fill in your AWS credentials, account ID, and GitHub org. Set GITHUB_REPO to control access scope:

    GITHUB_REPOTrust policy subject
    "*"repo:ORG/* — any repo in the org can assume the role
    "my-app"repo:ORG/my-app:* — single repo, all refs
  2. Run Setup:

    ./setup.sh

    The script will confirm your settings before creating the OIDC provider, IAM role, and attaching policies.

  3. Use in GitHub Actions:

    Add the following to your .github/workflows/deploy.yml:

    permissions:
    id-token: write # Required for requesting the JWTcontents: read # Required for actions/checkoutjobs:
    deploy:
    runs-on: ubuntu-lateststeps:
    - name: Configure AWS Credentialsuses: aws-actions/configure-aws-credentials@v4with:
    role-to-assume: arn:aws:iam::<ACCOUNT_ID>:role/github-actions-oidc-roleaws-region: us-east-1
    - name: Test AWS Accessrun: aws sts get-caller-identity

    For ECS deployments, you can extend the workflow:

     - name: Login to Amazon ECRid: login-ecruses: aws-actions/amazon-ecr-login@v2
    - name: Build, tag, and push image to ECRenv:
    ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}ECR_REPOSITORY: my-appIMAGE_TAG: ${{ github.sha }}run: | docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG - name: Download task definitionrun: | aws ecs describe-task-definition --task-definition my-app \ --query taskDefinition > task-definition.json - name: Update ECS task definitionid: task-defuses: aws-actions/amazon-ecs-render-task-definition@v1with:
    task-definition: task-definition.jsoncontainer-name: my-appimage: ${{ steps.login-ecr.outputs.registry }}/my-app:${{ github.sha }}
    - name: Deploy to ECSuses: aws-actions/amazon-ecs-deploy-task-definition@v2with:
    task-definition: ${{ steps.task-def.outputs.task-definition }}service: my-app-servicecluster: my-clusterwait-for-service-stability: true

File Structure

├── .env # Your private configuration (git-ignored)
├── .env.example # Template for configuration
├── .gitignore # Prevents committing secrets
├── README.md # This file
├── setup.sh # Main entry point (runs scripts 01-03)
├── scripts/
│ ├── 01-create-oidc-provider.sh # Create/Update OIDC identity provider
│ ├── 02-create-iam-role.sh # Create IAM role with trust policy
│ ├── 03-attach-policies.sh # Attach permission policies
│ └── 99-cleanup.sh # Tear down all resources
└── policies/
├── trust-policy.json # Who can assume the role
└── permissions-policy.json # What the role can do

Included Permissions

The default policies/permissions-policy.json grants the following:

StatementActionsPurpose
AllowS3Accesss3:GetObject, PutObject, ListBucketUpload/download artifacts to S3
AllowECRAccessecr:GetAuthorizationToken, BatchCheckLayerAvailability, GetDownloadUrlForLayer, BatchGetImage, PutImage, InitiateLayerUpload, UploadLayerPart, CompleteLayerUploadPush/pull container images
AllowCloudFormationDescribecloudformation:DescribeStacks, ListStacksRead CloudFormation stack info
AllowECSTaskDefinitionsecs:RegisterTaskDefinition, DescribeTaskDefinition, DeregisterTaskDefinition, ListTaskDefinitionsManage ECS task definitions
AllowECSServiceManagementecs:UpdateService, DescribeServices, ListServicesDeploy to ECS services
AllowECSTaskManagementecs:DescribeTasks, ListTasks, RunTask, StopTaskRun and monitor ECS tasks
AllowECSClusterReadecs:DescribeClusters, ListClustersRead ECS cluster info
AllowPassRoleForECSiam:PassRole (conditioned to ecs-tasks.amazonaws.com)Pass execution/task roles to ECS
AllowCloudWatchLogsForECSlogs:CreateLogGroup, CreateLogStream, PutLogEvents, DescribeLogGroups, DescribeLogStreamsECS container logging

Security Best Practices

1. Multi-Thumbprint OIDC

This project uses multiple thumbprints (OIDC_THUMBPRINTS) for the GitHub OIDC provider. This prevents your workflows from breaking when GitHub rotates its certificates.

2. Least Privilege

Edit policies/permissions-policy.json to grant only the specific permissions your workflow needs (e.g., only specific S3 buckets, ECR repositories, or ECS clusters/services).

3. Trust Policy Scoping

The GITHUB_REPO variable in .env controls how broadly the role can be assumed:

# All repos in the org
GITHUB_REPO="*"# Single repo, all refs
GITHUB_REPO="my-app"

The generated trust policy sub condition patterns:

GITHUB_REPOGenerated pattern
"*"repo:org/*
"my-app"repo:org/my-app:*

Cleanup

To remove all created resources from your AWS account:

./scripts/99-cleanup.sh

About

Automated setup for AWS IAM OIDC authentication with GitHub Actions.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages