Connect GitHub & AWS - Learn the OIDC Basics Now! πŸ”


AWS FOR THE REAL WORLD
⏱️
Reading time: 6 minutes
🎯
Main Learning: Learn how to securely connect GitHub Actions to your AWS account using OIDC authentication without storing access keys. Step-by-step guide with IAM role setup, trust policy configuration, and workflow examples for safe CI/CD deployments.
πŸ“

Hey Reader πŸ‘‹πŸ½,

welcome to another week of AWS for the Real World

We are right in the middle of pre:invent. Re:Invent starts next week! We are both not present, but we will give you all the updates we get πŸ˜‰

πŸ“° This Week in AWS

πŸš€API Gateway supports response streaming

Finally you can build your AI apps without a Lambda function URL! Read More β†’

πŸ“šAPI Gateway gets a developer portal

You can manage all your public API Documentation natively in AWS now. Read More β†’

πŸ’°CloudFront Flat Rate Pricing

One of the first times (I think) that AWS gives you a proper flatrate pricing! Read More β†’

I'm especially excited about this week's sponsor - Honeycomb. The founders of Honeycomb wrote an excellent book which helped both Tobi's and my career for writing the CloudWatch Book. It's called Observability Engineering and I highly recommend it.

Let's see what Honeycomb does:

Honeycomb
Honeycomb Sponsored
Honeycomb Dashboard

Observability built for AI apps

Don’t waste your AI advantage on observability tools that can't leverage it.

With Honeycomb, you get granular insight into how your LLMs behave in production in real time.

OpenTelemetry native. Instrument once, get insights everywhere. Start free with 20M events/month.

πŸ“– Read: The End of Observability As We Know It by Austin Parker

This is sponsored content supporting our AWS & serverless content

​

On to this week's deep dive.

We've set up GitHub Actions with AWS role assumption countless times. Somehow we never wrote about it. Until now.

Have fun with it πŸ‘¨πŸ½β€πŸ’»

Cover

πŸ“š This Week's Deep Dive

Introduction

GitHub Actions is one of the best CI/CD platforms out there.

It's easy to get started, powerful, and comes with a generous free tier for build minutes.
It's fast too.
You don't need to bootstrap containers that add overhead like AWS CodeBuild and CodePipeline do.

Configuring pipelines and jobs is simpler as well.

The catch is that GitHub Actions doesn't natively integrate with AWS like CodeBuild does (unless you run your own build agents, which most people don't).

Luckily, OIDC makes it possible to connect GitHub Actions with one or multiple AWS accounts in just a few steps.

No access keys to store.
No credentials to rotate.
Just secure, temporary access whenever your workflow runs.

What is OIDC Authentication?

OIDC stands for OpenID Connect.

It's a protocol that lets one service verify your identity without sharing credentials.
Think of it like a secure handshake between GitHub and AWS.

When your GitHub Actions workflow runs, GitHub acts as the identity provider.
It generates a short-lived token that proves the workflow is legitimate.
AWS checks this token, verifies it came from GitHub, and grants temporary access based on the permissions you've configured.

The verification process also checks which repository the request came from.
You configure exactly which repos are allowed to access your AWS account.
Any workflow from an unauthorized repository gets blocked automatically.

OIDC Flow between GitHub Actions and AWS

No static credentials.
No secrets stored in your repository.
The token expires automatically after the job finishes.

This makes OIDC perfect for CI/CD pipelines where you need AWS access but don't want to manage long-lived credentials.

We wrote a detailed guide to OIDC if you want to understand the protocol more deeply.

Prerequisites

You need two things to follow along:

  • A GitHub repository where you want to run workflows
  • An AWS account where you want to deploy or access resources

No previous IAM or OIDC knowledge required.

Step 1: Create an OIDC Identity Provider in AWS

We'll use Pulumi for this guide.

Pulumi is an Infrastructure as Code framework that lets you define cloud resources using your favorite programming language instead of YAML or custom DSLs.
We're using TypeScript here, but you could also use Python, Go, or C#.

The first step is creating an OIDC identity provider in AWS that trusts GitHub.

This tells AWS that tokens from GitHub's identity service are legitimate.

const githubOidcProvider = new aws.iam.OpenIdConnectProvider('GitHubOidcProvider', {
    url: 'https://token.actions.githubusercontent.com',
    clientIdLists: ['sts.amazonaws.com'],
    thumbprintLists: ['6938fd4d98bab03faadb97b34396831e3780aea1'],
});

The URL points to GitHub's OIDC token service.
The client ID sts.amazonaws.com is what AWS expects when workflows request temporary credentials.
The thumbprint validates GitHub's SSL certificate.

Step 2: Create an IAM Role for GitHub Actions

Next, create an IAM role that GitHub Actions will assume.

This role connects to the OIDC provider we just created.

const githubActionsRole = new aws.iam.Role('GitHubActionsProductPipelineRole', {
    name: 'my-app-prod-github-role',
    assumeRolePolicy: githubOidcProvider.arn.apply((oidcArn) =>
        JSON.stringify({
            Version: '2012-10-17',
            Statement: [
                {
                    Effect: 'Allow',
                    Principal: {
                        Federated: oidcArn,
                    },
                    Action: 'sts:AssumeRoleWithWebIdentity',
                    // Trust policy conditions will be added in the next step
                },
            ],
        }),
    ),
    description: 'Role for GitHub Actions from awsf-infra repository',
});

The role name can be whatever you want.
The important part is the assumeRolePolicy which defines the trust relationship.

Step 3: Configure the Trust Policy

The trust policy is where the security magic happens.

You need to add a Condition block to the assume role policy that specifies which repositories can use this role.

Condition: {
    StringEquals: {
        'token.actions.githubusercontent.com:aud': 'sts.amazonaws.com',
    },
    StringLike: {
        'token.actions.githubusercontent.com:sub': [
            'repo:awsfundamentals-hq/awsf-infra:*',
        ],
    },
}

The StringEquals condition ensures the token is meant for AWS STS.

The StringLike condition is what locks down access to specific repositories.
Replace awsfundamentals-hq/awsf-infra with your own organization and repository name.

Trust Policy configuration that only allows certain repositories

The :* wildcard allows any branch or tag from that repository.
You can make this more restrictive by specifying exact branches like repo:your-org/your-repo:ref:refs/heads/main to only allow the main branch.

Step 4: Attach Permissions to the Role

The role needs permissions to actually do something in AWS.

You can grant access to any AWS service or resource your workflow needs.
In our case, we want GitHub Actions to list and upload files to an S3 bucket.

const s3UploadPolicy = new aws.iam.Policy('GitHubActionsS3UploadPolicy', {
    description: 'Allows GitHub Actions to upload files to S3',
    policy: JSON.stringify({
        Version: '2012-10-17',
        Statement: [
            {
                Effect: 'Allow',
                Action: ['s3:PutObject', 's3:GetObject', 's3:ListBucket'],
                Resource: ['arn:aws:s3:::my-bucket-name', 'arn:aws:s3:::my-bucket-name/*'],
            },
        ],
    }),
});

Then attach the policy to the role.

new aws.iam.RolePolicyAttachment('GitHubActionsS3UploadPolicyAttachment', {
    role: githubActionsRole.name,
    policyArn: s3UploadPolicy.arn,
});

Replace the actions and resources with whatever your workflow needs.
Follow the principle of least privilege.
Only grant the minimum permissions required.

Step 5: Update Your GitHub Actions Workflow

Now that the AWS infrastructure is set up, you need to configure your GitHub Actions workflow to use it.

The aws-actions/configure-aws-credentials action handles the OIDC authentication for you.

- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
      role-to-assume: arn:aws:iam::123456789012:role/my-app-prod-github-role
      role-session-name: github-actions-$
      aws-region: us-east-1

Replace the role ARN with the ARN of the role you created.
The role-session-name is just a unique identifier for the session.
Using github.run_id makes it easy to trace which workflow run assumed the role.

The uses directive tells GitHub Actions to run the official AWS credentials action.
This action exchanges the GitHub OIDC token for temporary AWS credentials automatically.

After this step runs, any AWS CLI commands or SDK calls in subsequent steps will use those credentials.

Here's an example that lists the contents of your S3 bucket.

- name: List S3 bucket contents
  run: |
      aws s3 ls s3://my-bucket-name/

That's it.
No secrets to configure.
No credentials to rotate.
The authentication happens automatically through OIDC.

Security Best Practices

Keep your setup secure by following these practices:

  • Restrict repository access: Use specific repository names in your trust policy instead of wildcards. Lock it down to exact branches like ref:refs/heads/main if workflows only run from main.
  • Grant minimal permissions: Only attach IAM policies with the exact actions and resources your workflow needs. Avoid using * for actions or resources.
  • Rotate the OIDC thumbprint: GitHub's SSL certificate can change. Keep the thumbprint updated to prevent authentication failures.
  • Monitor CloudTrail logs (advanced): Track when and how the role is assumed. This gives you visibility into all authentication attempts and role usage.
  • Set up alerting: Configure CloudWatch alarms or EventBridge rules to alert you on unexpected usage patterns or failed authentication attempts.

Conclusion

Connecting GitHub Actions to AWS with OIDC is simple and has become an industry standard.

You created an OIDC provider, set up an IAM role with a trust policy, attached the necessary permissions, and configured your workflow.
Five steps total.

GitHub Actions comes with a generous free tier for build minutes.
Combined with secure AWS access through OIDC, you have everything you need to start a proper continuous delivery process.

Now go build something.

πŸš€ Read the Full Tutorial β†’

Summary

That's it for this week!

Quick recap:

  • πŸš€ API Gateway streaming - build AI apps without function URLs
  • πŸ“– API Gateway developer portal - native API docs in AWS
  • πŸ’° CloudFront flat rate - predictable pricing finally
  • πŸ” GitHub OIDC - ditch those long-lived credentials
  • πŸ“Š Honeycomb - want to learn more about observability? Check out Honeycomb!

Next week is Re:Invent week. Expect a lot of announcements. We'll filter through the noise and bring you what actually matters for your day-to-day work.

See you then!

Sandro

AWS for the Real World

We teach AWS for the real world - not for certifications. Join more than 10,500 developers learning how to build real-world applications on AWS.

Read more from AWS for the Real World

AWS FOR THE REAL WORLD ⏱️ Reading time: 4 minutes 🎯 Main Learning: AWS CloudWatch log centralization makes cross-account logging simple. Learn how to set it up, avoid gotchas, and query logs across your organization. πŸ“ Blog Post Hey Reader πŸ‘‹πŸ½ another week, another newsletter about CloudWatch. This time we're talking about a rather new feature: Log Centralization. But quick question before we dive into this week’s CloudWatch deep dive… We’re 6 weeks out from 2025 (wild, right?) and I’m...

AWS FOR THE REAL WORLD ⏱️ Reading time: 20 minutes 🎯 Main Learning: How to achieve end-to-end observability by integrating CloudWatch Application Signals with OpenTelemetry for automatic service discovery and cross-service request tracing in AWS. πŸ“ Blog Post πŸ’» GitHub Repository Hey Reader πŸ‘‹πŸ½ Welcome to this week’s AWS Fundamentals Newsletter. Pre:Invent season is starting slowly with new launches like: Bigger payload sizes for Kinesis and async Lambda invocations CloudWatch’s interactive...

AWS FOR THE REAL WORLD ⏱️ Reading time: 17 minutes 🎯 Main Learning: How to build a secure, scalable AWS landing zone using AWS Organizations, Service Control Policies, and Identity Center for centralized account and user management. πŸ“ Blog Post Hey Reader πŸ‘‹πŸ½Today I want to dig into how to set up a proper AWS landing zone. We’ll be chatting about AWS Organizations, Service Control Policies (SCPs), and Identity Center. These are the core tools I reach for when I need to get accounts organized,...