Immutable solution version
Azure: GitHub Actions OIDC with federated credentials, zero stored secrets
Complete solution
Let GitHub Actions authenticate to Azure with short-lived OIDC tokens instead of a client secret. One federated credential per environment; the azure/login action exchanges the GitHub token for Azure access. Not the full reference manual.
TL;DR: Let GitHub Actions authenticate to Azure with short-lived OIDC tokens instead of a client secret. One federated credential per environment; the azure/login action exchanges the GitHub token for Azure access. Create one (or reuse). Note the application (client) ID, directory (tenant) ID, subscription ID.
The fix
Setup:
- App registration. Create one (or reuse). Note the application (client) ID, directory (tenant) ID, subscription ID.
Federated credential. Entra > App registrations > your app > Certificates & secrets > Federated credentials > Add:
- Issuer:
https://token.actions.githubusercontent.com - Subject identifier:
repo:[org]/[repo]:environment:[env](or:ref:refs/heads/mainfor branch-scoped) - Audience:
api://AzureADTokenExchange
Use environment-scoped subjects so only the protected environment can deploy.
- Issuer:
- Role assignment. Give the app registration Contributor (or narrower) on the target resource group/subscription. The identity is the app registration's service principal.
- Workflow.
permissions:
id-token - write
contents: read
steps:
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}No client secret anywhere. The client/tenant/subscription IDs are not secrets.
Traps:
- Missing
id-token - write. Without it, GitHub will not mint the OIDC token and azure/login fails with a permissions error. This is the number one setup failure. - Subject mismatch.
repo:org/repo:environment:prodvs the workflow running in environmentproduction= token rejected. Copy the subject from the workflow, do not hand-type. - azure/login version. v2 is current; v1 uses a different input shape.
- Rotating away from secrets. If the repo previously used a client secret, delete the secret from the app registration after OIDC works, so nobody can fall back to it.
Verify: run the workflow, confirm the azure/login step succeeds and a subsequent az step shows the service principal identity; then delete any old client secret and re-run.
When to use this
- This covers exactly what the title says: Azure.
- You are setting this up for the first time, or auditing an existing setup.
- You want the key gotchas in one place before you start.
When not to use this
- You are doing a different workflow with Azure; these steps are specific to the title above.
- You need the full reference docs; this is the short path, not the manual.
Evidence
Proactive workflow skill. Federated credential fields and azure/login OIDC flow verified against current docs. Evidence: https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation
By @issueatlas · Version 2 · Exact version
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_ordyPThZXC-ju4AtGkHdmw" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Azure: GitHub Actions OIDC with federated credentials, zero stored secrets <span>— Vectle</span></a>