Skip to main content
Version 3.0

Security — ArgoCD

ChartVersion3.0.1TypeapplicationAppVersion3.2.5
CompatibilityKubernetes1.32+OpenShift4.19+Rancher2.10.x+
Feature SupportLDAPsupported

The tdp-argo chart supports LDAP authentication through Dex. LDAP is disabled by default; enable it explicitly by editing values.yaml and setting tdp-argo.dex.enabled: true.

When enabled, LDAP uses bind credentials in argocd-secret (keys dex.ldap.bindDN and dex.ldap.bindPW), dex.config in tdp-argo.configs.cm, and RBAC in tdp-argo.rbacConfig.

Prerequisites

  • LDAP server reachable from the Kubernetes cluster.
  • LDAP bind credentials for Dex.
  • argocd-secret created manually with kubectl create secret before the deploy, with the dex.ldap.bindDN and dex.ldap.bindPW keys.
  • Dex explicitly enabled with tdp-argo.dex.enabled: true.
  • tdp-argo.configs.cm.dex.config populated with the LDAP host and baseDN.

Credentials and Secrets

Create the argocd-secret before installing the chart, so Dex reads the bind credentials via references $dex.ldap.bindDN / $dex.ldap.bindPW and Helm does not try to manage it:

Terminal input
kubectl create namespace <NAMESPACE>

kubectl create secret generic argocd-secret \
--from-literal=dex.ldap.bindDN="uid=<LDAP_BIND_USER>,cn=users,cn=accounts,dc=<LDAP_DOMAIN>,dc=com" \
--from-literal=dex.ldap.bindPW="<LDAP_BIND_PASSWORD>" \
-n <NAMESPACE>

Then, keep createSecret: false in the values file so Helm does not manage the Secret:

tdp-argo:
configs:
secret:
createSecret: false
danger

Do not commit passwords. Use private values files, secure CI, or external secret management.

LDAP configuration

tdp-argo:
configs:
cm:
url: https://<ARGOCD_HOST>
dex.config: |
connectors:
- type: ldap
id: ldap
name: LDAP
config:
host: "<LDAP_HOST>:389"
insecureNoSSL: true
insecureSkipVerify: true
bindDN: "$dex.ldap.bindDN"
bindPW: "$dex.ldap.bindPW"
userSearch:
baseDN: "cn=users,cn=accounts,dc=example,dc=com"
filter: "(objectClass=person)"
username: uid
idAttr: uid
emailAttr: mail
nameAttr: givenName
secret:
createSecret: false

dex:
enabled: true

Adjust host, baseDN and SSL flags according to your directory. When createSecret: false, create and maintain argocd-secret by another means, with the keys referenced in dex.config.

The default values.yaml keeps Dex disabled and leaves dex.config empty. In this state, the login page does not show the LDAP/SSO button.

Production: prefer LDAPS

The example above uses plaintext LDAP (<LDAP_HOST>:389 with insecureNoSSL: true and insecureSkipVerify: true), suitable only for test environments. In production, use LDAPS (port 636): set insecureNoSSL: false and insecureSkipVerify: false, change host to <LDAP_HOST>:636, and make the LDAP server CA available to Dex.

Authorization and policies

tdp-argo:
rbacConfig:
policy.default: role:readonly
policy.csv: |
g:devops-admins, role:admin
g:data-platform, role:admin
g:data-read, role:readonly
p, role:ldap-user, applications, *, default/<NAMESPACE>, get
p, role:ldap-user, applications, *, default/<NAMESPACE>, sync
p, role:ldap-user, applications, *, default/<NAMESPACE>, override
p, role:ldap-user, clusters, *, *, get
g, *, role:ldap-user

This block is already active by default in the chart, even without LDAP/Dex enabled.
The groups devops-admins, data-platform, and data-read, and <NAMESPACE>, are example values: replace them with the real groups from your LDAP directory and your project's namespace, otherwise these rules won't apply to any user.

The rbacConfig.policy.csv block combines three rule types:

  • Group mappings: lines such as g:devops-admins, role:admin map LDAP groups to built-in Argo CD roles.
  • Custom role permissions: p, role:ldap-user, ... lines define what the ldap-user role can do.
  • Default assignment: g, *, role:ldap-user assigns authenticated users to the ldap-user role by default.

NetworkPolicy

By default, the chart does not create NetworkPolicies (tdp-argo.global.networkPolicy.create: false), keeping traffic open (allow-all).

To enable the upstream allow-all policies:

tdp-argo:
global:
networkPolicy:
create: true
defaultDenyIngress: false

The upstream templates do not allow customizing the rules via Helm values. For a real restriction, apply your own NetworkPolicy — for example, allowing ingress to the Argo CD pods only from a trusted namespace (<NAMESPACE> is the namespace where Argo CD runs; <TRUSTED_NAMESPACE>, the authorized source namespace):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: argocd-restrict-ingress
namespace: <NAMESPACE>
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- <TRUSTED_NAMESPACE>

Installation or update

Terminal input
helm upgrade --install <RELEASE_NAME> \
oci://registry.tecnisys.com.br/tdp/charts/tdp-argo \
-n <NAMESPACE> --create-namespace

After deploy or upgrade, confirm that Dex is running:

Terminal input
kubectl get pods -n <NAMESPACE> | grep dex
kubectl get svc -n <NAMESPACE> | grep dex

Also confirm the RBAC resources created by the chart:

Terminal input
kubectl get serviceaccount -n <NAMESPACE> | grep argo
kubectl get role -n <NAMESPACE> | grep argo
kubectl get rolebinding -n <NAMESPACE> | grep argo

Login

  • UI: access https://<ARGOCD_HOST> and use "LOG IN VIA LDAP" (local login/password is only for local accounts).
  • CLI: argocd login <ARGOCD_HOST> --sso

Troubleshooting

Initial checks

Check Argo CD server logs for LDAP connection errors and RBAC evaluation:

Terminal input
kubectl logs -n <NAMESPACE> deployment/<DEPLOYMENT_NAME> -f

Test LDAP from the Dex pod (example with ldapsearch):

Terminal input
kubectl exec -n <NAMESPACE> deployment/<DEPLOYMENT_NAME> -- \
ldapsearch -x -H ldap://<LDAP_HOST>:389 \
-D "<LDAP_BIND_DN>" \
-w "<PASSWORD>" \
-b "<LDAP_USER_BASE_DN>" \
"(uid=<USERNAME>)"

Replace deployment names with actual resources (kubectl get deploy -n <NAMESPACE>).

Common issues

ProblemProbable causeWhat to check
no such host for argocd-dex-serverDex is disabled or the Dex Service was not createdSet tdp-argo.dex.enabled: true and confirm `kubectl get pods,svc -n <NAMESPACE>
config referenced key does not exist in secretdex.config references keys that do not exist in argocd-secretConfirm the argocd-secret Secret exists and contains dex.ldap.bindDN and dex.ldap.bindPW
Invalid username or password or invalid LDAPConnectivity failure, incorrect bind DN/password, or incorrect user searchValidate LDAP server access from the cluster, check bindDN/password, userSearch.baseDN, filter, and LDAP server logs
Authenticated user has no permissionsLDAP user/group is not mapped to an Argo CD roleReview tdp-argo.rbacConfig.policy.csv, confirm LDAP group names, and check RBAC evaluation messages in Argo CD logs