Overview
Argo CD supports SSO authentication through two methods:
Bundled Dex OIDC provider : Use when your provider doesn’t support OIDC (SAML, LDAP) or to leverage Dex connector features
External OIDC provider : Use with existing OIDC providers like Okta, Auth0, Keycloak, Google, or Microsoft
SSO requires configuring the url field in the argocd-cm ConfigMap. This is the externally-facing base URL of your Argo CD instance.
Dex Configuration
Argo CD embeds Dex for delegating authentication to external identity providers.
GitHub OAuth2 Example
First, register an OAuth application in GitHub with the callback URL: https://argocd.example.com/api/dex/callback
Then configure the argocd-cm ConfigMap:
apiVersion : v1
kind : ConfigMap
metadata :
name : argocd-cm
namespace : argocd
labels :
app.kubernetes.io/name : argocd-cm
app.kubernetes.io/part-of : argocd
data :
url : https://argocd.example.com
dex.config : |
connectors:
- type: github
id: github
name: GitHub
config:
clientID: aabbccddeeff00112233
clientSecret: $dex.github.clientSecret
orgs:
- name: your-github-org
teams:
- red-team
Dex will automatically use the correct redirectURI to match your Argo CD URL. No need to set it explicitly.
GitHub Enterprise
data :
url : https://argocd.example.com
dex.config : |
connectors:
- type: github
id: acme-github
name: Acme GitHub
config:
hostName: github.acme.example.com
clientID: abcdefghijklmnopqrst
clientSecret: $dex.acme.clientSecret
orgs:
- name: your-github-org
Secret References
By default, secrets like $dex.github.clientSecret are looked up in the argocd-secret Secret. To use a different Secret:
clientSecret : $my-k8s-secret:dex.github.clientSecret
Custom Secrets must have the label app.kubernetes.io/part-of: argocd.
OIDC Configuration with Dex
Use Dex as an OIDC intermediary to fetch information from the UserInfo endpoint:
apiVersion : v1
kind : ConfigMap
metadata :
name : argocd-cm
namespace : argocd
data :
url : https://argocd.example.com
dex.config : |
connectors:
- type: oidc
id: oidc
name: OIDC
config:
issuer: https://example-oidc-provider.example.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
Requesting Additional Claims
Request additional scopes like groups:
dex.config : |
connectors:
- type: oidc
id: oidc
name: OIDC
config:
issuer: https://example-oidc-provider.example.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
insecureEnableGroups: true
scopes:
- profile
- email
- groups
Group information is only refreshed at authentication time. Changes to group membership won’t take effect until users re-authenticate.
Using UserInfo Endpoint
When claims aren’t available in the ID token, retrieve them from the UserInfo endpoint:
dex.config : |
connectors:
- type: oidc
id: oidc
name: OIDC
config:
issuer: https://example-oidc-provider.example.com
clientID: aaaabbbbccccddddeee
clientSecret: $dex.oidc.clientSecret
getUserInfo: true
insecureEnableGroups: true
scopes:
- profile
- email
- groups
Direct OIDC Configuration
Connect directly to an OIDC provider without Dex:
apiVersion : v1
kind : ConfigMap
metadata :
name : argocd-cm
namespace : argocd
labels :
app.kubernetes.io/name : argocd-cm
app.kubernetes.io/part-of : argocd
data :
url : https://argocd.example.com
oidc.config : |
name: Okta
issuer: https://dev-123456.oktapreview.com
clientID: aaaabbbbccccddddeee
clientSecret: $oidc.okta.clientSecret
# Optional: customize requested scopes
requestedScopes: ["openid", "profile", "email", "groups"]
# Optional: request specific ID token claims
requestedIDTokenClaims:
groups:
essential: true
TLS Configuration
data :
# Skip certificate verification (not recommended for production)
oidc.tls.insecure.skip.verify : "false"
Only set oidc.tls.insecure.skip.verify to true if you understand the security risks.
RBAC with SSO
Configure which OIDC scopes to use for RBAC:
apiVersion : v1
kind : ConfigMap
metadata :
name : argocd-rbac-cm
namespace : argocd
data :
policy.csv : |
p, my-org:team-alpha, applications, sync, my-project/*, allow
g, my-org:team-beta, role:admin
g, [email protected] , role:admin
policy.default : role:readonly
scopes : '[groups, email]'
The scopes field specifies which OIDC claims to examine for RBAC (defaults to [groups]).
Session Configuration
Configure session duration and behavior:
apiVersion : v1
kind : ConfigMap
metadata :
name : argocd-cm
namespace : argocd
data :
# Specifies token expiration duration
users.session.duration : "24h"
# Enable anonymous access (uses policy.default)
users.anonymous.enabled : "false"
Multiple Base URLs
Support multiple URLs for Argo CD access:
data :
url : https://argocd.example.com
additionalUrls : |
- https://argocd-secondary.example.com
- https://cd.example.org
Dex Static Clients
Reuse Dex with other services:
data :
dex.config : |
connectors:
- type: github
id: github
name: GitHub
config:
clientID: aabbccddeeff00112233
clientSecret: $dex.github.clientSecret
orgs:
- name: your-github-org
staticClients:
- id: argo-workflow
name: Argo Workflow
redirectURIs:
- https://argo-workflows.example.com/oauth2/callback
secret: $workflows.dex.clientSecret
Provider-Specific Examples
Okta
oidc.config : |
name: Okta
issuer: https://dev-123456.okta.com
clientID: 0oaabbbcccdddeeefff
clientSecret: $oidc.okta.clientSecret
requestedScopes:
- openid
- profile
- email
- groups
Google (G Suite)
Using Dex:
dex.config : |
connectors:
- type: google
id: google
name: Google
config:
clientID: xxxxxxxxxxxx.apps.googleusercontent.com
clientSecret: $dex.google.clientSecret
hostedDomains:
- example.com
serviceAccountFilePath: /path/to/service-account.json
Auth0
oidc.config : |
name: Auth0
issuer: https://example.auth0.com/
clientID: aabbccddeeff00112233
clientSecret: $oidc.auth0.clientSecret
Keycloak
oidc.config : |
name: Keycloak
issuer: https://keycloak.example.com/realms/master
clientID: argocd
clientSecret: $oidc.keycloak.clientSecret
requestedScopes:
- openid
- profile
- email
- groups
Microsoft Azure AD
dex.config : |
connectors:
- type: microsoft
id: microsoft
name: Microsoft
config:
clientID: aaaabbbbccccddddeeee
clientSecret: $dex.microsoft.clientSecret
tenant: your-tenant-id
redirectURI: https://argocd.example.com/api/dex/callback
Disabling Admin User
Once SSO is configured, disable the built-in admin user:
apiVersion : v1
kind : ConfigMap
metadata :
name : argocd-cm
namespace : argocd
data :
admin.enabled : "false"
Ensure you have configured at least one user with admin privileges via RBAC before disabling the admin user.
Adding Local Users
Create additional local users in the argocd-cm ConfigMap:
data :
accounts.alice : apiKey, login
accounts.bob : apiKey
accounts.alice.enabled : "true"
Capabilities:
apiKey: Allows generating API keys
login: Allows UI login
Failed Login Rate Limiting
Configure via environment variables on the argocd-server deployment:
ARGOCD_SESSION_FAILURE_MAX_FAIL_COUNT: Max failed logins (default: 5)
ARGOCD_SESSION_FAILURE_WINDOW_SECONDS: Failure window duration (default: 300)
ARGOCD_SESSION_MAX_CACHE_SIZE: Max cache entries (default: 1000)
ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT: Max concurrent logins (default: 50)
Complete Example
apiVersion : v1
kind : ConfigMap
metadata :
name : argocd-cm
namespace : argocd
labels :
app.kubernetes.io/name : argocd-cm
app.kubernetes.io/part-of : argocd
data :
url : https://argocd.example.com
users.session.duration : "24h"
users.anonymous.enabled : "false"
admin.enabled : "false"
accounts.devops : apiKey, login
dex.config : |
connectors:
- type: github
id: github
name: GitHub
config:
clientID: aabbccddeeff00112233
clientSecret: $dex.github.clientSecret
orgs:
- name: your-org
teams:
- devops-team
- platform-team
---
apiVersion : v1
kind : ConfigMap
metadata :
name : argocd-rbac-cm
namespace : argocd
data :
policy.csv : |
g, your-org:devops-team, role:admin
p, your-org:platform-team, applications, *, */*, allow
p, your-org:platform-team, repositories, *, *, allow
policy.default : role:readonly
scopes : '[groups]'
Best Practices
Use SSO for Teams Implement SSO with group-based access control instead of managing individual local users.
Secure Secrets Store sensitive values like client secrets in Kubernetes Secrets, not directly in ConfigMaps.
Session Duration Set appropriate session durations based on your security requirements.
Disable Admin Disable the built-in admin user once SSO and RBAC are properly configured.