Requires Enterprise plan. Contact sales for access.
Prerequisites
- Enable V3 tokens on the OIDC Token Configuration page in your organization settings. See Enable V3 tokens.
- Azure CLI installed in your environment (for
az login).
How it works
- Ona issues a JWT with claims about the environment, user, and organization.
- Azure validates the token against Ona’s OIDC discovery endpoint.
- If the token’s
issuer,subject, andaudiencematch the federated credential, Azure issues an access token. - The environment uses the access token to call Azure APIs.
Step 1: Create a user-assigned managed identity
Create a user-assigned managed identity in Azure:clientId and tenantId from the output. You need these in Step 3.
Step 2: Add a federated identity credential
Add a federated identity credential that trusts Ona’s OIDC tokens:<ORG_ID> and <PROJECT_ID> with your Ona organization and project IDs.
Key parameters:
| Parameter | Value |
|---|---|
--issuer | https://app.gitpod.io |
--subject | The exact V3 sub claim value from your Ona token |
--audiences | api://AzureADTokenExchange (Azure’s standard audience for federated credentials) |
The
subject must exactly match the sub claim in the Ona token. Decode your token to verify: ona idp token --audience api://AzureADTokenExchange --decodeMultiple federated credentials
You can add up to 20 federated credentials per managed identity. Each credential matches a differentsub value. For example, to allow two projects:
Step 3: Assign Azure RBAC roles
Grant the managed identity access to the Azure resources it needs:Step 4: Authenticate from an environment
Get an Ona OIDC token and exchange it for Azure credentials using the Azure CLI:Automate on environment startup
Add the login to your automations:Using the Azure SDK
For programmatic access, use the Azure Identity SDK’sClientAssertionCredential:
Sub claim strategy for Azure
Azure’s exact-match requirement on thesub claim means you need a predictable, stable sub value. The default V3 sub depends on whether the environment belongs to a project:
- With project:
organization_id:<orgID>:project_id:<projID>. Stable across all environments in the project. One federated credential covers all environments created from that project. - Without project:
organization_id:<orgID>. Stable but broad. Any environment in the org matches.
Recommended: use projects
Environments created from an Ona project produce a project-scoped sub by default. This is the best fit for Azure because:- The sub is stable across environment restarts and recreations
- One federated credential per project is manageable
- Access is scoped to a specific codebase
Alternative: user-scoped sub
Adduser_id to the extra sub fields on the OIDC Token Configuration page. Each user gets a stable sub:
Environments without a project
Environments created without a project produce a sub oforganization_id:<orgID>. A single federated credential then grants access to all environments in the org. If this is too broad, add extra sub fields (e.g., user_id or environment_id) to narrow the scope.
Limits
- Maximum 20 federated credentials per managed identity.
- If you need more, create additional managed identities with different role assignments.
- The
subjectfield has a 600-character limit.
Using V2 tokens with Azure
V2 tokens also work with Azure federated credentials. The V2sub claim uses a path-based format (e.g., org:<orgID>/prj:<projectID>/env:<envID>). Set the federated credential’s --subject to the exact V2 sub value.
V2 tokens include fewer claims (org, gsub, and standard JWT fields only), so Azure trust is limited to matching the sub claim. See the OIDC overview V2 section for the full V2 sub format reference.
Troubleshooting
“AADSTS70021: No matching federated identity record found”- The
subclaim in your Ona token does not match any federated credential’ssubjectvalue. - Decode your token:
ona idp token --audience api://AzureADTokenExchange --decode - Compare the
subvalue with the--subjectyou configured. They must match exactly, including casing.
- The token has expired. Ona tokens are valid for 1 hour. Re-run the login command.
- Verify the
--username(client ID) matches the managed identity’s client ID, not its object ID.