Article · Repository & Cloud Security

GitHub Actions OIDC Removes a Secret, Not the AWS Trust Problem

Federation changes how a workflow authenticates. It does not decide which workflow should be trusted or what the resulting session can change.

Published 5 min read

By

All articles
GitHub ActionsOIDCAWSIAM
Trust & provenance3 primary sources · reviewed Aug 12, 2026 · next review Nov 10, 2026
Trust and provenance

Editorial record

AI-assistance disclosure

AI assisted with repository-grounded drafting and source-packet assembly; Bryan Oubaita completed author review on 2026-08-12, and publication approval was recorded separately.

A human review was recorded.

Recorded limitations

  • GitHub claim formats and AWS integration guidance are platform-dependent and must be rechecked before using any example.
  • The Article does not provide a universal trust policy or inspect a production AWS account.

Sources

  • GitHub DocsOpenID Connect reference

    Audience and subject claims are used to constrain which workflows can receive cloud access.

    Retrieved
    Reuse
    link-only
  • GitHub DocsConfiguring OpenID Connect in Amazon Web Services

    AWS federation removes long-lived GitHub secrets and requires predictable trust-policy conditions.

    Retrieved
    Reuse
    link-only
  • Amazon Web ServicesPolicy evaluation logic

    The federated session's effective authority depends on policy types and explicit-deny behavior beyond role trust.

    Retrieved
    Reuse
    link-only

GitHub Actions OIDC removes the need to store long-lived AWS access keys as repository or organization secrets. That is a meaningful reduction in credential exposure. It does not answer which workflow can obtain a session, what role it can assume, what the session can do, or which downstream resources will honor it.

The security boundary is the entire path:

workflow trigger → OIDC token → IAM trust policy → STS session → permission policies → resource policies → effect

Authentication changed; authority did not disappear

GitHub’s AWS guide describes OIDC as a way for workflows to access AWS without storing long-lived credentials and recommends constraining the trust policy so access tokens are issued predictably. GitHub AWS OIDC guide

That change removes one secret lifecycle: creation, storage, rotation, accidental disclosure, and revocation of static access keys in GitHub. It replaces it with a federation lifecycle that must govern:

  • which GitHub issuer is trusted;
  • which audience is accepted;
  • which repository, owner, branch, tag, pull request, or environment can appear in the subject;
  • which workflow can request an ID token;
  • which AWS role the token can assume;
  • how long and under which session constraints the role operates;
  • which resources accept the resulting principal.

The subject condition is a security boundary

GitHub documents the aud and sub claims as common inputs to cloud trust conditions. Subject formats can encode repository, branch, pull-request, tag, or environment context, and GitHub now documents immutable-subject behavior for eligible repositories. GitHub OIDC reference

A policy that trusts only the issuer but does not constrain the relevant subject can expand trust far beyond the intended workflow. Conversely, a branch-specific condition can be undermined operationally if untrusted contributors can modify that branch’s workflow or the actions it invokes. The trust review must therefore include repository governance, workflow file ownership, trigger types, environment protection, action pinning, and token permissions.

An example policy is only safe relative to the exact subject format in use. Copying a policy from documentation without confirming the token claims from the target repository risks either excessive trust or a non-working deployment.

For example, the following trust policy is intentionally narrow and illustrative. It admits the default AWS audience and one GitHub environment subject; it is not copy-ready because the account, repository governance, environment protections, actual token claims, and role permissions still require verification:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
          "token.actions.githubusercontent.com:sub": "repo:octo-org/octo-repo:environment:Production"
        }
      }
    }
  ]
}

The useful review is to compare every literal in that condition with the claims GitHub actually issues for the protected job, then inspect who can change the workflow and pass the environment gate. A syntactically valid trust statement does not establish that the resulting role is least-privileged.

Role trust and role permissions solve different problems

The role trust policy answers who may assume the role. Identity policies, permissions boundaries, session policies, service control policies, resource policies, and explicit denies determine what the resulting principal can do. AWS documents union and intersection behavior across these policy layers and gives explicit deny precedence. AWS IAM evaluation logic

A narrowly scoped sub condition attached to a role with broad administrative permissions still creates a high-impact workflow. A broad trust condition attached to a tightly scoped read-only role is a different risk. Both need review because trust and reach compose.

Worked authority path

Consider a deployment job that can assume an AWS role and update an ECS service. Review the path in this order:

  1. Trigger: Which events can start the job? Can a pull request or fork reach it?
  2. Workflow authority: Who can edit the workflow and referenced local actions?
  3. Token issuance: Does the job have id-token: write, and only where needed?
  4. Claims: What exact iss, aud, and sub values does GitHub issue for the protected environment?
  5. Trust policy: Are those values matched precisely enough for the intended owner, repository, and environment?
  6. Session: Are duration, tags, or session policies used where appropriate?
  7. Role permission: Can the role only update the intended service and related artifacts?
  8. Resource policy: Do KMS keys, buckets, registries, or secrets add access not visible in the identity policy alone?
  9. Downstream effect: Can deployment configuration cause another principal to execute code with broader authority?
  10. Evidence and recovery: Can responders identify and revoke the session, restore the previous deployment, and prove the result?

Common review failures

  • Treating removal of static credentials as completion of the security review.
  • Constraining the repository but not the branch, environment, or subject form appropriate to the job.
  • Reviewing the trust policy without reviewing the role’s permissions.
  • Ignoring reusable workflows, third-party actions, or workflow-edit authority.
  • Allowing deployment authority from pull-request contexts without an independent approval boundary.
  • Failing to pin the analysis to the current GitHub claim format and AWS documentation.

Practical takeaways

Adopt OIDC to remove long-lived CI credentials, then review the trust path that remains. Bind the expected claims, constrain workflow edit and trigger authority, minimize the role, inspect resource policies, and preserve enough evidence to revoke and recover.

Continue with Secure AWS Architecture: Decisions, Controls, Evidence, and Recovery for the broader AWS trust-boundary and verification model.

Limitations

This Article is an architecture review, not a copy-ready trust policy. GitHub claim formats, immutable-subject eligibility, and integration guidance can change. AWS service authorization also has service-specific behavior, especially around resource policies and KMS. Every implementation must inspect its actual token claims, repository governance, role configuration, and resource policies. No BaitaPhish production AWS configuration is asserted here.