Integrating LDAP Authentication in Argo CD: A Practical Deep Dive

Introduction

In distributed platform environments, authentication must be centralized to ensure consistency, security, and operational efficiency. Managing local users across multiple tools quickly becomes unsustainable.

This article documents a complete LDAP integration with Argo CD, focusing on how the system works internally, why each configuration is required, and how to avoid common failure patterns.

This is based on a real lab setup, including full commands and explicit configuration choices.


1. LDAP Preparation

Before integrating with Argo CD, the LDAP directory must already contain:

  • A valid user
  • A group for authorization
  • Proper membership linking

User

In our LDAP, I created a group called ArgoAdminsGroup and added my user fbranco, and another group called ArgoDevsGroup, which will be used for developers. More details in 5. RBAC and Role-Based Access Control


Group

dn: cn=ArgoAdminsGroup,ou=SecurityGroups,dc=ldap,dc=devops-db,dc=info<br>objectClass: groupOfNames
member: cn=Fausto Branco,ou=UserGroups,dc=ldap,dc=devops-db,dc=info

Why this structure matters

LDAP schemas vary, but in this setup:

  • Users are identified by uid
  • Groups use groupOfNames
  • Membership is defined using full DN references

This directly impacts how Argo CD must be configured:

ConceptLDAP ValueArgoCD Mapping
User loginuid=fbrancousername: uid
User identityuididAttr: uid
Group membershipmember: DNuserAttr: DN

2. Understanding the Authentication Flow

Argo CD uses Dex as an identity broker. The LDAP authentication flow is:

  1. Bind using service account
  2. Search for user
  3. Resolve user DN
  4. Attempt bind as user (password validation)
  5. Resolve groups
  6. Apply RBAC

Each step depends on the previous one. Misconfiguration in any step results in authentication failure.


3. Argo CD LDAP Configuration

The LDAP integration is configured via the argocd-cm ConfigMap.


Apply configuration

kubectl patch configmap argocd-cm -n argocd \
  --type merge \
  -p "$(cat <<'EOF'
data:
  dex.config: |
    connectors:
      - type: ldap
        name: LDAP
        id: ldap
        config:
          host: ldap.devops-db.info:389
          insecureNoSSL: true

          bindDN: cn=readonly-bind-dn,ou=ServiceGroups,dc=ldap,dc=devops-db,dc=info
          bindPW: 1234qwer

          userSearch:
            baseDN: dc=ldap,dc=devops-db,dc=info
            filter: "(objectClass=person)"
            username: uid
            idAttr: uid
            emailAttr: mail
            nameAttr: cn

          groupSearch:
            baseDN: ou=SecurityGroups,dc=ldap,dc=devops-db,dc=info
            filter: "(objectClass=groupOfNames)"
            userMatchers:
              - userAttr: DN
                groupAttr: member
            nameAttr: cn
EOF
)"

Restart Argo CD components

kubectl rollout restart deployment argocd-server -n argocd
kubectl rollout restart deployment argocd-dex-server -n argocd

4. Configuration Breakdown

LDAP Connection

host: ldap.devops-db.info:389
insecureNoSSL: true

This uses plain LDAP over port 389. In production, TLS should be enforced.


Service Account (Bind DN)

bindDN: cn=readonly-bind-dn,ou=ServiceGroups,...
bindPW: 1234qwer

Used to:

  • search users
  • retrieve group membership

User Search

filter: "(objectClass=person)"
username: uid

Dex automatically injects the username, avoiding malformed filters.


Identity Mapping

idAttr: uid

Keeps identity aligned with login input.


Group Resolution

userMatchers:
  - userAttr: DN
    groupAttr: member

Required because groups reference users by DN.


5. RBAC and Role-Based Access Control

LDAP handles authentication, but authorization is entirely managed by Argo CD.


Where RBAC is defined

kubectl get configmap argocd-rbac-cm -n argocd -o yaml

Built-in Roles

Argo CD includes two primary roles by default:

role:admin

  • Full access
  • Create, update, delete applications
  • Manage clusters and repositories
  • Execute sync operations

role:readonly

  • View applications
  • View logs
  • No write or deployment permissions

Custom Roles

Argo CD does not restrict you to predefined roles — you can define your own.


RBAC Policy Syntax

p, <role>, <resource>, <action>, <object>, <effect>
g, <group>, <role>

Example: Developer Role

policy.csv: |
  p, role:dev, applications, get, */*, allow
  p, role:dev, applications, sync, */*, allow
  p, role:dev, logs, get, */*, allow  g, ArgoDevsGroup, role:dev

Example: QA Role

p, role:qa, applications, get, */*, allow
p, role:qa, logs, get, */*, allowg, ArgoQAGroup, role:qa

Mapping LDAP Groups to Roles

g, ArgoAdminsGroup, role:admin

This directly links LDAP group membership to Argo CD permissions.


Available Resources

ResourceDescription
applicationsApplication management
projectsProject definitions
clustersCluster connections
repositoriesGit repositories
logsApplication logs
execPod exec access
settingsArgo CD configuration

Available Actions

ActionDescription
getRead access
createCreate resources
updateModify resources
deleteRemove resources
syncDeploy applications
overrideBypass restrictions

Why RBAC Matters

Without RBAC:

  • All authenticated users are equal
  • No separation of responsibilities
  • Increased operational risk

With RBAC:

  • Permissions are centralized
  • Roles map cleanly to teams
  • Access becomes predictable and auditable

6. Debugging and Observability

View Dex logs

kubectl logs -l app.kubernetes.io/name=argocd-dex-server -n argocd -f

Leave a Reply

Your email address will not be published. Required fields are marked *