docs/operator-manual/user-management/microsoft.md
[!NOTE] Entra ID was formerly known as Azure AD.
Microsoft Entra ID > App registrations menu, choose + New registrationName for the application (e.g. Argo CD).Accounts in this organizational directory only).my-argo-cd-url with your Argo URL), then choose Add.
Web<my-argo-cd-url>/auth/callbackhttp://localhost:8085/auth/callback
azure.workload.identity/use: "true" label to the argocd-server pods.azure.workload.identity/client-id: "$CLIENT_ID" annotation to the argocd-server service account using the details from application created in previous step.Certificates & secrets menu, navigate to Federated credentials, then choose + Add credentialFederated credential scenario as Kubernetes Accessing Azure resources
argocd-serverCertificates & secrets menu, choose + New client secretName for the secret (e.g. ArgoCD-SSO).
client_secret.
API permissions menu, choose + Add a permissionUser.Read permission (under Microsoft Graph) and grant it to the created application:
Token Configuration menu, choose + Add groups claim
Microsoft Entra ID > Enterprise applications menu, search the App that you created (e.g. Argo CD).
Users and groups menu of the app, add any users or groups requiring access to the service.
Edit argocd-cm and configure the data.oidc.config and data.url section:
ConfigMap -> argocd-cm
data:
url: https://argocd.example.com/ # Replace with the external base URL of your Argo CD
oidc.config: |
name: Azure
issuer: https://login.microsoftonline.com/{directory_tenant_id}/v2.0
clientID: {azure_ad_application_client_id}
clientSecret: $oidc.azure.clientSecret // if using client secret for authentication
azure:
useWorkloadIdentity: true // if using azure workload identity for authentication
requestedIDTokenClaims:
groups:
essential: true
value: "ApplicationGroup"
requestedScopes:
- openid
- profile
- email
Skip this step if using azure workload identity. Edit argocd-secret and configure the data.oidc.azure.clientSecret section:
Secret -> argocd-secret
data:
oidc.azure.clientSecret: {client_secret | base64_encoded}
Edit argocd-rbac-cm to configure permissions. Use group ID from Azure for assigning roles
RBAC Configurations
ConfigMap -> argocd-rbac-cm
policy.default: role:readonly
policy.csv: |
p, role:org-admin, applications, *, */*, allow
p, role:org-admin, clusters, get, *, allow
p, role:org-admin, repositories, get, *, allow
p, role:org-admin, repositories, create, *, allow
p, role:org-admin, repositories, update, *, allow
p, role:org-admin, repositories, delete, *, allow
g, "84ce98d1-e359-4f3b-85af-985b458de3c6", role:org-admin
Mapping role from jwt token to argo.
If you want to map the roles from the jwt token to match the default roles (readonly and admin) then you must change the scope variable in the rbac-configmap.
policy.default: role:readonly
policy.csv: |
p, role:org-admin, applications, *, */*, allow
p, role:org-admin, clusters, get, *, allow
p, role:org-admin, repositories, get, *, allow
p, role:org-admin, repositories, create, *, allow
p, role:org-admin, repositories, update, *, allow
p, role:org-admin, repositories, delete, *, allow
g, "84ce98d1-e359-4f3b-85af-985b458de3c6", role:org-admin
scopes: '[groups, email]'
Refer to operator-manual/argocd-rbac-cm.yaml for all of the available variables.
Azure AD / Entra ID access tokens can contain a maximum of 200 groups. When a user belongs to more
than 200 groups, Azure AD sets overflow indicators (_claim_names and _claim_sources) in the ID
token instead of including the groups claim. This causes users to have no group-based RBAC
permissions in Argo CD.
Argo CD can automatically detect this overflow and resolve it by calling the Microsoft Graph API to fetch the complete list of group memberships.
scp claim
without needing to explicitly request them in requestedScopes.Add the following to your argocd-cm ConfigMap under oidc.config:
oidc.config: |
name: Azure
issuer: https://login.microsoftonline.com/{tenant_id}/v2.0
clientID: {client_id}
clientSecret: $oidc.azure.clientSecret
requestedScopes:
- openid
- profile
- email
azure:
enableUserGroupOverageClaim: true
| Setting | Default | Description |
|---|---|---|
enableUserGroupOverageClaim | false | Enable automatic overflow resolution via Graph API |
graphApiEndpoint | https://graph.microsoft.com/v1.0 | Graph API base URL (override for sovereign clouds) |
userGroupOverageClaimCacheExpiration | Token expiry | Cache duration for resolved groups (e.g., 10m) |
For Azure Government, Azure China, or other sovereign clouds, override the Graph API endpoint:
azure:
enableUserGroupOverageClaim: true
graphApiEndpoint: https://graph.microsoft.us/v1.0 # Azure Government
_claim_names and
_claim_sources).User.Read scope.POST /me/getMemberGroups to fetch all group IDs (up to 2048).
Only security-enabled groups are returned (not distribution lists), which is appropriate
for RBAC evaluation.| Symptom | Cause | Solution |
|---|---|---|
| User still has 0 groups despite 200+ memberships | Feature not enabled | Set enableUserGroupOverageClaim: true |
| Logs show "access token missing User.Read scope" | Missing permission | Verify the User.Read delegated permission is granted on the app registration in Azure AD |
| Logs show "insufficient permissions for Graph API" | App permission denied | Verify app permissions in Azure AD |
| Logs show "no access token cached" | Token expired | User must re-authenticate |
[!WARNING] This feature depends on the Microsoft Graph API being reachable at authentication time. If the Graph API is unavailable (network issues, outage, etc.), users with 200+ group memberships will be unable to authenticate until service is restored. Users with fewer than 200 groups are unaffected since their groups are included directly in the ID token.
Graph API failures (missing scope, permission denied, network errors) will cause authentication to fail with a 401 Unauthorized response. This is consistent with how the UserInfo endpoint behaves. Only enable this feature if you need group-based RBAC for users with 200+ groups, and ensure the prerequisites above are met to avoid authentication issues.
Microsoft Entra ID > Enterprise applications menu, choose + New applicationNon-gallery applicationName for the application (e.g. Argo CD), then choose AddEnterprise applications menu.Users and groups menu of the app, add any users or groups requiring access to the service.
Single sign-on menu, edit the Basic SAML Configuration section as follows (replacing my-argo-cd-url with your Argo URL):
<my-argo-cd-url>/api/dex/callback<my-argo-cd-url>/api/dex/callback<my-argo-cd-url>/auth/login<empty><empty>
Single sign-on menu, edit the User Attributes & Claims section to create the following claims:
+ Add new claim | Name: email | Source: Attribute | Source attribute: user.mail+ Add group claim | Which groups: All groups | Source attribute: Group ID | Customize: True | Name: Group | Namespace: <empty> | Emit groups as role claims: FalseUnique User Identifier required claim can be left as the default user.userprincipalname
Single sign-on menu, download the SAML Signing Certificate (Base64)
$ cat ArgoCD.cer | base64Single sign-on menu, copy the Login URL parameter, to be used in the next section.Edit argocd-cm and add the following dex.config to the data section, replacing the caData, my-argo-cd-url and my-login-url your values from the Entra ID App:
data:
url: https://my-argo-cd-url
dex.config: |
logger:
level: debug
format: json
connectors:
- type: saml
id: saml
name: saml
config:
entityIssuer: https://my-argo-cd-url/api/dex/callback
ssoURL: https://my-login-url (e.g. https://login.microsoftonline.com/xxxxx/a/saml2)
caData: |
MY-BASE64-ENCODED-CERTIFICATE-DATA
redirectURI: https://my-argo-cd-url/api/dex/callback
usernameAttr: email
emailAttr: email
groupsAttr: Group
Edit argocd-rbac-cm to configure permissions, similar to example below.
Use Entra ID Group IDs for assigning roles.
See RBAC Configurations for more detailed scenarios.
# example policy
policy.default: role:readonly
policy.csv: |
p, role:org-admin, applications, *, */*, allow
p, role:org-admin, clusters, get, *, allow
p, role:org-admin, repositories, get, *, allow
p, role:org-admin, repositories, create, *, allow
p, role:org-admin, repositories, update, *, allow
p, role:org-admin, repositories, delete, *, allow
g, "84ce98d1-e359-4f3b-85af-985b458de3c6", role:org-admin # (azure group assigned to role)
Configure a new AD App Registration, as above.
Then, add the dex.config to argocd-cm:
ConfigMap -> argocd-cm
data:
dex.config: |
connectors:
- type: microsoft
id: microsoft
name: Your Company GmbH
config:
clientID: $MICROSOFT_APPLICATION_ID
clientSecret: $MICROSOFT_CLIENT_SECRET
redirectURI: http://localhost:8080/api/dex/callback
tenant: ffffffff-ffff-ffff-ffff-ffffffffffff
groups:
- DevOps
<my-argo-cd-url>
LOGIN VIA AZURE button to log in with your Microsoft Entra ID account. You’ll see the ArgoCD applications screen.
Setup permissions for Entra ID Application step.
Open terminal, execute the below command.
argocd login <my-argo-cd-url> --grpc-web-root-path / --sso
You will see the below message after entering your credentials from the browser.
Your terminal output will be similar as below.
WARNING: server certificate had error: x509: certificate is valid for ingress.local, not my-argo-cd-url. Proceed insecurely (y/n)? y
Opening browser for authentication
INFO[0003] RequestedClaims: map[groups:essential:true ]
Performing authorization_code flow login: https://login.microsoftonline.com/XXXXXXXXXXXXX/oauth2/v2.0/authorize?access_type=offline&claims=%7B%22id_token%22%3A%7B%22groups%22%3A%7B%22essential%22%3Atrue%7D%7D%7D&client_id=XXXXXXXXXXXXX&code_challenge=XXXXXXXXXXXXX&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost%3A8085%2Fauth%2Fcallback&response_type=code&scope=openid+profile+email+offline_access&state=XXXXXXXX
Authentication successful
'[email protected]' logged in successfully
Context 'my-argo-cd-url' updated
You may get an warning if you are not using a correctly signed certs. Refer to Why Am I Getting x509: certificate signed by unknown authority When Using The CLI?.
For Microsoft identity platforms, you can set domainHint in oidc.config to provide a domain hint during sign-in.
When configured, Argo CD adds domain_hint=<value> to the authorization request sent to Microsoft.
This can reduce account discovery prompts in multi-tenant or federated environments.
domainHintstringExample:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
oidc.config: |
name: Microsoft
issuer: https://login.microsoftonline.com/<tenant-id>/v2.0
clientID: <client-id>
clientSecret: $oidc.microsoft.clientSecret
requestedScopes: ["openid", "profile", "email", "groups"]
domainHint: contoso.com