goauthentik / goauthentik/authentik
LDAP Sync removes group memberships after every sync (group.users.set() clears members)
- Dominant language
- Python
- Stars
- 25.6k
- Forks
- 2k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 644
Description
### Describe the bug
After every LDAP sync, all group memberships are cleared for LDAP-synced users.
The sync correctly imports users and groups (with ldap_uniq), but the membership
relationship between users and groups is lost after each sync run.
### How to reproduce
1. Configure LDAP Source with Active Directory
2. Run LDAP sync → Users and groups imported correctly ✅
3. Check group memberships → Members are assigned ✅
4. Run LDAP sync again
5. Check group memberships → **All memberships are gone** ❌
### Expected behavior
Group memberships should persist after LDAP sync, or be correctly
re-created based on LDAP group membership attributes (e.g. `member` attribute).
Actual behavior
After every sync, `group.users.set()` is called which **clears all existing
memberships** and only re-adds members if they are explicitly listed in the
LDAP group's `member` attribute during that sync run.
### Screenshots
_No response_
### Additional context
Groups have correct ldap_uniq values set in authentik_core_group
Users have correct ldap_uniq values set in authentik_core_user
The issue occurs 100% reproducibly on every sync run
Possibly related to: #18726
## Database verification
```sql
-- After sync: only akadmin remains
SELECT u.username, STRING_AGG(g.name, ', ') AS groups
FROM authentik_core_user u
JOIN authentik_core_user_groups ug ON u.id = ug.user_id
JOIN authentik_core_group g ON g.group_uuid = ug.group_id
GROUP BY u.username ORDER BY u.username;
-- Result: only akadmin | authentik Admins
-- All LDAP users lose their group memberships
Workaround
We implemented a cronjob that re-inserts memberships directly via SQL every 5 minutes using the ldap_uniq attribute to match users to groups. This is not a sustainable solution.
Workaround used
Re-inserting memberships every 5 minutes via cronjob directly in PostgreSQL:
INSERT INTO authentik_core_user_groups (user_id, group_id)
SELECT u.id, g.group_uuid
FROM authentik_core_user u
JOIN authentik_core_group g
ON g.attributes->>'ldap_uniq' = ANY(
ARRAY(SELECT jsonb_array_elements_text(u.attributes->'memberOf'))
)
ON CONFLICT DO NOTHING;
Logs
No errors visible in authentik-worker-1 logs during or after sync. The sync completes with "event": "Task finished", "exc": null – making this bug hard to detect without manually checking the database.
## LDAP Property Mappings
### Custom LDAP Group Mapping
```python
return {
"name": ldap.get("cn"),
"attributes": {
"ldap_dn": ldap.get("distinguishedName"),
"ldap_uniq": ldap.get("distinguishedName"),
"distinguishedName": ldap.get("distinguishedName"),
"member": ldap.get("member", []),
}
}
### Custom LDAP User Mapping
```python
return {
"name": ldap.get("displayName"),
"username": ldap.get("sAMAccountName"),
"email": ldap.get("mail"),
"attributes": {
"ldap_dn": ldap.get("distinguishedName"),
"ldap_uniq": ldap.get("distinguishedName"),
"distinguishedName": ldap.get("distinguishedName"),
"memberOf": ldap.get("memberOf", []),
"upn": ldap.get("userPrincipalName"),
"sn": ldap.get("sn"),
"givenName": ldap.get("givenName"),
}
}
### Deployment Method
Docker
### Version
2026.2.1
### Relevant log output
```shell
```
Contributor guide
Assessment
This issue has not been assessed yet.