LDAP
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
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
namespace | string | No | default | Namespace for created entities |
server | string | Yes | - | LDAP server hostname or IP |
port | integer | No | 389 | LDAP server port (636 for SSL) |
use_tls | boolean | No | false | Use STARTTLS encryption |
use_ssl | boolean | No | false | Use SSL/TLS connection |
bind_dn | string | No | null | DN for authentication |
bind_password | string | No | null | Password for authentication |
timeout | integer | No | 30 | Connection timeout in seconds |
page_size | integer | No | 1000 | Page size for pagination |
user_selectors | list | No | [] | User object selectors |
group_selectors | list | No | [] | Group object selectors |
org_unit_selectors | list | No | [] | OU object selectors |
Selector Options
Each selector defines search criteria:
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
base_dn | string | Yes | - | Base DN to start search |
search_filter | string | No | (objectClass=*) | LDAP search filter |
search_scope | string | No | SUBTREE | Search scope (BASE, ONELEVEL, SUBTREE) |
attributes | list | No | ["*"] | Attributes to retrieve |
Authentication
Service Account (Recommended)
Create a read-only service account:
- Create service account in LDAP
- Grant read permissions
- 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: UsernamedisplayName/cn: Full namemail: Email addressdepartment: Departmenttitle: Job titlemanager: Manager DNmemberOf: 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 namedescription: Group descriptionmember/uniqueMember: Group membersmanagedBy: Group managergroupType: 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:
- Verify server hostname/IP is correct
- Check port (389 for LDAP, 636 for LDAPS)
- Ensure firewall allows connection
- Test with
ldapsearchcommand - For TLS: Verify certificate is valid
Authentication Errors
Symptom: "Invalid credentials" or "Bind failed"
Solutions:
- Verify
bind_dnformat is correct - Check password is correct
- Ensure service account is not disabled/locked
- For AD: Use DN format, not username
- Try anonymous binding if supported
Missing Objects
Symptom: Expected users/groups not discovered
Solutions:
- Verify
base_dnis correct - Check
search_filtermatches objects - Ensure service account has read permissions
- Review
search_scope(use SUBTREE for deep searches) - Check logs for errors
Pagination Issues
Symptom: Not all objects returned
Solutions:
- Increase
page_size - Check LDAP server pagination limits
- Review logs for pagination warnings
- For large directories, consider multiple selectors
SSL/TLS Errors
Symptom: Certificate verification failed
Solutions:
- Verify certificate is valid and trusted
- Check certificate chain
- Use
use_tls: truefor port 389 - Use
use_ssl: truefor port 636 - Ensure correct port for SSL/TLS mode
Performance Tips
- Use specific base DNs: Narrow search scope
- Efficient filters: Filter at LDAP level
- Limit attributes: Only retrieve needed attributes
- Pagination: Use appropriate
page_size - Adjust interval: Balance freshness vs. server load
- Indexed attributes: Use attributes with directory indexes
Integration Examples
Link Users to GitHub
Map LDAP users to GitHub accounts:
# Use email or username matching
LdapUser (jdoe@company.com) --SAME_AS--> GithubUser (jdoe)
Link Groups to Teams
LdapGroup (Developers) --CORRESPONDS_TO--> Team (Platform)
Track Access
Link users to resources they can access:
LdapUser --HAS_ACCESS_TO--> Resource
Security Considerations
- Use read-only accounts: Service accounts should have minimal permissions
- Secure credentials: Store passwords in secrets management
- Use TLS/SSL: Encrypt connections
- Regular rotation: Rotate service account passwords
- Audit logs: Monitor LDAP access logs
- Network security: Use VPN or private networks
Next Steps
- Configure GitHub molecule to link user accounts
- Set up Jira molecule to link issue assignments
- Learn about entity relationships
- Explore user and group mapping strategies