Skip to main content
Version: Beta

LDAP

Discovery

Discover and manage users, groups, and organizational units from LDAP directories in your Devgraph knowledge graph.

Overview​

The LDAP molecule connects to LDAP directories (Active Directory, OpenLDAP, etc.) to discover directory objects and create corresponding entities. It supports flexible search filters, pagination for large directories, and multiple object types.

Key Features:

  • Discover users, groups, and organizational units
  • Support for Active Directory and OpenLDAP
  • Flexible LDAP search filters
  • Paginated searches for large directories
  • Multiple search scopes (BASE, ONELEVEL, SUBTREE)
  • Secure TLS/SSL connections

Quick Start​

providers:
- name: ldap
type: ldap
every: 600 # Reconcile every 10 minutes
config:
namespace: default
server: ldap.example.com
port: 389
use_tls: true
bind_dn: cn=readonly,dc=example,dc=com
bind_password: ${LDAP_PASSWORD}
user_selectors:
- base_dn: ou=Users,dc=example,dc=com
search_filter: "(objectClass=user)"

Configuration​

Basic Configuration (Active Directory)​

providers:
- name: active-directory
type: ldap
every: 600
config:
namespace: default
server: ad.company.com
port: 389
use_tls: true
bind_dn: cn=svc-devgraph,ou=Service Accounts,dc=company,dc=com
bind_password: ${AD_PASSWORD}
timeout: 30
page_size: 1000
user_selectors:
- base_dn: ou=Users,dc=company,dc=com
search_filter: "(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"
search_scope: SUBTREE
attributes: ["*"]
group_selectors:
- base_dn: ou=Groups,dc=company,dc=com
search_filter: "(objectClass=group)"
search_scope: SUBTREE
attributes: ["*"]
org_unit_selectors:
- base_dn: dc=company,dc=com
search_filter: "(objectClass=organizationalUnit)"
search_scope: SUBTREE
attributes: ["*"]

OpenLDAP Configuration​

providers:
- name: openldap
type: ldap
every: 600
config:
namespace: default
server: ldap.example.org
port: 389
use_tls: true
bind_dn: cn=readonly,dc=example,dc=org
bind_password: ${LDAP_PASSWORD}
user_selectors:
- base_dn: ou=people,dc=example,dc=org
search_filter: "(objectClass=inetOrgPerson)"
search_scope: SUBTREE
group_selectors:
- base_dn: ou=groups,dc=example,dc=org
search_filter: "(objectClass=groupOfNames)"
search_scope: SUBTREE

SSL/TLS Configuration​

providers:
- name: ldap-ssl
type: ldap
every: 600
config:
namespace: default
server: ldaps.company.com
port: 636
use_ssl: true # Use SSL on port 636
bind_dn: cn=readonly,dc=company,dc=com
bind_password: ${LDAP_PASSWORD}
user_selectors:
- base_dn: dc=company,dc=com
search_filter: "(objectClass=user)"

Anonymous Binding​

providers:
- name: ldap-anonymous
type: ldap
every: 600
config:
namespace: default
server: ldap.public.com
port: 389
bind_dn: null # Anonymous binding
bind_password: null
user_selectors:
- base_dn: dc=public,dc=com
search_filter: "(objectClass=person)"

Configuration Options​

OptionTypeRequiredDefaultDescription
namespacestringNodefaultNamespace for created entities
serverstringYes-LDAP server hostname or IP
portintegerNo389LDAP server port (636 for SSL)
use_tlsbooleanNofalseUse STARTTLS encryption
use_sslbooleanNofalseUse SSL/TLS connection
bind_dnstringNonullDN for authentication
bind_passwordstringNonullPassword for authentication
timeoutintegerNo30Connection timeout in seconds
page_sizeintegerNo1000Page size for pagination
user_selectorslistNo[]User object selectors
group_selectorslistNo[]Group object selectors
org_unit_selectorslistNo[]OU object selectors

Selector Options​

Each selector defines search criteria:

OptionTypeRequiredDefaultDescription
base_dnstringYes-Base DN to start search
search_filterstringNo(objectClass=*)LDAP search filter
search_scopestringNoSUBTREESearch scope (BASE, ONELEVEL, SUBTREE)
attributeslistNo["*"]Attributes to retrieve

Authentication​

Create a read-only service account:

  1. Create service account in LDAP
  2. Grant read permissions
  3. Use in configuration:
bind_dn: cn=svc-devgraph,ou=Service Accounts,dc=company,dc=com
bind_password: ${LDAP_PASSWORD}

Set environment variable:

export LDAP_PASSWORD="your-secure-password"

Anonymous Binding​

For publicly accessible LDAP:

bind_dn: null
bind_password: null

Entities Created​

LdapUser​

Represents a user account from the directory.

Entity Structure:

apiVersion: entities.devgraph.ai/v1
kind: LdapUser
metadata:
name: jdoe
namespace: default
spec:
dn: cn=John Doe,ou=Users,dc=company,dc=com
attributes:
sAMAccountName: jdoe
displayName: John Doe
mail: jdoe@company.com
department: Engineering
title: Software Engineer
manager: cn=Jane Smith,ou=Users,dc=company,dc=com

Common Attributes:

  • sAMAccountName / uid: Username
  • displayName / cn: Full name
  • mail: Email address
  • department: Department
  • title: Job title
  • manager: Manager DN
  • memberOf: Group memberships

LdapGroup​

Represents a group or security group.

Entity Structure:

apiVersion: entities.devgraph.ai/v1
kind: LdapGroup
metadata:
name: developers
namespace: default
spec:
dn: cn=Developers,ou=Groups,dc=company,dc=com
attributes:
cn: Developers
description: Development team
member:
- cn=John Doe,ou=Users,dc=company,dc=com
- cn=Jane Smith,ou=Users,dc=company,dc=com
groupType: "-2147483646"

Common Attributes:

  • cn: Group name
  • description: Group description
  • member / uniqueMember: Group members
  • managedBy: Group manager
  • groupType: Group type (AD)

LdapOrgUnit​

Represents an organizational unit.

Entity Structure:

apiVersion: entities.devgraph.ai/v1
kind: LdapOrgUnit
metadata:
name: engineering
namespace: default
spec:
dn: ou=Engineering,dc=company,dc=com
attributes:
ou: Engineering
description: Engineering department

LDAP Search Filters​

Active Directory Examples​

Enabled Users Only​

(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))

Security Groups​

(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=2147483648))

Service Accounts​

(&(objectClass=user)(servicePrincipalName=*))

Users in Specific Department​

(&(objectClass=user)(department=Engineering))

OpenLDAP Examples​

All Users​

(objectClass=inetOrgPerson)

Groups​

(objectClass=groupOfNames)

Users with Email​

(&(objectClass=inetOrgPerson)(mail=*))

Search Scopes​

SUBTREE (Most Common)​

Search base DN and all descendants:

search_scope: SUBTREE

ONELEVEL​

Search only direct children:

search_scope: ONELEVEL

BASE​

Search only the base DN itself:

search_scope: BASE

Use Cases​

User Directory Sync​

user_selectors:
- base_dn: ou=Employees,dc=company,dc=com
search_filter: "(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"
search_scope: SUBTREE

Department-Based Discovery​

user_selectors:
- base_dn: ou=Engineering,ou=Departments,dc=company,dc=com
search_filter: "(objectClass=user)"
- base_dn: ou=Sales,ou=Departments,dc=company,dc=com
search_filter: "(objectClass=user)"

Security Group Discovery​

group_selectors:
- base_dn: ou=Security Groups,dc=company,dc=com
search_filter: "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=2147483648))"

Troubleshooting​

Connection Issues​

Symptom: Cannot connect to LDAP server

Solutions:

  1. Verify server hostname/IP is correct
  2. Check port (389 for LDAP, 636 for LDAPS)
  3. Ensure firewall allows connection
  4. Test with ldapsearch command
  5. For TLS: Verify certificate is valid

Authentication Errors​

Symptom: "Invalid credentials" or "Bind failed"

Solutions:

  1. Verify bind_dn format is correct
  2. Check password is correct
  3. Ensure service account is not disabled/locked
  4. For AD: Use DN format, not username
  5. Try anonymous binding if supported

Missing Objects​

Symptom: Expected users/groups not discovered

Solutions:

  1. Verify base_dn is correct
  2. Check search_filter matches objects
  3. Ensure service account has read permissions
  4. Review search_scope (use SUBTREE for deep searches)
  5. Check logs for errors

Pagination Issues​

Symptom: Not all objects returned

Solutions:

  1. Increase page_size
  2. Check LDAP server pagination limits
  3. Review logs for pagination warnings
  4. For large directories, consider multiple selectors

SSL/TLS Errors​

Symptom: Certificate verification failed

Solutions:

  1. Verify certificate is valid and trusted
  2. Check certificate chain
  3. Use use_tls: true for port 389
  4. Use use_ssl: true for port 636
  5. Ensure correct port for SSL/TLS mode

Performance Tips​

  1. Use specific base DNs: Narrow search scope
  2. Efficient filters: Filter at LDAP level
  3. Limit attributes: Only retrieve needed attributes
  4. Pagination: Use appropriate page_size
  5. Adjust interval: Balance freshness vs. server load
  6. Indexed attributes: Use attributes with directory indexes

Integration Examples​

Map LDAP users to GitHub accounts:

# Use email or username matching
LdapUser (jdoe@company.com) --SAME_AS--> GithubUser (jdoe)
LdapGroup (Developers) --CORRESPONDS_TO--> Team (Platform)

Track Access​

Link users to resources they can access:

LdapUser --HAS_ACCESS_TO--> Resource

Security Considerations​

  1. Use read-only accounts: Service accounts should have minimal permissions
  2. Secure credentials: Store passwords in secrets management
  3. Use TLS/SSL: Encrypt connections
  4. Regular rotation: Rotate service account passwords
  5. Audit logs: Monitor LDAP access logs
  6. Network security: Use VPN or private networks

Next Steps​