# What is an IAM role trust policy?

> A trust policy is the part of an AWS IAM role that says who may assume it. How it works with OIDC and AssumeRoleWithWebIdentity, and the conditions to pin.

URL: https://crunu.com/learn/iam-trust-policy
Language: en
Updated: 2026-10-30

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](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html)). 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](https://crunu.com/learn/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.

*Figure: Diagram of a GitHub Actions job signing in to AWS STS with OIDC. Step 1: the job asks the GitHub Actions issuer for an ID token. Step 2: the issuer signs a JWT naming the repository kiteline/web-app and the branch main. Step 3: the job presents the JWT to AWS STS, which checks the issuer, the audience, the repository and the branch. Step 4: AWS STS returns short-lived credentials, and no long-lived cloud key is stored in CI.*

## The conditions that matter

- **`aud`**, the audience, so a token minted for another service isn't accepted.
- **`sub`**, the [subject claim](https://crunu.com/learn/oidc-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](https://docs.github.com/en/actions/reference/security/oidc)), 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](https://crunu.com/tools/oidc-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](https://crunu.com/guides/ci-cd-secrets-with-oidc).

## Sources

- [AWS IAM: Create a role for OpenID Connect federation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html), checked October 30, 2026.
- [GitHub Docs: OpenID Connect reference](https://docs.github.com/en/actions/reference/security/oidc), checked October 30, 2026.
