Skip to main content
cd ../config-traps
risk/register/renamed-github-repos-inherit-azures-oidc-trust.html
Azure Workload Identitycritical severityAzure AD Workload Identity Federation

Renamed GitHub Repos Inherit Azure's OIDC Trust

Overview

A Federated Identity Credential on an Azure Managed Identity keeps trusting a GitHub repository subject string long after that repository name is freed and reclaimed by an unrelated account. Azure AD's token exchange endpoint checks only the issuer, subject and audience tuple — not ownership continuity — so the new owner's workflow mints a valid OIDC token and inherits the identity's RBAC grants undetected.

At a glance

Unsafe setting
A Federated Identity Credential's subject claim is bound to a mutable GitHub org/repo name rather than an immutable repository ID.
Failure trigger
The original GitHub organisation or repository is renamed or deleted and the freed name is re-registered by a different account.
Blast radius
The new repository owner's Actions workflow mints an OIDC token matching the stale subject and exchanges it for the Managed Identity's Azure access token.
Recommended control
Pin trust to job_workflow_ref with a fixed commit SHA and audit federated credentials against GitHub's numeric repository_id, not display name.

The Trap

Federated Identity Credential subject binding to a GitHub repository by name rather than by its immutable repository ID.

The Default State

When you create a Federated Identity Credential on a User-Assigned Managed Identity or App Registration for GitHub Actions OIDC, the portal wizard writes the Subject identifier as repo:<org>/<repo>:ref:refs/heads/<branch> or repo:<org>/<repo>:environment:<name>. The Issuer is fixed at https://token.actions.githubusercontent.com and the Audience defaults to api://AzureADTokenExchange. Azure AD stores this as a static three-field tuple — issuer, subject, audience — and performs an exact string match against the sub, iss and aud claims presented in the client_assertion JWT during the OAuth2 exchange at /oauth2/v2.0/token. Nothing in that tuple references GitHub’s internal repository_id, and nothing re-validates ownership after the credential is created.

The Blast Radius

GitHub permits an organisation or repository name to be freed and immediately re-registered by an unrelated account the moment the original is renamed or deleted — a documented repojacking pattern. If your Federated Identity Credential still contains the old literal subject string, any new owner of that org/repo name — a different GitHub tenant, a separate business unit, or an external actor — can push a workflow run that mints an OIDC token with an identical sub claim. Azure AD’s token exchange endpoint has no visibility into GitHub’s repository lifecycle; it only checks the tuple match, so it issues a valid access token scoped to whatever role assignments the Managed Identity carries. The new owner inherits that RBAC, Key Vault access, or storage permission set, and Azure AD sign-in logs show nothing more suspicious than a routine federated token exchange from a trusted issuer.

The Lead Mechanic Fix

Audit every credential with az ad app federated-credential list –id <app-id> and cross-reference each subject string’s repository name against GitHub’s numeric repository_id via the REST API, not the display name. Where the workflow supports it, bind trust to the job_workflow_ref claim pinned to a specific reusable workflow path and commit SHA instead of a mutable branch ref, and scope Audience to a per-environment value rather than the shared default. Run a scheduled Azure Resource Graph query against federatedIdentityCredentials to flag any subject referencing a repository that no longer resolves under its original owner, and make credential removal a mandatory step in the repository transfer and deletion runbook, not an optional cleanup task.