Argo Workflows UI can be configured to use Single Sign-On (SSO) via an OIDC (OpenID Connect) provider.

Here’s how you can set it up using Keycloak as an example OIDC provider.

First, ensure you have Keycloak running and accessible. You’ll need to create a new realm and a client for Argo Workflows.

In Keycloak, create a new realm if you don’t have one already. Let’s call it argo-realm.

Next, within argo-realm, create a new client.

  • Client ID: argo-workflows
  • Client Protocol: openid-connect
  • Access Type: confidential
  • Valid Redirect URIs: This is crucial. It must be the full URL to your Argo Workflows UI, followed by /oauth2/callback. For example, https://argo.example.com/oauth2/callback.

After creating the client, Keycloak will provide you with a Client secret. Keep this safe. You’ll also need the Keycloak server’s OIDC discovery endpoint. This is typically in the format: https://<your-keycloak-host>:<port>/auth/realms/<your-realm-name>/.well-known/openid-configuration. For argo-realm, it would be https://keycloak.example.com/auth/realms/argo-realm/.well-known/openid-configuration.

Now, let’s configure Argo Workflows. You’ll need to modify the Argo Workflows controller’s deployment or configuration. The most common way is via environment variables or a ConfigMap.

Here are the essential configuration parameters for Argo Workflows to connect to your OIDC provider:

  • ARGO_OIDC_CONFIG: This should point to a ConfigMap containing the OIDC configuration.
  • ARGO_OIDC_CLIENT_ID: The client ID you created in Keycloak.
  • ARGO_OIDC_CLIENT_SECRET: The client secret Keycloak provided.
  • ARGO_OIDC_DISCOVERY_URL: The OIDC discovery URL from Keycloak.
  • ARGO_OIDC_SCOPES: The scopes requested from the OIDC provider. openid, profile, and email are common.

Let’s create a ConfigMap for the OIDC settings.

apiVersion: v1
kind: ConfigMap
metadata:
  name: argo-workflows-oidc-config
  namespace: argo
data:
  config.json: |
    {
      "issuer": "https://keycloak.example.com/auth/realms/argo-realm",
      "authorization_endpoint": "https://keycloak.example.com/auth/realms/argo-realm/protocol/openid-connect/auth",
      "token_endpoint": "https://keycloak.example.com/auth/realms/argo-realm/protocol/openid-connect/token",
      "userinfo_endpoint": "https://keycloak.example.com/auth/realms/argo-realm/protocol/openid-connect/userinfo",
      "jwks_uri": "https://keycloak.example.com/auth/realms/argo-realm/protocol/openid-connect/certs",
      "end_session_endpoint": "https://keycloak.example.com/auth/realms/argo-realm/protocol/openid-connect/logout",
      "scopes_supported": ["openid", "profile", "email", "offline_access"],
      "claims_supported": ["sub", "name", "email", "email_verified", "preferred_username"],
      "grant_types_supported": ["authorization_code", "refresh_token"],
      "response_types_supported": ["code"],
      "token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post"],
      "subject_types_supported": ["public"],
      "id_token_signing_alg_values_supported": ["RS256"],
      "code_challenge_method_supported": ["S256"]
    }

Apply this ConfigMap to your Argo Workflows namespace: kubectl apply -f oidc-configmap.yaml.

Next, you need to inject the OIDC configuration into the Argo Workflows controller. This is often done by patching the deployment.

kubectl patch deployment argo-workflows-controller -n argo \
  -p '{"spec":{"template":{"spec":{"containers":[{"name":"argo-workflows-controller","env":[{"name":"ARGO_OIDC_CLIENT_ID","value":"argo-workflows"},{"name":"ARGO_OIDC_CLIENT_SECRET","valueFrom":{"secretKeyRef":{"name":"argo-workflows-oidc-secret","key":"client_secret"}}},{"name":"ARGO_OIDC_DISCOVERY_URL","value":"https://keycloak.example.com/auth/realms/argo-realm/.well-known/openid-configuration"},{"name":"ARGO_OIDC_SCOPES","value":"openid,profile,email"},{"name":"ARGO_OIDC_CONFIG_MAP","value":"argo-workflows-oidc-config"}]}]}}}'

Important: The ARGO_OIDC_CLIENT_SECRET needs to be stored in a Kubernetes Secret. Create a secret named argo-workflows-oidc-secret in the argo namespace with a key client_secret containing your Keycloak client secret.

apiVersion: v1
kind: Secret
metadata:
  name: argo-workflows-oidc-secret
  namespace: argo
type: Opaque
data:
  client_secret: <base64_encoded_client_secret>

Replace <base64_encoded_client_secret> with your actual client secret, base64 encoded.

After applying these changes, restart the argo-workflows-controller pod for the new environment variables to take effect.

kubectl delete pod -n argo -l app=argo-workflows-controller

Once the pod restarts, navigate to your Argo Workflows UI. You should now see a "Login with OIDC" button. Clicking this will redirect you to Keycloak for authentication. Upon successful login, you’ll be redirected back to the Argo UI, logged in.

The ARGO_OIDC_CONFIG_MAP environment variable tells the controller where to find the OIDC configuration file. The config.json inside this ConfigMap specifies the endpoints and capabilities of your OIDC provider. The controller uses this information to initiate the OAuth2 authorization code flow. It redirects the user’s browser to Keycloak’s authorization endpoint, requesting specific scopes. Keycloak authenticates the user and, upon consent, redirects back to Argo’s oauth2/callback with an authorization code. The controller then exchanges this code for an ID token and access token at Keycloak’s token endpoint, validating the ID token using the JWKS URI. Finally, it extracts user information from the ID token to establish the user’s session.

The next challenge you’ll likely encounter is RBAC integration, mapping OIDC claims to Kubernetes RBAC roles for fine-grained access control within Argo Workflows.

Want structured learning?

Take the full Argo-workflows course →