Skip to main content

Azure Workload Identity Federation Setup

This guide walks through configuring an Azure App Registration that USDN can authenticate to using Workload Identity Federation — no client secrets are stored on the USDN platform. Once configured, you can use the Cloud Accounts page in the USDN portal to validate credentials and discover Resource Groups, Virtual Networks, subnets, and Network Security Groups in your Azure subscription.

Current Scope

Azure integration currently supports account onboarding and resource discovery only. The full one-click VM deploy lifecycle is available for AWS today and is planned for Azure in a future release. The portal will display a "Deploy coming soon" panel for Azure accounts in the meantime.

How It Works

USDN authenticates to Azure AD by exchanging a short-lived JSON Web Token (JWT) signed by the USDN OIDC issuer for an Azure access token. Azure verifies the JWT against a Federated Credential you configure on the App Registration, then issues a token scoped to your subscription.

The key invariant: USDN never stores a client secret. The trust anchor is the public JWKS endpoint that Azure AD pulls from our OIDC issuer at every token exchange.

Prerequisites

  • An Azure subscription with permissions to create App Registrations and assign RBAC roles
  • The USDN OIDC issuer URL: <USDN_OIDC_ISSUER> (provided during onboarding, e.g. https://api.usdn.example.com)
  • Access to the USDN portal with an active organization

Step 1: Create the App Registration

The App Registration is the Azure AD identity that USDN authenticates as.

Using the Azure Portal

  1. Open the Azure Portal and navigate to Microsoft Entra ID > App registrations > New registration.
  2. Enter a name, e.g. USDN Cloud Deploy.
  3. For Supported account types, select Accounts in this organizational directory only (single tenant).
  4. Leave Redirect URI blank — USDN does not use the interactive auth flow.
  5. Click Register.
  6. From the app's Overview page, copy the following values — you will need them in Step 4:
    • Application (client) ID
    • Directory (tenant) ID

Using the Azure CLI

APP_NAME="USDN Cloud Deploy"

# Create the app registration
APP_JSON=$(az ad app create --display-name "${APP_NAME}" --sign-in-audience AzureADMyOrg)
APP_ID=$(echo "${APP_JSON}" | jq -r .appId)
TENANT_ID=$(az account show --query tenantId -o tsv)

# Create the matching service principal so RBAC role assignments work
az ad sp create --id "${APP_ID}"

echo "Application (client) ID: ${APP_ID}"
echo "Directory (tenant) ID: ${TENANT_ID}"

Step 2: Configure the Federated Credential

The Federated Credential is what tells Azure AD to trust JWTs minted by the USDN OIDC issuer. The subject and audience values must match exactly — Azure AD does not allow wildcards.

Using the Azure Portal

  1. From your App Registration, go to Certificates & secrets > Federated credentials > Add credential.
  2. Choose Other issuer as the scenario.
  3. Fill in the form with the values below:
FieldValue
Issuer URL<USDN_OIDC_ISSUER> (e.g. https://api.usdn.example.com)
Subject identifierusdn:cloud-deploy
Nameusdn-cloud-deploy-federation
Audienceapi://AzureADTokenExchange
  1. Click Add.

Using the Azure CLI

USDN_ISSUER="https://api.usdn.example.com"   # Provided during onboarding

cat > federated-credential.json << EOF
{
"name": "usdn-cloud-deploy-federation",
"issuer": "${USDN_ISSUER}",
"subject": "usdn:cloud-deploy",
"description": "Federated credential for USDN cloud deploy",
"audiences": ["api://AzureADTokenExchange"]
}
EOF

az ad app federated-credential create \
--id "${APP_ID}" \
--parameters @federated-credential.json

Federated Credential Fields Explained

FieldWhy it matters
Issuer URLAzure AD fetches /.well-known/openid-configuration and the JWKS from this host to verify the JWT signature. It must be reachable from Azure AD over the public internet and serve valid HTTPS.
SubjectMust match iss claim's paired sub exactly. USDN sets this to the literal string usdn:cloud-deploy for every Azure JWT — wildcards are not supported.
AudienceMust be api://AzureADTokenExchange. This is Microsoft's reserved audience for workload identity federation.
Subject must match exactly

If the federated credential subject does not match the sub claim in our JWT byte-for-byte, Azure AD rejects the token exchange with AADSTS70021: No matching federated identity record found. The portal validation step will surface this as a connection failure.

Step 3: Grant the App Access to Your Subscription

Workload identity federation only handles authentication — you still need to authorize the App Registration to read resources in your subscription. The least-privilege role for onboarding + discovery is the built-in Reader role.

Using the Azure Portal

  1. Navigate to Subscriptions > (your subscription) > Access control (IAM) > Add > Add role assignment.
  2. Select the Reader role and click Next.
  3. Under Assign access to, choose User, group, or service principal.
  4. Click Select members, search for the App Registration name (USDN Cloud Deploy), and add it.
  5. Click Review + assign.

Using the Azure CLI

SUBSCRIPTION_ID=$(az account show --query id -o tsv)

az role assignment create \
--assignee "${APP_ID}" \
--role "Reader" \
--scope "/subscriptions/${SUBSCRIPTION_ID}"
Scope as narrow as possible

You can scope the role assignment to a specific Resource Group instead of the whole subscription if USDN only needs visibility into a subset of resources. Replace --scope with /subscriptions/${SUBSCRIPTION_ID}/resourceGroups/<rg-name>.

Permission Summary

PermissionPurpose
Microsoft.Resources/subscriptions/readValidate the subscription is reachable
Microsoft.Resources/subscriptions/resourceGroups/readDiscover Resource Groups for the deploy wizard
Microsoft.Network/virtualNetworks/readList VNets for placement selection
Microsoft.Network/virtualNetworks/subnets/readList subnets within VNets
Microsoft.Network/networkSecurityGroups/readList NSGs for instance assignment

All of these are covered by the built-in Reader role.

  1. Log in to the USDN portal and navigate to Cloud Accounts (under Infrastructure).
  2. Click Link Cloud Account.
  3. Select Microsoft Azure as the provider.
  4. Fill in the required fields:
FieldValueExample
Account NameA friendly labelProduction Azure
Tenant IDDirectory (tenant) ID from Step 111111111-1111-1111-1111-111111111111
Subscription IDTarget Azure subscription22222222-2222-2222-2222-222222222222
Application (Client) IDApp Registration client ID from Step 133333333-3333-3333-3333-333333333333
Default RegionPreferred Azure regioneastus
  1. Click Save. USDN will validate the credentials by minting a JWT, exchanging it for an access token via Azure AD, and listing the configured subscription via ARM.

  2. If validation succeeds, the account status will change to Connected and you can use the View Resources action to discover Resource Groups, VNets, subnets, and NSGs in the selected region.

No client secret field

The portal does not prompt for a client secret. The federated credential you configured in Step 2 is the only thing that grants USDN access — no long-lived secrets are ever stored on the platform side.

Troubleshooting

Validation Fails with "No matching federated identity record found"

This is AADSTS70021. Azure AD could not find a Federated Credential whose issuer, subject, and audience all match the JWT we sent.

  • Confirm the Subject on the federated credential is exactly usdn:cloud-deploy (no leading slash, no quotes, no trailing whitespace).
  • Confirm the Audience is exactly api://AzureADTokenExchange.
  • Confirm the Issuer URL matches the OIDC issuer USDN gave you, including the scheme and the absence of a trailing slash.

Validation Fails with "Couldn't retrieve verification key from your identity provider"

Azure AD could not fetch the JWKS from our OIDC issuer.

  • Verify the issuer URL is reachable over the public internet (Azure AD does not honor private networks).
  • Try curl -fsSL <USDN_OIDC_ISSUER>/.well-known/openid-configuration from any host — it should return JSON with a valid jwks_uri.

Validation Fails with "Insufficient privileges to complete the operation"

The federated identity authenticated successfully, but the App Registration does not have the RBAC role assignment from Step 3.

  • Confirm the Reader role is assigned to the App Registration's service principal at the subscription scope.
  • Wait up to 5 minutes for RBAC changes to propagate.
  • Re-run the validation from the portal.

Validation Fails with "Subscription not found"

  • Confirm the subscription ID entered in the portal matches an active subscription in the same tenant as the App Registration.
  • Confirm the App Registration's service principal has at least Reader access to that specific subscription.

Resource Discovery Returns Empty Lists

  • Confirm the region selected in the portal matches the region where your VNets and Resource Groups live (Azure resources are region-scoped).
  • Confirm the App Registration has read access to the Resource Group containing the resources, not just the subscription.

Security Best Practices

  1. No secrets on disk — Federated credentials are inherently more secure than client secrets. Never re-introduce a secret-based credential for this App Registration.
  2. Scope the role assignment — Prefer assigning Reader at the Resource Group scope over the subscription scope when possible.
  3. Single-tenant App Registration — Always select single tenant in Step 1 unless you have a documented reason to do otherwise.
  4. Audit federated credentials — Periodically review the federated credentials list in the App Registration and remove entries for issuers you no longer trust.
  5. Enable Microsoft Entra audit logs — Monitor token exchanges and role-assignment changes in the Microsoft Entra audit log.

Revoking Access

To immediately revoke USDN's access to your Azure subscription:

# Option 1: Remove just the federated credential (the App Registration stays)
az ad app federated-credential list --id "${APP_ID}"
az ad app federated-credential delete --id "${APP_ID}" --federated-credential-id <federated-credential-id>

# Option 2: Remove the role assignment (App Registration can no longer read resources)
az role assignment delete \
--assignee "${APP_ID}" \
--role "Reader" \
--scope "/subscriptions/${SUBSCRIPTION_ID}"

# Option 3: Delete the App Registration entirely
az ad app delete --id "${APP_ID}"

After revoking, the linked account in the USDN portal will show an Error status on the next validation attempt.