LDAP Configuration
Honeyframe can mirror directory group membership into its own groups. Each organization configures its own LDAP (or Active Directory) server; groups that carry an LDAP DN get their membership reconciled from the directory, so access granted through a group follows the directory.
What LDAP does and doesn't do today:
| Capability | Status |
|---|---|
| Per-org server configuration (URL, bind account, search bases, filters) | Available — /api/admin/ldap-config |
| Connection test (bind + sample search) | Available |
| Group-membership sync into LDAP-mapped groups | Available, run on demand |
| Scheduled (automatic) sync | Not yet — the sync_enabled flag is stored, but sync runs only when triggered |
| Signing in with a directory password | Not available — users sign in with a local password, Google, Microsoft, or your org's OIDC / SAML provider (see Applications & SSO) |
| Creating users from the directory | Not available — users must already exist in the org; directory members without a matching user are skipped |
How sync works
- An org admin saves the org's LDAP configuration.
- On the Groups page, set an LDAP DN on each group that should follow the directory (for example
cn=analysts,ou=groups,dc=example,dc=com). Groups without a DN are local and never touched by sync. - A sync run reads each mapped group's members from the directory (the
group_member_attribute, defaultmember), resolves each member to itsuser_id_attributevalue (defaultmail), and matches that value against the email of users in the org. - For each mapped group, members the directory added are added, and members the sync previously added but the directory dropped are removed.
Memberships granted by hand in the Groups console, by an approved access request, or by a recertification are kept — sync only removes rows it created itself. That means you can add a temporary member to a directory-mapped group without the next sync undoing it.
Configuration
All endpoints require org.admin and act on the caller's own organization.
| Endpoint | Description |
|---|---|
GET /api/admin/ldap-config | Current configuration (never the bind password), plus the last sync's time, status, error, and counts. Returns {"configured": false} when none is saved. |
PUT /api/admin/ldap-config | Save the configuration. The bind password is required on first save and optional afterwards (omit it to keep the stored one). |
DELETE /api/admin/ldap-config | Remove the org's LDAP configuration. |
POST /api/admin/ldap-config/test | Bind and run a small user search. With an empty body it tests the saved configuration; with connection fields in the body it tests them before you save. |
POST /api/admin/ldap-config/sync | Run a membership sync now. Returns counts (groups_synced, users_added, users_removed) and any error; a failed sync answers 200 with ok: false so the error can be shown inline. |
Configuration fields:
| Field | Default | Meaning |
|---|---|---|
server_url | — | ldaps://ldap.example.com:636 or ldap://…. |
use_ssl | true | Connect over TLS. |
bind_dn, bind_password | — | Service account used to read users and groups. The password is encrypted at rest with the platform's secret-encryption key. |
user_search_base | — | Base DN for user searches. |
group_search_base | the user search base | Base DN for groups. |
user_filter | (&(objectClass=person)(mail=*)) | Filter used by the connection test's user search. |
group_member_attribute | member | Attribute on a group entry that lists its members. |
user_id_attribute | mail | Attribute whose value must equal the Honeyframe user's email. |
sync_enabled | false | Stored for a future scheduled sync; has no effect today. |
curl -X PUT https://platform.your-domain.com/api/admin/ldap-config \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"server_url": "ldaps://ldap.example.com:636",
"bind_dn": "cn=honeyframe,ou=service-accounts,dc=example,dc=com",
"bind_password": "<redacted>",
"user_search_base": "ou=users,dc=example,dc=com",
"group_search_base": "ou=groups,dc=example,dc=com",
"user_id_attribute": "mail"
}'
curl -X POST https://platform.your-domain.com/api/admin/ldap-config/test \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{}'
Troubleshooting
- Members not added — the directory value of
user_id_attributemust equal the user's email in Honeyframe exactly, and the user must already belong to the org. See Permission denied after LDAP sync. - Bind fails — test with the same DN and password from the Platform host (
ldapwhoami), and check that the host trusts the directory's TLS certificate.
See also Installation → LDAP for directory-side preparation.