Feat: Add authentik idp#8619
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces support for Authentik as an Identity Provider (IdP) in SSSD, including documentation, a new lookup implementation, and JSON parsing enhancements. Several critical issues were identified in the review: a syntax error due to missing parentheses in a conditional check, incorrect parameter types and redundant calls during URL encoding of device codes, and logic errors in identifying Authentik users and groups. Specifically, using 'pk' for both user and group identifiers prevents proper object differentiation, and the user lookup logic should be updated to check for the 'pk' attribute to align with Authentik's API.
e2158a2 to
3cdafa1
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request adds support for Authentik as an Identity Provider, including documentation, a new lookup implementation, and enhanced JSON parsing. Feedback points out a potential crash in parse_result due to a missing NULL check when encoding the device_code and a typo in store_json_user where uid was used instead of uuid.
3cdafa1 to
677e00c
Compare
@Maddosaurus, take this with a grain of salt as some points might be off. If you prefer, feel free to postpone addressing this until somebody from maintainers performs a review. |
677e00c to
bd08e60
Compare
bd08e60 to
f0a57c4
Compare
|
@alexey-tikhonov I'd appreciate a human review at this point, as it seems that recent changes on master resulted in this code not working when rebased against the latest master. |
|
Could you please rebase on the top of the current 'master' branch? |
1c58c51 to
ba1d25b
Compare
|
I've rebased on master - to describe the current situation: Authentik uses random special characters for the device code, and loading/saving the JSON object in SSSD via the jansson lib strips some of the escaping. I suspect that the device code needs to be url sanitized when loaded from the buffer ( I suspect a3c506d to be one of the reasons for a change in behaviour. This escaping of my change is not needed anymore because of improved URL data escaping, I will remove that. |
|
This currently doesn't build: |
|
I've removed the not needed function I mentioned earlier. Could you advise what the best strategy would be to ensure proper url safe encoding of the token that is stored in An example device token that Authentik returns: |
Hi, I'm a bit confused because the error in the logs you've send is coming from the Can you recompile after running bye, |
I see, thanks for the clarification. I'm not entirely sure where to escape the device code best after the recent changes. Any advice is appreciated.
You should find the logs in your inbox momentarily. |
|
@sumit-bose / @alexey-tikhonov From my point of view the PR is ready for a review. I can confirm that Authentik OIDC now works correctly. |
Thank you. Take a note it will take some time though, as we are going thru release cycle now. |
|
Hi @Maddosaurus, sorry for making you wait so long. I did a first review round, going thru feedback provided by sssd-bot, and added as inline comments items that I find valid / need addressing. |
| uuid = json_object_get(group, "id"); | ||
| if (!json_is_string(uuid)) { | ||
| uuid = json_object_get(group, "pk"); | ||
| } |
There was a problem hiding this comment.
This will go out of control very soon.
If SSSD is going to support very different IdP providers with different attribute names then there should be name maps (as LDAP based providers have).
There was a problem hiding this comment.
I understand your point. Given the time this PR has been open, and the fact that I'm not very familiar with the codebase (yet), I'd be glad if we could not implement the name map in the context of this PR.
Let's address this in a follow up PR, either by me or a maintainer. How about that?
There was a problem hiding this comment.
Not sure. Maybe we could have a dedicated feature branch.
There was a problem hiding this comment.
Sure, we can do that. I want to get this current PR wrapped up soon, as it has been open for 2 months now.
I'd really like to land the current changes in SSSD and address improvements either in a feature branch or a follow up PR.
There was a problem hiding this comment.
Hi,
there should be no changes to the general backend code. Please see my comments about setting id in authentik_lookup().
bye,
Sumit
| char buffer[64]; | ||
| json_int_t i_val = json_integer_value(tmp); | ||
| snprintf(buffer, sizeof(buffer), "%" JSON_INTEGER_FORMAT, i_val); | ||
| str = talloc_strdup(mem_ctx, buffer); |
There was a problem hiding this comment.
You could use single talloc_asprintf() instead.
But so far I don't understand why this fallback is needed at all.
|
|
||
| switch (oidc_cmd) { | ||
| case GET_USER_GROUPS: | ||
| uri = talloc_asprintf(rest_ctx, |
There was a problem hiding this comment.
You need either to use tmp context and free it at function exit, or free 'uri' explicitly here before assigning new memory allocation.
Otherwise it will hang on 'rest_ctx'.
There was a problem hiding this comment.
Before I do this: This part is functionally identical to
https://github.com/Maddosaurus/sssd/blob/d6c76c57a667f6cc8e768f852c58070ff3814279/src/oidc_child/oidc_child_id.c#L413-L416
and to
https://github.com/Maddosaurus/sssd/blob/d6c76c57a667f6cc8e768f852c58070ff3814279/src/oidc_child/oidc_child_id.c#L210-L213
That would apply there as well, correct?
There was a problem hiding this comment.
I've updated this only for the Authentik for now - in d75f932
|
@Maddosaurus, please |
87d6cd5 to
5307184
Compare
348ec8b to
cc9aca9
Compare
:relnote: Add Authentik as an IDP integration option.
cc9aca9 to
d75f932
Compare
|
@alexey-tikhonov @sumit-bose given this PR has been open for over 2 months now, I would really like to focus on landing these changes in SSSD. Please let me know what we need to address right away. Thanks! |
It's currently pending @sumit-bose's review. But to set proper expectations: we are being "swamped" with PRs and requests to support new IdP types - authentik (this PR), Entra ID via himmelblau, Ahdapa IdP, Okta... This creates a number of issues. |
sumit-bose
left a comment
There was a problem hiding this comment.
Hi,
thank you for your patience. I was finally able to install the authentik containers (it looks like the real docker tools are needed here, I run into issues with the podman based ones coming with Fedora) and test your PR. It is working as expected, but see my comments in the code.
As mentioned otherwise we are thinking about a proper plugin interface e.g. to allow IdPs or other interested parties to provided their own plugins. For the time being I think it makes sense to include your code in the main SSSD tree. But after a first version of the plugin interface is available we might want to remove it from the main tree and host it in a dedicated repository.
bye,
Sumit
| : "\", \"verification_uri_complete\": \"", | ||
| dc_ctx->verification_uri_complete == NULL ? "" | ||
| : dc_ctx->verification_uri_complete); | ||
| tmp_json = json_pack("{s:s, s:i, s:i}", |
There was a problem hiding this comment.
Hi,
thank you for adding proper JSON support here. I would suggest to move the generation of the two output line to oidc_child_json.c so that here only a single fprintf() has to be called.
bye,
Sumit
| * https://api.goauthentik.io/ */ | ||
| errno_t authentik_lookup(TALLOC_CTX *mem_ctx, enum oidc_cmd oidc_cmd, | ||
| char *base_url, | ||
| char *input, enum search_str_type input_type, |
There was a problem hiding this comment.
Hi,
yes, basically input_type is a placeholder for lookups by id which might be available in future. If you want to avoid this warning you can add something like e.g.
if (input_type ==TYPE_OBJECT_ID) {
ret = ENOTSUP;
goto done;
}
bye,
Sumit
| rest_ctx, get_http_data(rest_ctx), "results", "pk"); | ||
|
|
||
| if (obj_id == NULL) { | ||
| DEBUG(SSSDBG_OP_FAILURE, "Failed to read mandatory object id.\n"); |
There was a problem hiding this comment.
Hi,
please read uid for users and pk for groups here and store the values as id in out. This way you cam remove the changes in idp_id_eval.c. It is expected that out contains besides posixUsername etc which are added inadd_posix_to_json() the id attribute which a unique identifier for the user or group object. Since this unique attribute is provider specific it is best to set it here instead of figuring it out in the backend.
Additionally, since you need the user's pk for the group-memberships I would suggest to create a get_str_attr_from_embed_json_int() to avoid the fallback in get_json_string().
bye,
Sumit
| json_t *id_object = NULL; | ||
| const char *user_identifier = NULL; | ||
| const char *id_attr_list[] = { "sub", "id", NULL }; | ||
| const char *id_attr_list[4]; |
There was a problem hiding this comment.
Hi,
what is the purpose of this change? I'm asking because it is changing the behavior of this function. If user_identifier_attr is given the function should only be successful if user_identifier_attr is present, there should be no fall back. Only if user_identifier_attr is not set sub and id should be checked.
bye,
Sumit
| uuid = json_object_get(group, "id"); | ||
| if (!json_is_string(uuid)) { | ||
| uuid = json_object_get(group, "pk"); | ||
| } |
There was a problem hiding this comment.
Hi,
there should be no changes to the general backend code. Please see my comments about setting id in authentik_lookup().
bye,
Sumit
This PR add Authentik as an available IDP provider besides Entra and Keycloak.
From a quick look around the Authentik repo, it looks they do daily test runs against their Compose deployment (see this workflow).
For testing, starting from a fresh Authentik instance (Docker compose instructions), the following additional configuration is needed:
sssd-prod-prov) and auth flow (e.g.default-provider-authorization-implicit-consent (Authorize Application))authentik default OAuth Mapping: authentik API accessto "Selected Scopes"sssd-prod-appand select the previously created provider (e.g.sssd-prod-prov)ak-<application>-client_credentials)authentik user goup read-only)authentik CoreselectCan view GroupandCan view Userakservice user of your application: Users -> $serviceaccout -> Roles -> Add to existing role -> select the created roleCombined with the following
sssd.confthis will result in a running setup for ssh login and sudo management:Note that authentik does not have application-specific endpoints for token, userinfo and device auth, but instead global endpoints. For example, the token endpoint for a given Authentik server would be
https://prod.idp.tld.com/application/o/token(onlyauthentik.companyis a placeholder in this config).Fixes #8613