Skip to content

OIDC with Azure

1. Create an app registration (or managed identity)

Section titled “1. Create an app registration (or managed identity)”
Terminal window
az ad app create --display-name slipway-deployer
az ad sp create --id <appId>
Terminal window
az ad app federated-credential create --id <appId> --parameters '{
"name": "slipway-prod",
"issuer": "https://slipway.example.com",
"subject": "<exact sub from a test job>",
"audiences": ["api://AzureADTokenExchange"],
"description": "Slipway production deploys"
}'

Azure matches the subject exactly, so create one credential per environment or pipeline you want to allow. Read the real sub from a test job’s token (see OIDC job tokens).

Terminal window
az role assignment create --assignee <appId> --role "Contributor" \
--scope /subscriptions/<sub>/resourceGroups/prod-api

Scope to a resource group, not the subscription.

permissions: { id_token: write }
jobs:
- name: deploy
environment: { name: production, service: api }
steps:
- run: |
az login --service-principal \
--username "$AZURE_CLIENT_ID" --tenant "$AZURE_TENANT_ID" \
--federated-token "$SLIPWAY_ID_TOKEN"
az containerapp update -n api -g prod-api --image "$IMAGE"
env:
AZURE_CLIENT_ID: ${{ vars.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ vars.AZURE_TENANT_ID }}

Client and tenant IDs are not secrets; keep them as variables. The token’s audience must be api://AzureADTokenExchange. The built-in Azure integration takes the tenant, client and subscription IDs once and handles the exchange for AKS, App Service, Container Apps and Azure Monitor.