feat(auth): assign elevated LDAP roles via configurable filters

The LDAP sync only ever granted the base "user" role. Add an optional
auth.ldap.role-filters map (role -> LDAP filter) so accounts matching a
filter are granted that elevated role (admin/support/api/manager).

LDAP is authoritative for the configured roles: sync both adds and removes
them to match group membership, while roles not listed (e.g. a manually
granted manager) are preserved. A managed manager that still has assigned
projects is never stripped. With no role-filters configured behaviour is
identical to before.

Roles are reconciled during periodic sync and at login. Sync evaluates
each filter once over the whole base (one search per role, not per user)
and reconciles existing users via a single ListUsers lookup plus the new
UserRepository.UpdateRoles helper.

Closes #74

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: e38526c3259d
This commit is contained in:
2026-06-19 06:36:55 +02:00
co-authored by Claude Opus 4.8
parent 1bd3f25371
commit 63a82d022b
4 changed files with 343 additions and 3 deletions
+7
View File
@@ -131,6 +131,13 @@ var configSchema = `
"sync-password": {
"description": "Password for the LDAP admin account used for syncing. Overridden by the LDAP_ADMIN_PASSWORD environment variable when set.",
"type": "string"
},
"role-filters": {
"description": "Maps an elevated role to an LDAP filter; accounts matching the filter are granted that role. LDAP is authoritative for every role listed here (roles are added and removed to match group membership), while roles not listed are preserved. Applied during sync and at login. Valid keys: admin, support, api, manager.",
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"required": ["url", "user-base", "search-dn", "user-bind", "user-filter"]