Integrating SSO with ArgoCD: Enterprise-Grade Identity and Access Management
In an enterprise Kubernetes environment, securing access to your continuous delivery pipelines is non-negotiable. As organizations scale, managing individual user credentials within ArgoCD becomes an administrative nightmare and a significant security risk. Integrating Single Sign-On (SSO) with ArgoCD centralizes authentication, enforces Multi-Factor Authentication (MFA), and simplifies user lifecycle management by leveraging your existing Identity Provider (IdP).
ArgoCD SSO integration is the process of delegating user authentication to an external Identity Provider (IdP)—such as Okta, Keycloak, GitHub, or Microsoft Entra ID—using OpenID Connect (OIDC) or SAML 2.0. This allows ArgoCD to leverage enterprise directory services for user login, group membership retrieval, and Role-Based Access Control (RBAC) mapping, eliminating local user management and enhancing security posture.
This comprehensive guide details the architecture, protocols, and implementation strategies for integrating SSO with ArgoCD. Whether you choose to use ArgoCD's bundled Dex server or opt for a direct OIDC integration, this lesson provides production-ready configurations, step-by-step walkthroughs, troubleshooting playbooks, and security best practices for the modern enterprise.
Table of Contents
- Introduction
- What You Will Learn
- Prerequisites
- SSO Architecture Overview
- Dex vs. Direct OIDC: Choosing the Right Path
- Step-by-Step: GitHub OAuth Integration via Dex
- Step-by-Step: Okta OIDC Direct Integration
- Step-by-Step: Keycloak OIDC Integration
- Step-by-Step: Microsoft Entra ID (Azure AD) Integration
- ArgoCD RBAC Mapping Strategies
- Production Security and Secret Management
- High Availability and Scaling SSO Services
- Troubleshooting and Debugging SSO Configurations
- Monitoring and Observability
- Technical Interview Questions & Answers
- Frequently Asked Questions (FAQs)
- Summary & Next Steps
What You Will Learn
By the end of this deep-dive lesson, you will be able to:
- Architect secure authentication flows using both Dex and Direct OIDC connections.
- Configure production-ready SSO integrations for GitHub, Okta, Keycloak, and Microsoft Entra ID.
- Design and implement complex, group-based RBAC policies in ArgoCD.
- Securely manage OAuth client secrets using Kubernetes external secrets patterns.
- Troubleshoot real-world SSO issues like redirect URI mismatches, certificate trust issues, and group claim failures.
- Scale and monitor the ArgoCD Dex and API server components under heavy enterprise loads.
Prerequisites
To successfully implement the configurations in this guide, you must have:
- A running ArgoCD instance (v2.4 or higher recommended). If you need to set up a new instance, refer to our guide on Installing ArgoCD.
- Administrative access to your Kubernetes cluster (via
kubectl). - A fully qualified domain name (FQDN) configured for your ArgoCD instance (e.g.,
https://argocd.example.com) with a valid SSL/TLS certificate. Single Sign-On will fail over unencrypted HTTP or invalid certificates due to browser security policies. - Administrative privileges in your target Identity Provider (IdP) to create applications, register redirect URIs, and manage group assignments.
SSO Architecture Overview
ArgoCD supports two primary mechanisms for integrating external identity providers: Dex and Direct OIDC. Understanding how these components communicate with the user's browser, the Kubernetes API, and the external IdP is critical for secure deployment.
The Authentication Lifecycle
Regardless of the protocol, the authentication process follows the OAuth 2.0 Authorization Code Flow with Proof Key for Code Exchange (PKCE) or standard OpenID Connect specifications. Below is the workflow diagram representing a user authenticating via an external IdP.
+------+ +----------------+ +-----------------+ +--------------+ | User | | ArgoCD Browser | | ArgoCD Server | | Identity | | | | / CLI Client | | (or Dex) | | Provider | +--+---+ +-------+--------+ +--------+--------+ +------+-------+ | | | | | 1. Access ArgoCD URL | | | +------------------------>| | | | | 2. Redirect to /api/v1/login | | | +------------------------------>| | | | | 3. Redirect to IdP Login | | |<------------------------------+ | | | | | 4. Prompt for Credentials | |<--------------------------------------------------------------------------------------+ | | | | 5. Enter Credentials & MFA | +-------------------------------------------------------------------------------------->| | | | | | 6. Redirect back with Auth Code (Callback URL) | | |<------------------------------------------------------------+ | | | | | 7. Send Auth Code to Server | | +------------------------------>| | | | | 8. Exchange Code for Tokens | | | +---------------------------->| | | | | | | | 9. Return ID/Access Tokens | | | |<----------------------------+ | | 10. Issue Session Cookie | | | |<------------------------------+ | | 11. Logged In | | | |<------------------------+ | |
Key Architectural Components
- ArgoCD API Server (
argocd-server): The gateway for all user interaction via the web UI, CLI, and API. It validates session cookies, handles direct OIDC configurations, and enforces RBAC policy checks. - ArgoCD Dex Server (
argocd-dex-server): An in-memory/in-cluster instance of Dex, an open-source OpenID Connect identity service. Dex acts as an intermediary portal, translating requests from ArgoCD into protocols understood by upstream identity providers (like LDAP, SAML, or OAuth2). - Identity Provider (IdP): The source of truth for user identities, credentials, and group memberships (e.g., Okta, Azure AD).
Dex vs. Direct OIDC: Choosing the Right Path
When planning your integration, you must choose whether to route traffic through the bundled Dex server or connect the ArgoCD API server directly to your identity provider via OpenID Connect.
| Feature / Capability | ArgoCD Dex (Bundled) | Direct OIDC Connection |
|---|---|---|
| Supported Protocols | OIDC, SAML 2.0, LDAP, OAuth 2.0, Active Directory, Keystone | OIDC (OpenID Connect) only |
| Complexity | Moderate (requires configuring Dex block in argocd-cm) |
Low (direct API mapping in argocd-cm) |
| Network Topology | Dex runs inside the cluster; handles upstream proxying | ArgoCD API server communicates directly with IdP endpoints |
| Multi-Tenancy / Multiple IdPs | Yes (Dex can connect to multiple upstream connectors) | No (ArgoCD can only connect to a single direct OIDC provider) |
| Token Size & Cookies | Dex issues its own compact token, preventing cookie size issues | Upstream tokens are passed directly; can cause "Header Too Large" errors |
| Best Use Case | SAML, LDAP, GitHub teams, or complex multi-IdP setups | Modern clouds using pure OIDC (Okta, Keycloak, PingIdentity) |
Architectural Recommendation
Use Direct OIDC if your organization standardizes on a modern identity provider that supports standard OIDC (like Okta or Entra ID) and you do not require SAML or LDAP. Choose Dex if you must integrate with legacy SAML systems, on-premise LDAP directories, or GitHub Organizations where team memberships must be dynamically resolved.
Step-by-Step: GitHub OAuth Integration via Dex
Integrating GitHub allows your developers to log in to ArgoCD using their GitHub credentials. It also allows you to map GitHub Teams directly to ArgoCD RBAC roles. This integration uses the bundled Dex server.
Step 1: Register an OAuth Application on GitHub
- Log in to GitHub and navigate to your Organization settings (or personal settings if testing).
- Go to Developer Settings > OAuth Apps > New OAuth App.
- Fill in the application details:
- Application Name:
ArgoCD Enterprise - Homepage URL:
https://argocd.example.com - Authorization callback URL:
https://argocd.example.com/api/dex/callback(Note:/api/dex/callbackis critical when using Dex).
- Application Name:
- Click Register Application.
- Copy the generated Client ID.
- Click Generate a new client secret and copy the resulting secret. Save this securely.
Step 2: Create the Kubernetes Secret
To avoid committing sensitive credentials to your GitOps repository, create a Kubernetes secret containing the GitHub OAuth client secret.
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
namespace: argocd
labels:
app.kubernetes.io/part-of: argocd
type: Opaque
stringData:
# The key must match what we reference in the argocd-cm ConfigMap
dex.github.clientSecret: "your_github_client_secret_here"
Step 3: Configure argocd-cm ConfigMap
Apply the following configuration to the argocd-cm ConfigMap to enable the Dex GitHub connector.
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/part-of: argocd
data:
# Define the public facing URL of your ArgoCD instance
url: https://argocd.example.com
# Configure Dex connector for GitHub
dex.config: |
connectors:
- type: github
id: github
name: GitHub Enterprise Portal
config:
clientID: "your_github_client_id_here"
# Reference the secret key created in Step 2
clientSecret: $dex.github.clientSecret
# Restrict login to specific GitHub organizations
orgs:
- name: my-enterprise-org
# Optional: Restrict to specific teams within the organization
teams:
- platform-engineering
- security-operations
Step 4: Verify the Dex Pods
Once the ConfigMap is updated, the ArgoCD operator or standard controller will detect the change. You may need to restart the Dex deployment to apply the configuration immediately:
kubectl rollout restart deployment argocd-dex-server -n argocd
Step-by-Step: Okta OIDC Direct Integration
Okta is one of the most common enterprise identity management systems. This section demonstrates how to configure a direct OIDC connection without using Dex, which is the cleanest integration path for Okta.
Step 1: Configure Okta Application
- Log in to your Okta Admin Console.
- Navigate to Applications > Applications > Create App Integration.
- Select OIDC - OpenID Connect as the Sign-in method, and Web Application as the Application type. Click Next.
- Configure the App Integration settings:
- App integration name:
ArgoCD Production - Grant type: Authorization Code
- Sign-in redirect URIs:
https://argocd.example.com/auth/callback(Note:/auth/callbackis used for direct OIDC, NOT/api/dex/callback). - Sign-out redirect URIs:
https://argocd.example.com/login - Controlled Access: Limit to groups or assign to everyone depending on your security policy.
- App integration name:
- Click Save and capture the Client ID and Client Secret.
Step 2: Configure Okta Group Claims
ArgoCD requires a "groups" claim in the ID token to map Okta groups to internal roles.
- In the Okta App settings, navigate to the Sign On tab.
- Under OpenID Connect ID Token, edit the settings.
- Set the Groups claim filter:
- Name:
groups - Filter:
Matches regexand value.*(or a specific pattern likeargocd-.*to limit token size).
- Name:
- Save the changes.
Step 3: Create Kubernetes Secrets
Store the Okta client secret securely inside the cluster:
apiVersion: v1
kind: Secret
metadata:
name: argocd-secret
namespace: argocd
type: Opaque
stringData:
oidc.okta.clientSecret: "your_okta_client_secret_here"
Step 4: Configure argocd-cm for Direct OIDC
Apply the following configuration to bind ArgoCD directly to Okta's OpenID Connect endpoints.
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
# Direct OIDC Configuration block
oidc.config: |
name: Okta Enterprise SSO
issuer: https://your-okta-domain.okta.com # Do not include /oauth2/default unless using custom auth servers
clientID: "your_okta_client_id_here"
clientSecret: $oidc.okta.clientSecret
requestedScopes: ["openid", "profile", "email", "groups"]
requestedIDTokenClaims:
groups:
essential: true
Verify that your Okta issuer URL matches your corporate domain. If you are using a custom Okta Authorization Server, ensure the issuer path matches the designated custom endpoint (e.g., https://auth.example.com/oauth2/ausxxxxxx).
Step-by-Step: Keycloak OIDC Integration
Keycloak is the premier open-source identity and access management solution for cloud-native architectures. This section details how to configure Keycloak using a direct OIDC connection.
Step 1: Configure Keycloak Client
- Log in to your Keycloak Admin Console.
- Select the Realm you wish to use (e.g.,
masteror a custom realm likeEnterprise). - Navigate to Clients > Create Client.
- Configure the following settings:
- Client type: OpenID Connect
- Client ID:
argocd - Name:
ArgoCD GitOps
- On the Capability Config page, ensure Client Authentication is toggled to ON (this makes it a confidential client) and Standard Flow is checked. Click Save.
- In the Client settings, configure the following endpoints:
- Valid redirect URIs:
https://argocd.example.com/auth/callback - Web Origins:
https://argocd.example.com - Admin URL:
https://argocd.example.com
- Valid redirect URIs:
- Navigate to the Credentials tab and copy the Client Secret.
Step 2: Map Keycloak Groups to ID Token
By default, Keycloak does not include user groups in the OpenID Connect token. We must add a Group Mapper.
- Inside your Keycloak Client configuration, go to the Client scopes tab.
- Click on the dedicated scope for your client (usually named
argocd-dedicated). - Click Add mapper > By predefined mapper.
- Search for groups and select the mapper named
groups. - Ensure the Token Claim Name is set to
groupsand Add to ID token is enabled.
Step 3: Update argocd-cm ConfigMap
Deploy the configuration referencing your Keycloak Realm URL.
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: Keycloak Corporate IAM
issuer: https://keycloak.example.com/realms/Enterprise
clientID: argocd
clientSecret: $oidc.keycloak.clientSecret
requestedScopes: ["openid", "profile", "email", "groups"]
Ensure you have created the Kubernetes secret argocd-secret containing oidc.keycloak.clientSecret before applying the configuration.
Step-by-Step: Microsoft Entra ID (Azure AD) Integration
Microsoft Entra ID (formerly Azure Active Directory) requires specific configurations because it uses UUIDs for group claims by default rather than human-readable group names.
Step 1: Register Application in Azure Portal
- Log in to the Microsoft Entra admin center.
- Go to Identity > Applications > App registrations > New registration.
- Set the following parameters:
- Name:
ArgoCD GitOps Production - Supported account types: Accounts in this organizational directory only (Single tenant).
- Redirect URI: Select Web and enter
https://argocd.example.com/auth/callback.
- Name:
- Click Register. Copy the Application (client) ID and the Directory (tenant) ID.
- Navigate to Certificates & secrets > New client secret. Generate the secret and copy the value immediately.
Step 2: Configure Group Claims
To pass user groups inside the token:
- In the App Registration menu, navigate to Token configuration.
- Click Add groups claim.
- Select Security groups (and optionally Directory roles if needed).
- Under Customize token properties by type, check Group ID. Note: Entra ID will emit the Object IDs (UUIDs) of the groups, not the names. You will map these UUIDs in your RBAC configuration.
Step 3: Configure API Permissions
To read group memberships, the application needs Microsoft Graph permissions:
- Go to API permissions > Add a permission > Microsoft Graph.
- Select Delegated permissions.
- Search for and check
User.ReadandGroupMember.Read.All. - Click Grant admin consent for [Your Organization]. This is mandatory for the permissions to take effect.
Step 4: Update argocd-cm
Configure the direct OIDC block using your Entra ID tenant endpoint:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
url: https://argocd.example.com
oidc.config: |
name: Microsoft Entra ID
# Replace {tenant-id} with your actual Azure Directory ID
issuer: https://login.microsoftonline.com/{tenant-id}/v2.0
clientID: "your_azure_client_id_here"
clientSecret: $oidc.azure.clientSecret
requestedScopes: ["openid", "profile", "email", "User.Read"]
ArgoCD Role-Based Access Control (RBAC) Mapping Strategies
Authentication is only half the battle. Once users are authenticated, ArgoCD must determine what resources they are authorized to view, modify, or delete. This is handled by the argocd-rbac-cm ConfigMap.
For more details on overall RBAC structures, you can check our dedicated guide on ArgoCD RBAC Policies.
Understanding the RBAC Policy Format
ArgoCD uses the Casbin policy engine format. Each policy rule follows this structure:
p, subject, resource, action, object, effect
- subject: The group name or user email returned in the SSO token (e.g.,
my-org:platform-engineeringor a UUID from Azure AD). - resource: The resource type (e.g.,
applications,projects,clusters,repositories). - action: The operation (e.g.,
get,create,update,delete,sync,override). - object: The target path, usually formatted as
project/application-name(e.g.,default/guestbookor*/*). - effect: Either
allowordeny.
Production-Grade RBAC Configuration Example
The following manifest demonstrates how to map different SSO groups to various administrative tiers within an enterprise.
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-rbac-cm
namespace: argocd
data:
# 1. Disable local admin account for production compliance
admin.enabled: "false"
# 2. Define a safe default role for authenticated users (Read-Only)
policy.default: role:readonly
# 3. Define custom roles and map them to SSO groups
policy.csv: |
# Define custom developer role
p, role:developer, applications, get, */*, allow
p, role:developer, applications, sync, dev-project/*, allow
p, role:developer, applications, update, dev-project/*, allow
p, role:developer, projects, get, *, allow
# Define platform engineer role (Cluster Admin)
p, role:platform-admin, *, *, *, allow
# Map GitHub Teams (via Dex) to roles
g, "my-enterprise-org:platform-engineering", role:platform-admin
g, "my-enterprise-org:application-developers", role:developer
# Map Okta groups (Direct OIDC) to roles
g, argocd-admins, role:platform-admin
g, argocd-devs, role:developer
# Map Microsoft Entra ID groups (using Object UUIDs) to roles
g, 8b4c2b9a-1123-4e89-99a0-f2038749a12c, role:platform-admin
g, d3b07384-d113-40e1-8889-1234567890ab, role:developer
Best Practices for RBAC Design
- Least Privilege: Set
policy.defaulttorole:readonlyor""(empty string, which denies all access by default). Never set it torole:admin. - Explicit Overrides: Use explicit deny rules if you need to restrict access to sensitive production namespaces or projects for specific subgroups.
- Group Name Normalization: Pay attention to how your IdP formats group claims. GitHub includes the organization prefix (e.g.,
org:team), whereas Okta or Keycloak send raw string names.
Production Security and Secret Management
Hardcoding client secrets in your GitOps repositories is a critical security vulnerability. If your Git repository is compromised, your corporate Identity Provider configuration is compromised. You must use a secure secrets injection mechanism.
Pattern: External Secrets Operator (ESO) with AWS Secrets Manager
The standard enterprise pattern is to store secrets in an external vault (like AWS Secrets Manager, HashiCorp Vault, or Azure Key Vault) and project them dynamically into Kubernetes Secrets using the External Secrets Operator.
Below is an architecture diagram representing the GitOps secrets injection workflow:
+---------------+ +-----------------------+ +----------------------+
| Git Repository| | AWS Secrets Manager / | | External Secrets |
| (GitOps Repo) | | HashiCorp Vault | | Operator |
+-------+-------+ +-----------+-----------+ +----------+-----------+
| | |
| 1. Commit ExternalSecret CRD | |
+--------------------------------------------------------------------->|
| | |
| | 2. Fetch encrypted secret payload |
| |<-----------------------------------+
| | |
| | 3. Return client secret plaintext |
| +----------------------------------->|
| |
| 4. Reconcile & generate K8s Secret |
| +------------------------------------> [ K8s Secret: argocd-secret ]
Implementation Manifests
First, define the SecretStore configuration targeting your cloud vault:
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: aws-secrets-manager
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
jwt:
# Authenticate to AWS using IAM Roles for Service Accounts (IRSA)
serviceAccountRef:
name: external-secrets-sa
namespace: external-secrets
Next, define the ExternalSecret resource that pulls the Okta/GitHub credentials and populates the standard argocd-secret:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: argocd-sso-secrets
namespace: argocd
spec:
refreshInterval: "1h"
secretStoreRef:
name: aws-secrets-manager
kind: ClusterSecretStore
target:
name: argocd-secret # This must overwrite/merge with the existing ArgoCD secret
creationPolicy: Merge
data:
- secretKey: oidc.okta.clientSecret
remoteRef:
key: production/argocd/sso
property: okta_client_secret
- secretKey: dex.github.clientSecret
remoteRef:
key: production/argocd/sso
property: github_client_secret
Securing ArgoCD Sessions and Cookies
To prevent session hijacking and cross-site scripting (XSS) attacks on your SSO tokens, optimize the cookie parameters in the argocd-cmd-params-cm ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cmd-params-cm
namespace: argocd
data:
# Enforce HTTPOnly and Secure flags on session cookies
server.secure: "true"
# Set session duration (e.g., 8 hours - standard shift length)
server.session.duration: "8h"
High Availability and Scaling SSO Services
When implementing SSO at scale across thousands of developers, the authentication services can become a performance bottleneck. High Availability (HA) configuration is essential to prevent login failures during high-traffic events.
Scaling the Dex Server
By default, the ArgoCD Dex server runs as a single replica and stores session data in-memory. If the Dex pod crashes or restarts, all active login sessions are invalidated, forcing users to re-authenticate.
To scale argocd-dex-server to multiple replicas, you must configure a persistent backend store. ArgoCD supports utilizing the integrated **Redis** instance as the storage backend for Dex.
Configuring Redis Backend for HA Dex
Modify the argocd-cm ConfigMap to enable the Redis storage backend for Dex:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
# Configure Dex to use Redis for session storage
dex.config: |
storage:
type: redis
config:
host: argocd-redis.argocd.svc.cluster.local:6379
# If Redis is password protected:
password: $redis.password
Once Redis storage is configured, scale up the Dex deployment replicas:
kubectl scale deployment argocd-dex-server -n argocd --replicas=3
Scaling the API Server
The argocd-server handles the direct OIDC token exchanges and session checks. Scale it to handle concurrent token validations:
kubectl scale deployment argocd-server -n argocd --replicas=3
Network Security Policies for SSO
Ensure that egress traffic is permitted from your ArgoCD server and Dex pods to your external identity provider. Below is a production NetworkPolicy restricting outbound traffic to DNS and standard HTTPS ports.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: argocd-server-egress-sso
namespace: argocd
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: argocd-server
policyTypes:
- Egress
egress:
- to:
# Allow DNS resolution
- namespaceSelector: {}
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
- to:
# Allow outbound HTTPS traffic to the internet (or specific IdP IP ranges)
ports:
- protocol: TCP
port: 443
Troubleshooting and Debugging SSO Configurations
SSO integrations can fail due to misconfigured redirect URIs, invalid certificates, or RBAC naming mismatches. This section outlines common error patterns and debugging steps.
Common Error Scenarios and Resolutions
1. "Failed to authenticate: oauth2: cannot fetch token"
- Symptom: After entering credentials on the IdP portal, the user is redirected back to ArgoCD, but an error screen is displayed containing this message.
- Root Cause: The ArgoCD server or Dex pod cannot trust the TLS certificate of the upstream Identity Provider. This frequently happens in on-premise deployments with private Certificate Authorities (CAs).
- Resolution: Mount your custom CA certificate into the
argocd-serverandargocd-dex-serverpods. You can do this by adding your root CA to theargocd-tls-certs-cmConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-tls-certs-cm
namespace: argocd
data:
# Add your internal enterprise CA cert
internal-ca.crt: |
-----BEGIN CERTIFICATE-----
MIIFpTCCA42gAwIBAgIUR3S8Z...
-----END CERTIFICATE-----
2. "Redirect URI Mismatch" (Error 400 on IdP page)
- Symptom: The user clicks the login button but immediately lands on an error page hosted by the IdP (e.g., Okta or Keycloak) stating that the redirect URI is invalid.
- Root Cause: The callback URL registered in the IdP does not exactly match the URL configured in ArgoCD.
- Resolution:
- Verify the
urlkey in yourargocd-cmConfigMap matches the browser URL. - For Dex integrations, ensure the IdP redirect URI is set to
https://<domain>/api/dex/callback. - For Direct OIDC integrations, ensure the IdP redirect URI is set to
https://<domain>/auth/callback.
- Verify the
3. "User logged in successfully but is unauthorized"
- Symptom: The user logs in, but sees no applications or projects, and receives permission errors for basic actions.
- Root Cause: The group claims emitted in the OIDC ID Token are not matching the group strings defined in the
argocd-rbac-cmpolicy file. - Resolution: Inspect the JWT token payload emitted by your identity provider to verify the exact spelling and casing of the group values.
Inspecting Tokens and Debugging Logs
To determine what claims are being sent in your SSO tokens, increase the logging level of the ArgoCD API server:
kubectl patch deployment argocd-server -n argocd --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--loglevel" }, {"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "debug" }]'
Follow the logs during a login attempt:
kubectl logs -f deployment/argocd-server -n argocd
Look for log lines containing Claims: or ID Token:. You can copy the raw JWT token and paste it into jwt.io (ensure no sensitive production secrets are leaked) to inspect the JSON structure of the claims, specifically looking for the groups array:
{
"iss": "https://keycloak.example.com/realms/Enterprise",
"sub": "23d8c10a-3341-4560-8812-f0293849102c",
"email": "dev-lead@example.com",
"email_verified": true,
"groups":