Skip to content
LearnIAM role trust policy

What is an IAM role trust policy?

Also known asassume role policyAssumeRoleWithWebIdentity
Example. Kiteline is a fictional company.
On this page

An IAM role trust policy is the document attached to an AWS IAM role that defines who is allowed to assume the role, that is, which AWS accounts, services or external identity providers may obtain the role's temporary credentials, and under which conditions.

Two policies on every role

AWS splits a role into two questions. The trust policy "specifies who can assume the role". The permissions policy "specifies the AWS actions and resources" the role may use (AWS). A role with tight permissions and a loose trust policy is still a problem: the wrong caller gets the right permissions.

For CI with OIDC, the trust policy names an OIDC identity provider as the Federated principal, allows the action sts:AssumeRoleWithWebIdentity, and adds conditions on the claims of the job's token. A job presents its JWT; AWS checks it against the provider and the conditions, and returns temporary credentials.

JSON
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "Federated": "arn:aws:iam::012345678910: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:kiteline/web-app:environment:production"
      }
    }
  }]
}

This one accepts only jobs of kiteline/web-app that deploy to the GitHub environment production. Kiteline is a fictional company.

Example. Kiteline is a fictional company. Claim names and endpoints follow GitHub Actions and AWS STS documentation.

The conditions that matter

  • aud, the audience, so a token minted for another service isn't accepted.
  • sub, the subject claim, so only your repository and branch or environment qualify.

AWS enforces part of this for GitHub. When GitHub's provider is the trusted principal, IAM checks that the sub condition key "is present and that its value is not solely a wildcard character", and rejects the policy otherwise. It also warns that if you don't limit sub to a specific organization or repository, "GitHub Actions from organizations or repositories outside of your control are able to assume roles" in your account.

Common mistakes

  • StringLike with a broad pattern. repo:kiteline/* trusts every repository in the organization, now and later.
  • Branch subjects for production. Any branch push that can run a workflow then gets production. Prefer an environment subject and add protection rules to that environment in GitHub.
  • The wrong subject format. Repositories created on GitHub after July 15, 2026 use subjects with numeric IDs (GitHub), and a policy for the old format silently fails to match.
  • One role for every job. Tests and production deploys then share the same trust and the same permissions.

Crunu and trust policies

Crunu is not part of AWS and doesn't create IAM roles. Two things connect it to this topic. The free OIDC trust policy builder writes trust policies for AWS, and the Google Cloud and Azure equivalents, from a repository, branch and environment, in both GitHub subject formats. And for values that aren't AWS credentials, a Crunu service token can carry its own CI binding (OIDC) with the same idea: rules on the repository, branch and environment, checked by the Crunu server. The complete setup for each cloud is in CI/CD secrets with OIDC.

Sources

From the blog

  • CI/CD

    GitHub's new OIDC subject format: fixing AWS trust policies

    Not authorized to perform sts:AssumeRoleWithWebIdentity on a new repo? GitHub added owner and repo IDs to the OIDC sub claim. How to check and fix the policy.

    CI and OIDC guide

  • Migration

    HCP Vault Secrets is gone: choosing where to move

    HCP Vault Secrets reached end of life on July 1, 2026. HashiCorp's suggested paths, what Vault Community lacks, and how the alternatives differ on who decrypts.

    Who can decrypt guide

  • CI/CD

    GitLab CI OIDC without Premium: id_tokens on the Free tier

    The secrets keyword needs GitLab Premium, but id_tokens works on Free. How to exchange a job's ID token for AWS, Google Cloud, Azure or Crunu by hand.

    CI and OIDC guide