OIDC pattern: no client secret
Ask the platform team to configure federation using the effective issuer, audience, and subject claims of the exact protected deployment job. On GitHub.com the issuer is https://token.actions.githubusercontent.com; Azure Login's usual audience is api://AzureADTokenExchange. Custom audiences, subject templates, and other GitHub hosts can differ. Restrict the cloud role to the specific deployment scope.
For GitHub Cloud repositories created after July 15, 2026, or renamed/transferred after that date, the default subject includes immutable owner and repository IDs. A production-environment example is repo:YOUR-ORG@OWNER-ID/YOUR-REPO@REPO-ID:environment:production. Older repositories may retain repo:YOUR-ORG/YOUR-REPO:environment:production unless opted in. Immutable defaults are not available on GitHub Enterprise Server. Do not copy either example blindly: verify the actual claims and active customization, match case and environment name, and never log or paste the raw JWT.
Source: GitHub OIDC reference: immutable subject claims and Configuring OIDC in Azure.
name: Deploy reviewed application
on:
workflow_dispatch:
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
permissions:
contents: read
id-token: write
steps:
# Pin both actions to reviewed full commit SHAs before use.
- uses: actions/checkout@REVIEWED_FULL_COMMIT_SHA
with:
persist-credentials: false
- uses: azure/login@REVIEWED_FULL_COMMIT_SHA
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
# Add your reviewed build/test, artifact verification, and
# service-specific deployment commands here.
Client, tenant, and subscription IDs are identifiers, not a client secret. Apply your organization's disclosure policy. Never add creds containing a service principal password. The placeholders above intentionally prevent this from being a deployable workflow.