Question on irods http api user mapping execution flow

24 views
Skip to first unread message

Bruno Santos

unread,
Jun 8, 2026, 10:31:31 AMJun 8
to iRODS-Chat
Hi there, 

I'm doing some tests with the irods-http-api and I found something I would like to clarify.

I have a setup with introspection, where the http-api is not able to map the irods username.

My understanding of the general flow ():
  1. The irods-http-api receives the request with the token (the token has the claims, including the custom claim  "uid"  to map the user)
  2. The irods-http-api calls the introspection endpoint to validate the token.
    • Introspectoin endpoint returns "active":true
  3. The irods-http-api parses the introspection response and tries to find the "irods_user_claim": "uid"
    • This fails, because, the claim exists only in the original token and not in the introspection response.
The oidc provider could add extra fields to the response, but I'm not sure on how standard is this (they are not required by the RFC), and I have no control over it...

I potentially could use the file mapping plugin to map the user using the mandatory field in the introspection response (sub), but that is extra complexity to build and maintain.

Btw, I tried with local_validation and it works for another provider, but from this specific provider, I get a jwt without the typ element.
This results into: validate_using_local_validation: invalid JWT, missing [typ].


My questions are:
  • In the introspection case: shouldn't the irods-http-api use the original token to map the user?
  • In the local_validation: isn't the irods-http-api too picky?



Extra details on the  introspection setup:

irods http api config.json:
(...)
                        "openid_connect": {
                                "timeout_in_seconds": 3600,
                                "provider_url": "https://auth.place.bb",
                                "client_id": "<client_id>",
"client_secret": "<client_secret>",
                                "access_token_validation_method": "introspection",
                                "require_aud_member_from_introspection_endpoint": false,
                                "state_timeout_in_seconds": 600,
                                "user_mapping": {
                                        "plugin_path": "/usr/lib/irods_http_api/plugins/user_mapping/libirods_http_api_plugin-user_claim.so",
                                        "configuration": {
                                                "irods_user_claim": "uid"
                                        }
                                }
                        }
(...)

Token decoded payload (partial):
{
  "scope": "openid profile email uid",
  "aud": [
    "<client_id>"
  ],
  "jti": "<value>",
  "client_id": "<client_id>",
  "sub": "2ca2570889e12e64f7f8...@auth.place.bb",
  "name": "Name1 The FamilyName",
  "given_name": "Name1",
  "family_name": "The FamilyName",
  "email": "em...@aaa.bb",
  "uid": [
    "username37"
  ],
  "sid": "<value>",
  "token_class": "access_token",
  "iss": "https://auth.place.bb",
  "iat": 1780918086,
  "exp": 1780921686
}


Logs:

[2026-06-08 11:28:09.866] [P:1] [debug] [T:14] resolve_client_identity: Bearer token: [<ommited>]
[2026-06-08 11:28:09.866] [P:1] [debug] [T:14] get_port_from_url: Detected HTTPS scheme, using port 443.
[2026-06-08 11:28:09.961] [P:1] [debug] [T:14] get_port_from_url: Detected HTTPS scheme, using port 443.
[2026-06-08 11:28:10.048] [P:1] [debug] [T:14] hit_introspection_endpoint: Received the following response: [{"active": true, "scope": "openid profile email uid", "client_id": "<client_id>", "exp": 1780921686, "iat": 1780918086, "sub": "2ca2570889e12e64f7f8...@auth.place.bb", "iss": "https://auth.place.bb", "token_type": "Bearer", "aud": ["<client_id>"]}]
[2026-06-08 11:28:10.049] [P:1] [trace] [T:14] validate_using_introspection_endpoint: Attempting [aud] validation.
[2026-06-08 11:28:10.049] [P:1] [trace] [T:14] validate_using_introspection_endpoint: Attempting [iss] validation.
[2026-06-08 11:28:10.049] [P:1] [debug] [T:14] user_mapper_match: Attempting match of _param [{"active":true,"aud":["<client_id>"],"client_id":"<client_id>","exp":1780921686,"iat":1780918086,"iss":"https://auth.place.bb","scope":"openid profile email uid","sub":"2ca2570889e12e64f7f8...@auth.place.bb","token_type":"Bearer"}].
[2026-06-08 11:28:10.049] [P:1] [warning] [T:14] resolve_client_identity: Could not find a matching user.


Regards,
Bruno

Martin Flores Jr

unread,
Jun 9, 2026, 4:19:36 PMJun 9
to irod...@googlegroups.com
Hello Bruno,

Thanks for reaching out and providing all of this information! I have created two issues on GitHub for the points that you've described.

For the introspection case, a link to the issue on GitHub follows: https://github.com/irods/irods_client_http_api/issues/497
I am glad that you pointed out that the response from the introspection endpoint, depending on the provider configuration, may not have the information required to map the users. I agree that the access token claims should be used if available, though the solution might still include the introspection response.

For the local validation, the link to the issue on GitHub follows: https://github.com/irods/irods_client_http_api/issues/496
I agree that the checking of the typ header is strict. It comes from a relatively recent standard for a JWT profile for OAuth tokens. The code around this check can be changed to opt-in since there are JWT access tokens that don't provide a specific typ, or a typ at all in some cases.

The strict checking of the typ header will most likely be handled first, so you should be able to use the local validation method to get by after that issue is resolved.

I also noticed that the "uid" claim you were trying to map is an array. Is there a particular reason the claim is an array? I'm asking since the current implementation of the user mapping only supports strings, not arrays, even if there is just one element.

Best Regards,

Martin Flores
Software Developer
iRODS Consortium

--
--
The Integrated Rule-Oriented Data System (iRODS) - https://irods.org
 
iROD-Chat: http://groups.google.com/group/iROD-Chat
---
You received this message because you are subscribed to the Google Groups "iRODS-Chat" group.
To unsubscribe from this group and stop receiving emails from it, send an email to irod-chat+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/irod-chat/95bdd0fe-aa66-450a-ab93-d74ac49c31ddn%40googlegroups.com.

Bruno Santos

unread,
Jun 10, 2026, 6:06:32 AMJun 10
to iRODS-Chat
Hi Martin,

Thank you for having a look into this.

Good point on the "uid" claim. Looks like I have extra issues...
I need that info to map the irods user.
I will ask the provider on the why it is an array. The spec (provider info) says it is an array, but only 1 value is allowed.

That raises the question: how to use a claim that is not a string?

As a claim can be any valid json, some kind of JsonPath would be nice.
Or just parse the claim value to string and use the `match_regex` to extract the data from the json ...


Regards,
Bruno
Reply all
Reply to author
Forward
0 new messages