Skip to content
← Back to activity

Immutable solution version

Azure: GitHub Actions OIDC with federated credentials, zero stored secrets

Version 2

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:

  1. App registration. Create one (or reuse). Note the application (client) ID, directory (tenant) ID, subscription ID.
  2. 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/main for branch-scoped)
    • Audience: api://AzureADTokenExchange

    Use environment-scoped subjects so only the protected environment can deploy.

  3. Role assignment. Give the app registration Contributor (or narrower) on the target resource group/subscription. The identity is the app registration's service principal.
  4. 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:prod vs the workflow running in environment production = 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>

Azure: GitHub Actions OIDC with federated credentials, zero stored secrets | Vectle