GitHub - Azure - OIDC - Custom Claims setup to enable all GitHub repositories to connect to Azure.

We often connect to cloud providers to deploy an infrastructure or apply a change to an application using GitHub workflow using an action. To access any resources within the Cloud, the workflow needs to be connected using a either providing credential or using the OIDC federated trust based between GitHub and the cloud provider. Here we will see how to customise and harden the OIDC connection between the GitHub and Azure for an Enterprise account.

More details on setting up the OIDC based connectvity between the GitHub and Azure can be found below.

a. Overview of OpenID Connect
b. Setup AzureAD application to allow GitHub workflow to connect.

Azure GitHub OIDC

The default Azure GitHub OIDC setup accepts subject, issuer and audience input.

So when a GitHub workflow tries to authenticate against an Azure AD, Azure will validate the incoming federated token received and authenticates it.

By default, GitHub workflow sends the above claims to Azure with the below claims
a. subject as “repo:/:environment:"
b. audience as "api://AzureADTokenExchange"
c. issuer as ""

Enable unique issuer url for an enterprise

For an Enterprise GitHub account, Azure AD SP can be configured to receive token only from a unique url rather than from a default “” GitHub token issuer using the below script.

gh api --header 'Accept: application/vnd.github+json' --header 'X-GitHub-Api-Version:2022-11-28' --method PUT<enterprise name>/actions/oidc/customization/issuer -F include_enterprise_slug=true

The above script enables GitHub to send a unique issuer url to the AzureAD to verify.

Update the Azure AD Application to include the Custom Unique Url and Environment Only

Configure Custom Claim on the repository

By default, the workflow on a repository sends the repository context on the “subject” claim. This can be amended using the below script to include the context only.

Setup Organisation level claim for the subject

Include “context” only into the subject claim at the organisation level.

gh api --header 'Accept: application/vnd.github+json' --header 'X-GitHub-Api-Version:2022-11-28' --method PUT<org name>/actions/oidc/customization/sub -f include_claim_keys[]="context"

Setup repo level claim for the subject

Configure the repository to use the organisation level claim setup.

gh api --header 'Accept: application/vnd.github+json' --header 'X-GitHub-Api-Version:2022-11-28' --method PUT<org name>/<repo name>/actions/oidc/customization/sub  -F use_default=false

Run the workflow again to login to the Azure AD, with the updated claim.

  - name: Login
        run: |
          oidctoken=$(curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange")
          JWT=$(echo $oidctoken | jq -j '.value')
          jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< $JWT
          az login --service-principal -u <client-id> -t <tenant-id> --federated-token $JWT


a. Run “gh auth refresh -h -s admin:org” to refresh the token, to login as organisation adminministrator, if there is an authorisation error.
b. Each invidual repo needs to be configured to use the organisation level configured claim using the rest api or it can be automated to scan the repositories and configure to use the organisation level claim setup.
c. List of claims supported by GitHub OIDC can be retrieved using the link.

Written on September 11, 2023