Skip to main content

Command Palette

Search for a command to run...

Securing your GitHub Workflows with OIDC: Connection to AWS explained

Updated
5 min read
Securing your GitHub Workflows with OIDC: Connection to AWS explained

We’ve all seen it: AWS keys sitting in GitHub Workflows. They might feel convenient at first, but if they ever leak, it’s a nightmare—especially when those keys have wide IAM permissions.

Rotating them every 90 days means generating new keys, updating environments, and hoping nothing breaks in the process.

And really, why keep replacing long-term credentials every 90 days? That’s just turning long-term creds into short-term ones the hard way. Why not start with short-term credentials from the beginning and avoid the problem altogether?

How does OIDC work?

That's where the OpenID Connect (OIDC) protocol comes in. Through a series of verifications between GitHub and AWS, it provides short-term credentials instantly to run the GitHub workflow and use resources from AWS.

This protocol has three main actors

  • Github workflow

  • GitHub as an Identity provider

  • AWS STS as Authorizer and credentials issuer

Let’s have a general picture of how the communication flows between these actors:

  1. GitHub, acting as an identity provider, issues a token when the GitHub workflow begins.

  2. A GitHub Action aws-actions/configure-aws-credentials sends this OIDC token to AWS STS via the API call AssumeRoleWithWebIdentity , along with the IAM Role Arn and optional configurations like the TTL.

  3. STS validates the token against the OIDC identity provider you configured in AWS IAM, comparing its properties against the trust policy configured on the IAM Role, and returns short-term credentials in case of success.

  4. The workflow now uses those short-term credentials to run AWS CLI commands, Terraform, CDK, etc, using the same permissions as the IAM role has defined

Here is a Sequence-System Diagram of the above flow:

sequenceDiagram     participant GA as GitHub Action (Workflow Runner)     participant GH as GitHub OIDC Provider     participant AWS as AWS STS (via IAM Role)      Note over GA: Workflow job starts in GitHub Action      GA->>GH: Request OIDC token (includes: repository, ref, job info)     GH-->>GA: Return signed OIDC ID Token(JWT with claims:audience=sts.amazonaws.com,subject=repo:org/repo:ref,exp, etc.)      Note over GA: Runner now has a short-lived OIDC token (valid ~5 min)      GA->>AWS: AssumeRoleWithWebIdentity(provides OIDC token + role ARN)     AWS-->>GA: Validate token against trust policy(checks issuer=token.actions.githubusercontent.com,audience, subject, repo, branch)      Note over AWS: If trust policy matches, continue. Otherwise reject.      AWS-->>GA: Return temporary STS credentials(AccessKeyId, SecretAccessKey, SessionToken)valid ~15 min      Note over GA: Runner now has short-term AWS credentials      GA->>AWS: Use temporary credentials (e.g., deploy Lambda, push to S3, manage SQS)     AWS-->>GA: Acknowledge API calls with valid auth

What is AWS STS?

AWS STS (Security Token Service) is an AWS service that allows you to request temporary security credentials for AWS resources instead of using long-term IAM user access keys.

These temporary credentials are:

  • Short-lived (from a few minutes up to a maximum of 12 hours, depending on the request).

  • Scoped to specific permissions (defined by IAM roles and policies).

  • Automatically expire, reducing the risk if they get exposed.

It’s the key player on the OIDC implementation with AWS.

Key uses of AWS STS:

  1. AssumeRole – Allows one AWS service, user, or external identity (like GitHub via OIDC) to temporarily act as another role with specific permissions.

  2. Federation – Provides temporary credentials for external users authenticated by identity providers (like Google, Active Directory, GitHub).

  3. Cross-account access – Lets you securely access resources in another AWS account without creating permanent users.

  4. IAM role session management – Useful for apps, CI/CD pipelines, or temporary jobs that only need short-lived access.

Contrary to what you might think, this OIDC process falls under the second use case: Federation. This is because, initially, you don't have any AWS credentials. AWS federates an external identity into AWS to generate short-lived credentials. In other scenarios, you begin with AWS credentials and request temporary credentials to assume a role or start a new session for security reasons.

How does the AWS STS validation process works?

Here is a flowchart that describes in detail the validation process AWS STS performs to issue short-term credentials. This provides a deeper look into points 2 and 3 from the previous picture showing the general communication flow.

flowchart TD   A["Start: STS receives AssumeRoleWithWebIdentity request with OIDC token + RoleArn"] --> B["Check: Does IAM account have an OIDC provider for this issuer?"]   B -->|No| Z["Reject: InvalidIdentityToken"]   B -->|Yes| C["Verify TLS certificate or thumbprint of OIDC provider endpoint"]   C -->|Invalid| Z   C -->|Valid| D["Fetch JWKS from provider and verify JWT signature"]   D -->|Invalid signature| Z   D -->|Valid signature| E["Validate JWT standard claims: iss, aud, exp, nbf, iat"]   E -->|Expired / invalid| Z["Reject: ExpiredToken or InvalidIdentityToken"]   E -->|Valid| F["Evaluate IAM role trust policy conditions against token claims (sub, repository, ref, aud, etc.)"]   F -->|Claims don't match| Z["Reject: IDPRejectedClaim"]   F -->|Claims match| G["Issue temporary STS credentials (AccessKeyId, SecretAccessKey, SessionToken, Expiration)"]   G --> H["Return credentials to caller"]   H --> I["Caller uses temporary credentials for AWS API calls until expiration"]   I --> J["End"]

In simple terms, the validation process goes like this:

  • AWS checks whether it has configured GitHub as an identity provider.

  • It then verifies the authenticity of the OIDC token by checking if it was issued by GitHub and confirming its TLS certificate or thumbprint.

  • It verifies the token signature.

  • It compares the token payload claims against the properties set in the IAM Role trust policy, such as repository, branch, environment, sub, etc.

  • If everything is correct, AWS STS issues temporary credentials that are returned to the caller.

Conclusion

OpenID Connect (OIDC) lets your GitHub Actions talk to AWS in a secure, short-lived, and trust-based way. No need to deal with long-term access keys ever again.

With OIDC, you can ditch static credentials, skip the rotation headaches, and set up fine-grained permissions that map directly to your repo and branches. It’s cleaner, safer, and follows AWS’s best practices for least privilege and temporary credentials.

So really, what are you waiting for to switch to OIDC?

Next steps

In the next article, I’ll walk you through how to set up OIDC between AWS and GitHub step by step, so you can securely assume roles without adding extra complexity.