Create a federated identity credential on a Microsoft Entra app registration that trusts GitHub's token issuer and one exact subject, such as an environment. The workflow then exchanges its GitHub token for an Azure access token, so no client secret is stored in your repository.
What a federated identity credential is
Microsoft describes it as a trust relationship between an app in Entra ID and an external identity provider. The external workload exchanges a token from that provider for an access token from the Microsoft identity platform, and can reach protected resources without secrets or certificates, in supported scenarios.
The trust is defined by three fields: issuer, subject and audience. For GitHub Actions the issuer is https://token.actions.githubusercontent.com, the recommended audience is api://AzureADTokenExchange, and the subject identifies your organization, repository and trigger.
Steps
- Create an app registration, or a managed identity, and grant it only the Azure roles the deployment needs.
- In the app's certificates and secrets area, open the federated credentials tab and add a credential for the scenario "GitHub Actions deploying Azure resources".
- Enter the organization and repository, then choose an entity type: environment, branch, pull request or tag.
- Give it a name. The name cannot be changed later.
- In the workflow, set
id-token: writepermission and sign in with the client ID, tenant ID and subscription ID. The client and tenant IDs come from the app registration overview. - Run the workflow and confirm the login step succeeds.
Subject formats
Microsoft's page lists these shapes for GitHub:
| Trigger | Subject |
|---|---|
| Job tied to an environment | repo:ORG/REPO:environment:NAME |
| Branch or tag | repo:ORG/REPO:ref:refs/heads/NAME or refs/tags/NAME |
| Pull request | repo:ORG/REPO:pull-request |
The docs say values must match the GitHub workflow configuration exactly, and that wildcard characters are not supported in any federated identity credential property. Pattern matching for branches and tags is not available either. If your workflow runs on many branches or tags, Microsoft suggests using an environment.
Check the current GitHub documentation too. GitHub says repositories created after 15 July 2026 use an immutable subject format with owner and repository IDs, so a credential copied from an older example may not match.
Limits and traps
Two points from Microsoft's documentation save debugging time.
First, an incorrect subject does not produce an error when you create the credential. The credential is created successfully and the failure appears only when the token exchange is attempted, and it fails without a helpful message. When login fails, compare the subject character by character.
Second, a maximum of 20 federated identity credentials can be added to one app or user assigned managed identity. If you deploy from many repositories or environments, plan identities by purpose instead of piling credentials onto one app.
Also note who can create these. The person must own the app or hold a role such as Application Administrator, so treat that permission like any other that changes who can access production.
A sensible layout
Use one identity for production deploys, trusted only for the production environment, with required reviewers on that environment. Use a separate identity with read access for pull request checks. Keep the Azure role assignments narrow and scoped to a resource group rather than a subscription where possible.
Quick check
Can I use a wildcard in the subject?
No. Microsoft states wildcard characters are not supported in any federated identity credential property value.
Why does login fail silently with a wrong subject?
The credential is created without validation, and the mismatch only shows when the token exchange runs. Recheck the subject against the actual workflow trigger.
Safeguard does not manage your cloud accounts. It scans your code and dependencies, applies pull request policies and gates, and automates compliance evidence. Free scan: gold.safeguard.sh/scan.
Sources
- Microsoft Learn: Create a trust relationship between an app and an external identity provider
- GitHub Docs: OpenID Connect reference
Last reviewed: 19 October 2026.