Open MartinFlores751 opened 2 weeks ago
Hi @MartinFlores751 , I am wondering if you really mean ID Token or Access Token here, because they are different in both definition and use. Considering this is essentially a reseource server, the appropriate token to use would be an access token and ID tokens should not be let in. Or am I mistaken? If we are checking an access token via introspection from a server as in
then the possible json-response members are defined here https://datatracker.ietf.org/doc/html/rfc7662#section-2.2. In this case,
it would be nice to check the token_type
to make sure that we are actually dealing with an access token and not a different one.
Similarly, it is also good idea to reject access tokens deemed too old by checking the iat
. One problem that could arise when checking time-based values in the introspection response json members, including exp
and nbf
, is clock synchronizations. Usually it is not a bad idea to allow a clock skew of a couple of seconds.
When validating access tokens locally as in
then the verifications steps are outlined here https://datatracker.ietf.org/doc/html/rfc9068#section-4. Most importantly, in both cases (local or remote introspection), an access token might present some scopes. These scopes will have to be somehow taken into account because this is an important feature of the concept of access tokens. I will elaborate more on this in #248.
Hi @MartinFlores751 , I am wondering if you really mean ID Token or Access Token here, because they are different in both definition and use. Considering this is essentially a reseource server, the appropriate token to use would be an access token and ID tokens should not be let in. Or am I mistaken?
Yes, ID Tokens and Access Tokens do serve different purposes, and when operating as a protected resource, we should only accept access tokens.
However, as an artifact of our initial implementation, we do have the option to run as an OpenID Client:
In client mode, we do utilize ID Tokens, in both the Authorization Code Grant:
And the Resource Owner Password Credentials Grant (which is planned to be removed #363):
This issue is to address these use cases.
Of note, I plan on creating an issue on considering the removal of this mode. I'll link back to it when I do create it.
If we are checking an access token via introspection from a server as in
then the possible json-response members are defined here https://datatracker.ietf.org/doc/html/rfc7662#section-2.2. In this case, it would be nice to check the
token_type
to make sure that we are actually dealing with an access token and not a different one.
This check was initially left out as it seems the only token_type
s defined are bearer
or mac
. If a token type is mac
, I don't believe the HTTP API even processes this, as we only expect bearer
type tokens. It certainly wouldn't hurt to check regardless. I'll check to see what passing an ID token to the introspection endpoint does too.
Similarly, it is also good idea to reject access tokens deemed too old by checking the
iat
.
Yes, I'm not sure if this is the only place this is mentioned, but I recall seeing rejecting based on old iat
here: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
Specifically:
- The iat Claim can be used to reject tokens that were issued too far away from the current time, limiting the amount of time that nonces need to be stored to prevent attacks. The acceptable range is Client specific.
While this does refer to ID Tokens, it wouldn't be a surprise to see another RFC or document talking about applying this to access tokens.
One problem that could arise when checking time-based values in the introspection response json members, including
exp
andnbf
, is clock synchronizations. Usually it is not a bad idea to allow a clock skew of a couple of seconds.
We certainly do want to consider the option for leeway/skew for the validate_using_local_validation(...)
function, as well as the iat
based rejection.
For the introspection endpoint, based on this section here: https://datatracker.ietf.org/doc/html/rfc7662#section-4
I believe that the iat
, exp
, and nbf
claims are handled by the authorization server. Unless the leeway the endpoint has differs from the expected, it might be better to let the authorization server handle the claims.
If we can find a document talking about rejecting Access Tokens based on the iat
claim, we can certainly add it.
When validating access tokens locally as in
then the verifications steps are outlined here https://datatracker.ietf.org/doc/html/rfc9068#section-4. Most importantly, in both cases (local or remote introspection), an access token might present some scopes. These scopes will have to be somehow taken into account because this is an important feature of the concept of access tokens. I will elaborate more on this in #248.
Yes, I believe this also shows up in the security best practices draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#name-access-token-privilege-rest
Apologies for the confusion. The authorization code grant type should exchange a code for an access token. Usually both an access token and an ID token are returned, optionally a refresh token. The API docs in this project state that at the end of the code grant flow an access token will be returned and made visible in the user browser. At what stage is the ID token verified in this scenario and why if the purpose was just to get an access token? I am sorry if I am mistakenly making wrong assumptions and thanks in advance.
Apologies for the confusion. ... I am sorry if I am mistakenly making wrong assumptions and thanks in advance.
No problem at all! All questions are very much welcome.
The authorization code grant type should exchange a code for an access token. Usually both an access token and an ID token are returned, optionally a refresh token. The API docs in this project state that at the end of the code grant flow an access token will be returned and made visible in the user browser.
Yes, this is all correct, though the API documentation should have the phrasing changed, since it's misleading. I'll make an issue for that shortly. (See #374)
While we do return a bearer token, what we make visible in the browser is not an ID Token or Access Token. We give back a token generated by the HTTP API, similar to what is used when you perform basic authentication using your iRODS username and password for the HTTP API.
At what stage is the ID token verified in this scenario and why if the purpose was just to get an access token?
The ID Token is verified before performing the mapping of the OpenID User to an iRODS user. We use the ID Token for the mapping of the user in client mode of the HTTP API, as it should contain more information to map against.
Once the OpenID user is mapped to an iRODS user, we check that the iRODS user exists, and then give back the HTTP API token. The OpenID/OAuth Access Token is not used in client mode.
No further OpenID commutations are made in client mode after the HTTP API token is generated and returned.
Hopes this answers your question on how and why we use ID Tokens in client mode, as well as your questions on the use of access tokens.
If there's any more questions, feel free to ask.
Got it. Indeed the docs were misleading.
Let's suppose the IAM server is external and managed separately from the iRODS and the HTTP API servers. What would happen if a user authenticated on the IAM server with username rods? Would this be assigned admin privileges to the underlying iRODS system by the HTTP API server just because the username claim in the ID token happened to match the local iRODS admin username?
Is the ID token then essentially (and mistakenly) performing authorization?
Hence my interest in how the HTTP API server utilizes ID and access tokens and the introduction of scopes in the authorization workflow.
No - we would actively map information from the IAM to an iRODS username. We’ll get the multiple scenarios laid out better in the documentation.
Until then - this 2x2 is the best we have so far…
https://slides.com/irods/sc24-irods-http-api-and-openid-connect#/9
ID Token validation reference: https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
Should we reject tokens with a distant
iat
?If we add a
nonce
value, consider the above?If
acr
is used, consider this.If
auth_time
is requested.