SSO - vdsharma/argocd GitHub Wiki

Single Sign On (SSO) & Role-Based Access Control (RBAC)

Argo CD does not have any local users other than the built-in admin user. All other users are expected to login via SSO. There are two ways that SSO can be configured:

Bundled Dex OIDC provider - Use this option if your current provider does not support OIDC (e.g. SAML, LDAP) or if you wish to leverage any of Dex's connector features (e.g. the ability to map GitHub organizations and teams to OIDC groups claims).

Existing OIDC provider - Use this if you already have an OIDC provider which you are using (e.g. Okta, OneLogin, Auth0, Microsoft), where you manage your users, groups, and memberships.

Details at SSO Overview

I will be using DEX and LDAP

Using DEX with LDAP

TL;DR

  1. Edit argocd-cm configmap and
    • Add the ArgoCD url for key 'url'
    • Add Dex config for ldap for key 'data:'
  2. Add key ldappass to argocd-secret
  3. Update argocd-dex-server deployment, and add environment variable referenced from a secret.
  4. Restart 'argocd-dex-server' deployment.
  5. Login using LDAP option.

Edit the argocd-cm configmap:

kubectl edit configmap argocd-cm -n argocd

Add Dex config for ldap for key 'data:'

apiVersion: v1
data:
  url: https://<ARGOCD_SERVER_URL>

Add a dex config under data. Check DEX documentation on adding LDAP connector

apiVersion: v1
data:
  url: https://<ARGOCD_SERVER_URL>
  dex.config: |
    connectors:
      - type: ldap
        id: ldap
        name: LDAP
        config:
          host: ${host}:389
          insecureNoSSL: true
          insecureSkipVerify: true
          bindDN: ${binDN}
          bindPW: ${ldappass}

          # The attribute to display in the provided password prompt. If unset, will
          # display "Username"
          usernamePrompt: SSO Username
         # User search maps a username and password entered by a user to a LDAP entry.
          userSearch:
            # BaseDN to start the search from. It will translate to the query
            # "(&(objectClass=person)(uid=<username>))".
            baseDN: ${baseDN}
            # Optional filter to apply when searching the directory.
            filter: "(memberOf=DC=corp,DC=example,DC=com)"

            # username attribute used for comparing user entries. This will be translated
            # and combined with the other filter as "(<attr>=<username>)".
            username: cn
            # The following three fields are direct mappings of attributes on the user entry.
            # String representation of the user.
            idAttr: cn
            # Required. Attribute to map to Email.
            emailAttr: mail
            # Maps to display name of users. No default value.
            nameAttr: displayName
          # Group search queries for groups given a user entry.
          groupSearch:
            # BaseDN to start the search from. It will translate to the query
            # "(&(objectClass=group)(member=<user uid>))".
            baseDN: ${baseDN}
            # Optional filter to apply when searching the directory.
            # filter: "(objectClass=group)"

            # Following list contains field pairs that are used to match a user to a group. It adds an additional
            # requirement to the filter that an attribute in the group must match the user's
            # attribute value.
            userAttr: DN
            groupAttr: member

            # Represents group name.
            nameAttr: name

Important Notes about Environment Variables and Secrets

According to the Argo documentation

Any values which start with '$' will look to a key in argocd-secret of the same name (minus the $), to obtain the actual value. This allows you to store the clientSecret as a kubernetes secret.

with this in mind setting:

bindPW: $ldappass

Should have worked, but it doesn't. There might be another reason for this - special character '$' in the password. More on this below.

So I had to add these as environment variables using:

bindPW: ${ldappass}

I am picking the ldappass from secret key defined in argocd-secret. One reason for adding the secret key in argocd-secret is to avoid annoying warning message:

level=warning msg="config referenced '${ldappass}', but key does not exist in secret

So I just added my secret key ldappass in argocd-secret instead of some other secret.

So in short, perform these two steps

  • Add key ldappass to argocd-secret
    • kubectl edit secret argocd-secret
    • Add ldappass=<BASE64_ENCODED_PASSWORD>
  • Update argocd-dex-server deployment, and add environment variable referenced from a secret.
    • kubectl edit deployment argocd-dex-server
   spec:
      containers:
      - command:
        - /shared/argocd-util
        - rundex
        #add environment variable ldappass.
        env:
        - name: ldappass
          valueFrom:
            secretKeyRef:
              key: ldappass
              name: argocd-secret
        #end
        image: quay.io/dexidp/dex:v2.14.0
        imagePullPolicy: Always
        name: dex

DEX Password Parsing Issue

If the password has $ character in it, then it tries to replace the next set of characters with a value from environment variable. Some bug. I am sure most of the passwords have $ sign.

⚠️ **GitHub.com Fallback** ⚠️