January 2026 AWS Condition Keys: What Changed and Why It Matters
In January 2026, AWS added new condition context keys for GitHub Actions OIDC trust policies. This was a quiet update — no blog post, no re:Invent announcement — but it fundamentally changes how you should write trust policies for GitHub Actions federation.
The problem: mutable identifiers
Before January 2026, the standard way to restrict an OIDC trust policy to a specific GitHub repository was to use the sub claim with the repository name:
{
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:ref:refs/heads/main"
}
}
}
The problem: my-org/my-repo is a mutable identifier. If someone renames the repository, transfers it to another organization, or deletes and recreates it with the same name, the trust policy still matches. The identity the policy was written for no longer exists, but something with the same name does.
This isn't theoretical. GitHub repository transfers happen routinely during acquisitions, reorganizations, and open-source project migrations.
The fix: immutable condition keys
AWS now supports these condition context keys for GitHub's OIDC provider:
repository_id— The immutable numeric ID of the repository. Survives renames and transfers.actor_id— The immutable numeric ID of the GitHub user who triggered the workflow.repository_owner_id— The immutable numeric ID of the organization or user who owns the repository.runner_environment— Whether the workflow is running on GitHub-hosted or self-hosted runners.
These are part of the OIDC token claims that GitHub sends to AWS. They've always been in the token — AWS just didn't allow you to use them in trust policy conditions until January 2026.
How to update your trust policies
Before (mutable):
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:sub"
values = ["repo:my-org/my-repo:ref:refs/heads/main"]
}
After (immutable):
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:sub"
values = ["repo:my-org/my-repo:environment:production"]
}
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:repository_id"
values = ["123456789"]
}
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:repository_owner_id"
values = ["987654321"]
}
The repository_id is a belt-and-suspenders approach alongside the sub claim. Even if the repository name changes, the immutable ID check will either still match (same repo, renamed) or fail (different repo with the same name).
Finding your repository_id
Your repository's immutable ID is available via the GitHub API:
curl -s https://api.github.com/repos/my-org/my-repo | jq .id
Or in any GitHub Actions workflow, it's available as github.repository_id.
What our scan found
In our 10,000-repo scan, we analyzed how repositories reference their identity in OIDC trust policies. The vast majority still use mutable repository names. Adoption of the January 2026 immutable keys is near zero in public repositories — the feature is too new and there's been minimal documentation from AWS about the change.
This creates a temporal window: teams that adopt these keys now have a meaningful security advantage over those who haven't heard about the update.
What to do today
- Add
repository_idconditions to all OIDC trust policies alongside your existingsubconditions - Add
repository_owner_idto prevent cross-organization confusion - Use
StringEquals(notStringLike) for all condition comparisons - Add an
environmentcondition for production-critical roles
TrustFix detects trust policies that are missing immutable condition keys and generates the Terraform fix automatically. Try it at trustfix.dev.
The condition keys referenced in this post are documented in AWS's OIDC federation documentation.
Subscribe to our newsletter
Get OIDC security research and AWS IAM insights delivered to your inbox. 2-3 posts per month.
