Microsoft Entra ID (Azure AD)
Configure Microsoft Entra ID, formerly known as Azure AD, as the Single Sign-On provider for your Kargo instance.
There are three ways to connect Entra ID. Pick one:
| Method | Kargo mode | Azure object | Credential | Groups from | Group limit |
|---|---|---|---|---|---|
| Native OIDC | OIDC | App registration, SPA platform | PKCE | ID-token claim | 200 |
| Dex OIDC | Dex, oidc connector | App registration | Client secret | ID-token claim | 200 |
| Dex SAML | Dex, saml connector | Enterprise application (non-gallery) | Signing certificate, inline | SAML assertion | 150 |
Native OIDC is the simplest of the three: Kargo talks to Entra ID directly, with no Dex hop and no client secret. It is also the only method documented here for CLI login. The two Dex methods route through Kargo's built-in Dex instance.
Before you start, you need:
- An Akuity Platform account with a Kargo instance
- Admin access to your Kargo instance settings
- Azure Entra ID access with permission to create App registrations, or Enterprise applications for Dex SAML
Native OIDC
Connect Entra ID directly over OIDC with PKCE. Kargo's UI runs the authorization-code flow as a public client, so there is no client secret and no Dex hop.
Kargo stores the Dex configuration and the direct-OIDC fields side by side and uses a flag to select between them, so you can switch between Dex and OIDC without losing either configuration.
For CLI login (Step 8) you also need the kargo CLI installed.
Step 1: Switch to OIDC mode and note the callback URL
-
In your Kargo Instance, go to Settings.
-
In the left panel, search for Access and go to OIDC Config.

-
Toggle Enabled to on.
-
Select OIDC, not Dex.
-
The callback URL banner shows:
https://<your-kargo-hostname>/login
The form changes completely compared with Dex mode: you get Client ID, CLI Client ID, Issuer URL and Additional Scopes instead of a YAML editor and a Secrets tab.

Leave this page open — you will return to it in Step 5.
Step 2: Register the application in Azure
-
In the Azure Portal, go to Microsoft Entra ID → App registrations → + New registration.
-
Name: a descriptive name, for example
Kargo-Native-OIDC-EntraID. -
Supported account types: Accounts in this organizational directory only (Single tenant).
-
Redirect URI: change the platform dropdown from Web to Single-page application (SPA), then enter:
https://<your-kargo-hostname>/login -
Click Register.

This is the most important choice in this guide.
Kargo's UI runs the authorization-code and PKCE exchange from the browser as a public client, with no client secret. Entra's Web platform expects a client secret and does not enable CORS on the token endpoint, so the token exchange fails.
Single-page application is the only platform that supports public-client PKCE with CORS.
On the Overview page, note the Application (client) ID and the Directory (tenant) ID.
No client secret is needed anywhere in this method. PKCE replaces it. If you find yourself creating one, you are on the wrong platform type.
Step 3: Add the CLI platform
The Kargo CLI authenticates with the same authorization-code and PKCE flow, receiving the callback on a local loopback port.
-
In the application, go to Authentication → + Add a platform.
-
Choose the Mobile and desktop applications tile.
-
Ignore the suggested URIs. Under Custom redirect URIs enter:
http://localhost/auth/callback -
Click Configure.
You should now have two platform configurations: SPA for /login, and Mobile and desktop applications for http://localhost/auth/callback. Adding this platform also marks the application as a public client, which the CLI flow requires.

Step 4: Configure token claims
Azure Entra ID does not emit an email claim by default, and groups must be explicitly requested as a claim.
Add the email claim
-
In the application, go to Token configuration → + Add optional claim.
-
For Token type, select ID.
-
Check
email. Optionally also checkpreferred_usernameandupn. -
Click Add.
-
A banner appears reading "Some of these claims (email) require OpenId Connect scopes…". Tick the checkbox to turn on the Microsoft Graph
emailpermission, then click Add.
Without that checkbox the claim is configured but never appears in the token. The email scope is a basic OpenID Connect scope and does not require admin consent.

email claim only carries a value if the user's mail attribute is populatedEntra ID sources it from the directory mail attribute, which is frequently blank on newly created, test, or service accounts even when the UPN looks like an email address.
To check, query Microsoft Graph:
GET https://graph.microsoft.com/v1.0/me?$select=mail,userPrincipalName
A response of "mail": null confirms the problem. You can also look under Users → user → Contact Information → Email.
To fix it you need the User Administrator role: set Contact Information → Email on the user, or send PATCH /users/{id} with { "mail": "user@yourcompany.com" }.
Alternatively, map Kargo roles on a claim that is always present, such as preferred_username or sub. Kargo accepts any claim name.
Add the groups claim
Add this if you want group-based roles.
-
Go to Token configuration → + Add groups claim.
-
Select Security groups, or Groups assigned to the application — see the limit below.
-
Under the ID token section, select Group ID.
-
Click Add.

Past 200 groups Entra ID drops the groups claim entirely and emits overage indicators (_claim_names and _claim_sources) instead. Kargo has no overage-resolution feature, so affected users silently receive no groups at all, with no error, and group-based roles quietly stop applying.
To avoid this, configure a groups claim filter: select Groups assigned to the application instead of Security groups, so only groups explicitly assigned to the application are emitted. Assign them under Enterprise applications → your app → Users and groups.
Assigning groups to an application requires Entra ID P1 or P2.
No API permissions or admin consent are required for this method. The default User.Read plus the basic email scope is sufficient.
Step 5: Complete the Kargo OIDC configuration
Back on the Kargo OIDC Config page with OIDC mode selected, fill in:
| Field | Value |
|---|---|
| Client ID | Your Application (client) ID from Step 2 |
| CLI Client ID | The same Application (client) ID |
| Issuer URL | https://login.microsoftonline.com/<TENANT_ID>/v2.0 |
| Additional Scopes | Leave empty |
Replace <TENANT_ID> with your Directory (tenant) ID.
groups to Additional ScopesKargo already requests openid, profile and email by default, and appends offline_access when the identity provider advertises it. Adding a groups scope produces:
AADSTS650053: The application asked for scope 'groups' that doesn't exist on the
resource '00000003-0000-0000-c000-000000000000'.
Microsoft Graph has no groups scope. Groups arrive via the token claim configured in Step 4, never via a scope.
A single Entra ID registration serves both the UI and the CLI, because Entra allows multiple platform configurations on one application. Leaving CLI Client ID blank also works — the UI auto-fills it from Client ID.
Step 6: Map users to Kargo roles
Scroll to Kargo Roles and Permissions. For the Admin role:
- Claim key:
email - Claim value: your email address
- Click Add
Available roles are Admin, Viewer, User, and Project Creator.
For group-based mapping, use claim key groups with the group's Entra ID Object ID as the value, matching the Group ID format chosen in Step 4.
Claim matching is exact string equality — no wildcards, no substring matching, no case folding. If you later change the groups claim format, for example from Group ID to sAMAccountName, every existing mapping must be rewritten. Plan format changes as a coordinated migration.
Click Save.
Step 7: Test the UI login
-
Open a fresh incognito or private window and go to
https://<your-kargo-hostname>. -
Click SSO Login.
-
Sign in with your Entra ID account, and accept the consent prompt if shown. This is basic user consent and needs no admin approval.
-
You land in the Kargo UI with the role you mapped.
The redirect URL should contain:
login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize?…&code_challenge=…&code_challenge_method=S256&redirect_uri=…%2Flogin
code_challenge_method=S256 confirms PKCE, and a redirect_uri ending in /login with no /dex/callback anywhere confirms Dex is bypassed.
Step 8: Test the CLI login
kargo login https://<your-kargo-hostname> --sso
The CLI starts a loopback listener on a free local port, opens your browser to Entra ID, completes the PKCE exchange, and stores the token.
Verify you are authenticated:
kargo get projects
You should see your projects listed.
Native OIDC troubleshooting
AADSTS50011 for the CLI callback
Check the registered URI for stray characters. A trailing bracket, space, or slash pasted in with the URL is easy to miss in the Azure form — the value must be exactly http://localhost/auth/callback.
AADSTS50011 for the UI callback
The redirect URI registered in Azure does not match the callback Kargo actually uses. Read the redirect_uri parameter out of the browser URL when you are redirected to Microsoft — that is the exact value Azure must have registered. For native OIDC it is https://<kargo-host>/login.
AADSTS650053: The application asked for scope 'groups' that doesn't exist
Remove groups from Additional Scopes. Entra ID has no groups scope — groups come from the token claim configured in Step 4.
CORS error, or "client_secret is required" at the token exchange
The application is registered on the Web platform instead of Single-page application (SPA). Kargo's UI is a public client using PKCE, and only the SPA platform supports that with CORS. Add a SPA platform configuration, or recreate the application, with the /login redirect URI.
Login succeeds but the user has no permissions
No role mapping matched. Check Kargo Roles and Permissions: the claim key and value must match the token exactly. Decode the ID token and compare the claim values character for character.
Groups missing, or group-based roles not applying
- Confirm a groups claim is configured in Azure Token configuration (Step 4)
- Use the group's Object ID as the mapping value, not the display name
- Check whether the user exceeds the 200-group ceiling. Kargo has no overage fallback, so affected users get no groups silently — switch to Groups assigned to the application
Only some of a user's groups appear
If the groups claim is set to Groups assigned to the application, only groups explicitly assigned to the application are emitted. Assign the remaining groups under Enterprise applications → your app → Users and groups.
If it is set to Security groups, verify the missing groups are actually security-enabled. Microsoft 365 groups and distribution lists are excluded.
email claim missing
You need both the email optional claim, with the Graph email permission enabled, and a populated mail attribute on the user. See Step 4. Alternatively map roles on preferred_username or sub.
Native OIDC summary
| Component | Value |
|---|---|
| Azure app type | App registration (single tenant) |
| UI platform | Single-page application (SPA) |
| UI redirect URI | https://<kargo-host>/login |
| CLI platform | Mobile and desktop applications |
| CLI redirect URI | http://localhost/auth/callback — no port needed |
| Kargo SSO mode | OIDC, not Dex |
| Issuer URL | https://login.microsoftonline.com/<TENANT_ID>/v2.0 |
| Client secret | PKCE |
| Additional scopes | Empty; defaults are openid, profile, email |
| Admin consent | Not required |
| Group token limit | 200, with no overage fallback in Kargo |
| CLI command | kargo login https://<kargo-host> --sso |
| Key gotchas | Register the UI as SPA, not Web; register the CLI loopback URI under Mobile and desktop applications; never add a groups scope; the mail attribute must be set for the email claim |
Dex OIDC
Connect Entra ID through Dex's oidc connector, using an app registration and a client secret.
Step 1: Get your Kargo callback URL
-
In your Kargo Instance, go to Settings.
-
In the left panel, search for Access and go to OIDC Config.

-
Toggle Enabled to on.
-
Select the Dex option, not OIDC.
-
A banner displays your callback URL. Copy it — you will register it in Azure:
https://<your-kargo-hostname>/dex/callback
The Kargo Dex callback path is /dex/callback.
When Dex is selected the page shows the /dex/callback URL; when OIDC (direct) is selected it shows a /login URL. Make sure you copy the /dex/callback one.

Leave this page open — you will come back to fill in the configuration.
Step 2: Register a new application in Azure Entra ID
-
Log in to the Azure Portal.
-
Navigate to Microsoft Entra ID → App registrations.
-
Click + New registration.
-
Fill in the registration form:
- Name: a descriptive name, for example
Kargo-Dex-OIDC-EntraID - Supported account types: Accounts in this organizational directory only (Single tenant)
- Redirect URI: platform Web, set to
https://<your-kargo-hostname>/dex/callbackfrom Step 1
- Name: a descriptive name, for example
-
Click Register.

Step 3: Note down application details
On the application's Overview page, note down the Application (client) ID and the Directory (tenant) ID.

Step 4: Create a client secret
-
In the left sidebar, click Certificates & secrets.
-
Click + New client secret.
-
Enter a description, for example
Kargo Dex OIDC Secret, and select an expiry such as 12 months. -
Click Add.
-
Copy the secret Value immediately. It is shown only once.
Copy the Value column, not the Secret ID. If you lose it, you will need to create a new one.

Step 5: Add the email optional claim
Azure Entra ID does not include an email claim in tokens by default. Kargo requires an email claim to identify users, so you must add it.
-
In the application, click Token configuration in the left sidebar.
-
Click + Add optional claim.
-
For Token type, select ID.
-
Check
email. Optionally also checkpreferred_usernameandupnas fallbacks. -
Click Add.
-
If prompted that the claim requires the Microsoft Graph profile permission, tick the box to turn it on, then click Add. This is a profile-level permission and does not require admin consent.

email claim only appears if the account has a populated mail attributeMany test and service accounts have a blank Email field, under Users → user → Contact Information → Email. This causes a missing email claim error at login even when everything else is correct.
See Dex OIDC troubleshooting for both the proper fix and a Dex-side fallback.
Add a groups claim for RBAC
Add this if you want to map Entra ID groups to Kargo roles.
-
On the Token configuration page, click + Add groups claim.
-
Select Security groups, or Groups assigned to the application — see the limit below.
-
Under the ID token section, select Group ID.
-
Click Add.

If a user belongs to more than 200 groups, Entra ID silently drops the extras from the JWT, which can break group-based RBAC and is hard to diagnose.
To avoid this, configure a groups claim filter: select Groups assigned to the application instead of Security groups, so only groups explicitly assigned to the application are emitted.
Assigning groups to an application requires Entra ID P1 or P2. On lower tiers you can still emit security groups, but stay mindful of the 200-group limit.