Azure AD Workload Federation anywhere?

I decided to write an post into creation of Azure AD Workload Identity using the option ’Workloads running in compute platforms outside of Azure’ covered @ MS DOCS.

The ultimate simplification of workload federation is using Azure AD Client Credentials flow with client private key signed token, where metadata is provided to Azure AD via Discovery URL, and then public key which Azure AD uses to check the signature is provided by JWKS uri (discovered via metadata endpoint)

This felt quite trivial, as I’ve covered the use of Client Credentials flow with certificate in multiple posts. Why this matters, is that Azure AD Workload Federation is almost 1:1 to scenarios which I’ve covered previously – except you don’t store the public key in Azure, but rather provide it by metadata endpoint (.well-known/..) that points to the separate JWKS uri.

  • In my previous examples I’ve used Azure Functions to provide the metadata endpoint, but this time I am just going to use blob storage to achieve this as covered in this excellent guide by MS

Diagram from MS DOCS: https://docs.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation#how-it-works


  • While not demonstrated in this example, you could use single endpoint to cater multiple workload identities
  • No need to upload public key Azure AD (ease of use)
    • Some might still prefer uploading the public key to Azure, when reliance for the external IDP is to be minimized, as even if the IDP would be down, any client credentials using client could could still request tokens from Azure AD without the external IDP being awake)

Previously covered

I included these posts here because they cover code, workflow diagram, and setting up OIDC metadata endpoint with GH actions which I’ve done previously

Azure AD Client Credentials with Certificate – Code Examples for Node.js

Walktrough ( using blob storage example from AKS workload federation example )

For the discovery document (.well-known/..) I am going to use the example provided here (The example also covers the use and creation of JWKS document)

For the JWKS document I am going to use previous example I have created with Azure Functions, but upload the JWKS document this time to Azure Blob Storage instead of using functions.

Example of the endpoints

Azure AD Configuration

  • Issuer needs to match to that of configured for the endpoint.
  • You can use custom audience, but I opted for the familiar audience value
Settings under credentials – federated credentials

Getting AAD issued tokens for workload Identity

I used slightly modified version of Azure AD Client Credentials with Certificate – Code Examples for Node.js

Issued tokens

Token payload created by the client (signed by the private key)

subject, issuer and audience values are the critical ones here.

  header: { alg: 'RS256', typ: 'JWT', x5t: 'nnMrEpA2R_ECV1jBy-Wlq6qNvx0=' },
  payload: {
    aud: 'api://AzureADTokenExchange',
    iss: 'https://oidcissuerb128517a.blob.core.windows.net/oidc-test/',
    sub: 'oidcissuerb128517a',
    actor: 'jose@securecloud.blog (this value is not needed)',
    jti: 'f26d803a-1cdf-4a6c-bdb6-2bb3af5e303e',
    exp: 1653286228,
    iat: 1653282628

Azure AD Issued Token

The request returned V2 token, so some of the attributes are bit different from V1 token

azp (click the link for more examples)- Only present in v2.0 tokens, a replacement for appid.

  "typ": "JWT",
  "alg": "RS256",
  "kid": "jS1Xo1OWDj_52vbwGNgvQO2VzMc"
  "aud": "fb60f99c-7a34-4190-8149-302f77469936",
  "iss": "https://login.microsoftonline.com/033794f5-7c9d-4e98-923d-7b49114b7ac3/v2.0",
  "iat": 1653282328,
  "nbf": 1653282328,
  "exp": 1653286228,
  "aio": "E2ZgYHg0Q/A7942d8/0eSS6q1az9BAA=",
  "azp": "a992567e-0dfe-4d37-9741-5a849cb6932d",
  "azpacr": "2",
  "oid": "03461c6e-600b-4f95-957f-f3a350098fad",
  "rh": "0.AYIA9ZQ3A518mE6SPXtJEUt6w5z5YPs0epBBgUkwL3dGmTaCAAA.",
  "sub": "03461c6e-600b-4f95-957f-f3a350098fad",
  "tid": "033794f5-7c9d-4e98-923d-7b49114b7ac3",
  "uti": "FCTEIjmgpkSkQD-AWA6EAA",
  "ver": "2.0"
  • I also tested requesting tokens for other resources, such as MS graph api

Code snippet (Does not include depedencies, but gives an idea of the flow)

const {createToken} = require('./src/getAADtokenWithCert')
const {getKey, jwtverify} = require('./src/helpers')
const { decode } = require('jsonwebtoken')
const { default: axios } = require('axios')
const { axiosClient } = require('./src/axioshelpers')

var priv = require('fs').readFileSync('./private1.pem').toString()

getToken().then((token) => {


async function getToken() {

    var claims = {
        "aud": `api://AzureADTokenExchange`,
        "iss": "https://oidcissuerb128517a.blob.core.windows.net/oidc-test/",
        "sub": "oidcissuerb128517a",

// testing locally that signature matches

var det =await getKey(`https://oidcissuerb128517a.blob.core.windows.net/oidc-test/openid/v1/jwks`)    

var {x5t, key} = det

     var jwt = await createToken(x5t,priv,claims).catch((error) => {
        return error

    var res =await jwtverify(jwt,key)

// request token from Azure AD 
    let opt = {
            grant_type: "client_credentials",
            client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
            client_id: "a992567e-0dfe-4d37-9741-5a849cb6932d",
            client_assertion: jwt,
            resource: 'https://graph.microsoft.com'

    let s = await axiosClient(opt,true).catch(error => {




You can see any request made by workload identity in the servicePrincipal logs

End of blog

I anticipate that we are going see to much more use for so called federated credentials in future – Especially in AKS

0 comments on “Azure AD Workload Federation anywhere?


Täytä tietosi alle tai klikkaa kuvaketta kirjautuaksesi sisään:


Olet kommentoimassa WordPress.com -tilin nimissä. Log Out /  Muuta )


Olet kommentoimassa Twitter -tilin nimissä. Log Out /  Muuta )


Olet kommentoimassa Facebook -tilin nimissä. Log Out /  Muuta )

Muodostetaan yhteyttä palveluun %s

%d bloggaajaa tykkää tästä: