"category": "Risks" · job/oidc-subject-recycling
Subject recycling: when a deleted GitHub name still unlocks your cloud role
Trust rules that match names can be satisfied by whoever registers that name next. What the 2026 research found, what GitHub, GitLab and the clouds changed, and how to audit your own roles.
- Shared issuers sign tokens for every customer; the sub claim is what separates one tenant from another.
- If that sub is built from names, a deleted or renamed namespace can be registered again by someone else.
- Astrix Security reported in June 2026 that about 14% of AWS and 24% of Azure namespaces referenced in its sampled trust policies were unregistered.
- Match numeric IDs and remove trust for repositories and organizations you no longer own.
GitHub, GitLab.com and HCP Terraform each sign tokens with one issuer for all of their customers. AWS calls these shared providers.[AWS IAM User Guide] Because everyone’s tokens come from the same issuer, the cloud tells tenants apart by reading the subject and other claims. When those claims are names, the trust is only as permanent as the names.
How does the attack work?
- Your trust policy allows
repo:old-org/deploy:ref:refs/heads/main. old-orgis renamed or deleted. The trust policy is forgotten and stays in place.- Someone registers
old-org, creates adeployrepository and runs a workflow onmain. - GitHub issues a token whose
subisrepo:old-org/deploy:ref:refs/heads/main. Your cloud accepts it.
Astrix Security published this as “Sub:jugation” on June 1, 2026.[Astrix Security] It covers GitHub Actions, GitLab CI and HCP Terraform as issuers, with AWS, Azure and Google Cloud as targets. In their sample, roughly 14% of AWS namespaces and 24% of Azure namespaces referenced in trust policies were unregistered, so anyone could have claimed them.
What did the platforms change?
- GitHub moved to the immutable subject format, which embeds owner and repository IDs. It became the default for repositories created, renamed or transferred after July 15, 2026; older repositories must opt in.[GitHub Changelog] Astrix reports that GitHub also rolled out a fix on May 28, 2026.[Astrix Security]
- GitLab blocks ID token issuance when a project path in
subwas previously used by a different project, and recommends startingsubwith an ID component (ci_id_token_sub_claim_components) so trust policies matchproject_id.[GitLab Docs] - HCP Terraform added warnings when an organization name changes, according to Astrix; a permanent fix was still pending at publication.[Astrix Security]
- AWS, Microsoft and Google all document ID-based matching: AWS recommends
repository_id,repository_owner_idandactor_idcondition keys;[AWS IAM User Guide] Microsoft describes “subject recycling” and publishes a migration to immutable subjects;[Microsoft Learn] Google warns that name fields invite squatting and recommends*_idclaims.[Google Cloud documentation]
Platform fixes protect new configurations. They do not rewrite trust policies you already have.
How do I audit my own trust?
1. List everything that trusts a shared CI issuer
AWS (per account):
aws iam list-roles \
--query "Roles[?contains(to_string(AssumeRolePolicyDocument), 'token.actions.githubusercontent.com')].RoleName"
Repeat with gitlab.com and app.terraform.io if you use them.
Microsoft Entra (per app registration):
az ad app federated-credential list --id <application-object-id>
Google Cloud (per pool):
gcloud iam workload-identity-pools providers list \
--workload-identity-pool=POOL_ID --location=global
2. Extract the names each rule depends on
From each sub pattern or condition, note the owner (organization or user) and repository. For Google Cloud, also note names used in assertion.repository_owner or assertion.repository conditions.
3. Check each name is still yours
gh api orgs/OLD-ORG # 404 means the organization does not exist
gh api users/OLD-ORG # personal accounts are under /users
A 404 means the name is unregistered. A name that exists but that your organization does not control is already someone else’s. Either way, that trust should go.
4. Switch the rest to IDs
For names you still own, add the numeric IDs (immutable sub, or repository_id and repository_owner_id conditions) and then remove the name-only rule. The immutable subject guide has the steps for each cloud, and the OIDC trust checker flags name-only trust as a warning.
How do I stop it happening again?
- Delete cloud trust in the same change that archives or transfers a repository.
- Prefer one role or credential per repository and environment, so ownership is obvious.
- Re-run the audit on a schedule that matches how often teams create and retire repositories.
Questions people ask
- Does GitHub's immutable subject format fix this on its own?
- For trust rules that match the immutable sub or the ID claims, yes: a recreated repository gets a new ID. Rules that still match the name-only format, or repository and repository_owner names, keep the exposure.
- Is this only a GitHub problem?
- No. The research covered GitHub Actions, GitLab CI and HCP Terraform, and the same reasoning applies to any shared issuer whose subject is built from names.
- How do I know whether a namespace still belongs to us?
- Look it up while signed in as an owner. For GitHub, an organization or user that returns 404 from the REST API is unregistered and could be claimed. One that exists but is not yours is already someone else's.
Sources
- Sub:jugation: Hijacking Cloud Identities by Recycling Namespaces in Global OIDC Issuers — Astrix Security.# vendor security research · checked November 10, 2026 (full article text)
- Immutable subject claims for GitHub Actions OIDC tokens — GitHub Changelog.# official announcement (issuer) · checked November 10, 2026 (full page text)
- OpenID Connect (OIDC) authentication using ID tokens — GitLab Docs.# official documentation (issuer) · checked November 10, 2026 (full page text)
- Migrate GitHub Actions federated credentials to immutable subjects — Microsoft Learn.# official documentation · checked November 10, 2026 (full page text (page dated 2026-07-28))
- IAM and AWS STS condition context keys — available keys for AWS OIDC federation — AWS IAM User Guide.# official documentation · checked November 10, 2026 (first 100,000 characters of the page (the GitHub and default OIDC sections were inside that range))
- Configure Workload Identity Federation with deployment pipelines — Google Cloud documentation.# official documentation · checked November 10, 2026 (full page text)
- Identity-provider controls for shared OIDC providers — AWS IAM User Guide.# official documentation · checked November 10, 2026 (full page text)
Update history
- — First published.
Related guides
3 jobs- job/github-oidc-immutable-subject category CI/CD federation
GitHub's immutable OIDC subject claims, fixed in AWS, Azure and Google Cloud
Repositories created after July 15, 2026 send a new sub format with owner and repository IDs. What changed, how to tell which format you get, and the trust changes for each cloud.
· 8 min - job/github-actions-aws-oidc category CI/CD federation
Scoping a GitHub Actions trust policy in AWS
Which condition keys to use in an IAM role trust policy for GitHub Actions, which ones are immutable, and worked examples for a branch, an environment and a reusable workflow.
· 8 min - job/github-oidc-trust-aws category CI/CD federation
One workflow, three clouds: how AWS, Azure and Google Cloud match GitHub OIDC tokens
The same GitHub Actions token is checked three different ways. A side-by-side comparison of where the trust lives, how claims are matched, wildcard support, limits and how failures show up.
· 7 min