goauthentik / goauthentik/authentik
Use policies to calculate LDAP provider attributes
- Dominant language
- Python
- Stars
- 25.6k
- Forks
- 2k
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 651
Description
### Is your feature request related to a problem?
There are many issues/pain points related to the LDAP provider that would be solved if the administrator had more control over how attributes were calculated. Currently, all attributes and objects are hard-coded, with only user and group custom attributes being merged into the results to provide some kind of customization. This is strange as many other features of authentik can be customized with property mappings.
The current implementation poses the following problems:
- Fixed schema definitions; this has multiple knock-on effects:
- Can't define custom schemas for applications that expect their schemas to be loaded, and that will fail if they can't find them
- The currently provided schemas are not well-defined and, in a hyper-strict environment, do not provide full coverage; examples:
- The `nsContainer` `objectClass` used by built-in OUs is not defined, and a strict client that validates `objectClass`es may choke on it
- Any client that attempts to validate the type, syntax, etc of a custom attribute on a user or group will choke, since none of those are defined either
- Buggy interactions with built-in attributes (e.g. #24372)
- Unable to prevent the exposure of potentially private/internal/sensitive custom attributes; e.g. in my environment, I store logs of the last-run of external user provisioning actions as custom attributes, and they're exposed as LDAP attributes when I'd rather them not be
- Overriding built-in attributes *requires* updating *every user's custom attributes*, so have fun scripting that if you want everyone to have a specific attribute, be it derived from something else or a static value
- N.B.: This is much more easily attainable if you are sourcing your users/groups from a sync job that already has property mapping policies, but if you are using authentik as a primary source of truth without syncs, this will have to be done manually and potentially external to authentik
### Describe the solution you'd like
Replace the current system whereby custom user and group attributes are returned as LDAP attributes with one based on policies. I can think of ~two~ three directions for this:
1. Implement user, group, and schema LDAP property mappings
- Pros:
- Easier to cache on a micro level: don't need to run a potentially very large policy if only a single user's cache is invalidated
- Likely easier to implement given current code
- Easily build and cache new objects, and delete no longer existing objects from cache before using the entries
- Cons:
- Multiple property mappings required for multiple object types; complexity grows and overall performance decreases with each supported type
- Need to run a bunch of small policies repeatedly to get a full update of all users/groups, which would likely take longer than a monolithic solution
- Notes:
- Schema mappings would be useful for strict clients, but probably aren't *really* necessary for most clients, I imagine
- Potentially could implement mappings for other structural types, like containers, virtual groups, or roles
2. Implement a single policy that returns the entire LDAP tree
- Pros:
- Simpler from an architectural standpoint
- Immediately allows full customization of the entire LDAP system for any purpose, will be inherently compatible with any LDAP client (as long as they don't implement unsupported extensions)
- Cons:
- Harder to cache, can't invalidate individual objects and full refresh is needed every time
- Potentially very heavy operation, policy to give 1:1 functionality with current system would likely be quite large
3. Hybrid single that works like 2. but can have context set that allows retrieving individual objects; this assumes the policy is implemented with functions called to build each object, and those functions can be called one-off based on an object's type and ID provided at policy runtime
- Pros:
- All benefits of 1. andd 2.
- Cons:
- More confusing for the user to read and write
- Even more complex and heavier policy
- Requires different and unique architecture that no other policy does
[Concerns about performance](https://github.com/goauthentik/authentik/issues/10210#issuecomment-2188708309) could be offset by caching, which the LDAP outpost already implements. Background updates could be utilized, so as to not slow down queries with running policies.
### Describe alternatives that you've considered
Use custom attributes. But, this is very clunky and requires potentially out-of-band management processes to get even a somewhat reliable solution. Custom attributes would not be able to be guaranteed to be updated in tandem with user updates, and existing in-use attributes may need to be duplicated and re-formatted to be more easily consumed by LDAP clients. In my experience, it is simply not tenable. I mean, [just look at this absolute monster](https://github.com/goauthentik/authentik/issues/21950#issuecomment-4809497155) and tell me there isn't a problem to be solved here.
### Additional context
Could be considered a dupe of #10210, but I feel the scope is more focused.
I believe implementing this would close *at least*:
- #24372
- #24313
- #25262
- #25313
- #16954
- #15722
- #10601
- #7985
and maybe close/help:
- #13416
- #11819
- #10123
- #6120 (specific to Synology)
Contributor guide
Research direction
No files or tests are named. Start by tracing the LDAP provider and outpost attribute/schema handling, then read the related issues (#10210, #24372, and the listed follow-ups) to understand existing constraints; done means agreeing on and implementing a policy-based design with suitable caching and coverage for the stated LDAP objects.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- authentication, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100