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