usage of id_token_hint in OIDC.Core

Issue #1395 resolved
Kristina Yasuda created an issue

I have encountered an interpretation that a language used in Section 3.1.2.1 Authentication Request of OIDC.Core “If the End-User identifier by the ID Token (in the id_token_hint) is logged in or is logged in by the request, then the AS returns a positive response“ means that ID Token in the id_token_hint can be used to log in the user.

If the part “If the End-User identifier by the ID Token is logged in“ means “If id_token_hint was used to identify user’s existing session with the AS“, as I have heard being pointed out several times, could someone please clarify what is meant by “If the End-User identifier by the ID Token is logged in by the request (without a prompt)“? Since I have also been pointed out several times that id_token_hint must not be used to log in (re-authenticate) the user.

Is there a place where best practice of id_token_hint is documented? Suggest clarification is added in the errata 2 of OIDC.Core that I think it being prepared.

Comments (25)

  1. gffletch

    I would interpret that to mean… if the id_token identifies the user who is currently logged in (first case) or identifies the user that actually logs in (second case) then return a positive response. Basically, the positive response MUST be regarding the user identified in the id_token_hint value. Any other user who is already logged in or authenticates to login MUST result in an error being returned to the relying party.

    My take anyway:)

  2. Michael Jones

    The "or is logged in by the request" language is there exactly so the OP can use the ID Token supplied in the id_token_hint to silently reauthenticate the end-user's session if it has expired. The interpretation "I have also been pointed out several times that id_token_hint must not be used to log in (re-authenticate) the user" cited in the issue above is inaccurate, as it doesn't permit the reauthentication operation that's in the specification by design.

    Indeed, reauthentication support is why id_token_hint and prompt=none are so closely tied together and why there are user_interaction_required and login_requred error codes in the first place.

    That said, it's up to the OP to do its own risk assessment to determine whether to perform reauthentication using the supplied ID Token. If it's way too old, it should probably not be honored. Or if it's not the latest ID Token issued to the RP, maybe it should not be honored. But if it's the latest one, the OP is probably on good grounds honoring it, as long as there are no negative risk signals in play for the session or account.

  3. Vittorio Bertocci

    I might be misremembering, but I recall intense discussions about the semantic of “hint” being only, well, a hint rather than a mechanism where the id_token is used as some kind of credential again. The id_token validation is tied to its initial reception by the client (nonce check, etc) and cannot be repeated if the id_token is used as a credential in subsequent transactions, as it would be the case if you would allow the presence of an id_token to revive an expired session.
    The assumption that id_token is a single use credential is also behind the lack of any sender constraint mechanism, leaving this use of id_token_hint as credential unprotected.

  4. gffletch

    From a risk perspective, I think the OP/IdP would want to ensure that the id_token being used in the hint is the exact same id_token used when establishing the expired session in that specific browser. So some sort of binding in the id_token to the browser used to authenticate the user and obtain the id_token in the first place.

    Generally I’m not in favor of using an id_token as the primary credential to renew an expired session.

  5. Michael Jones

    The id_token_hint is a hint in that it's an input to a risk calculation by the OP about whether to honor the reauthenticaiton request. It wouldn't be a hint if, when presented with the ID Token, the OP was obligated to reauthenticate the End-User. But it's a hint; performing reauthentication is not a MUST.

    The ID Token is definitely not single-use. There are two places in the Connect specs where reuse of the ID Token is specified in protocol interactions between the RP to whom it was issued and the OP that issued it: id_token_hint in https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest and id_token_hint in https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout .

    Note that my careful wording above was intentional. We only specify use of the ID Token among the two parties involved in the initial issuance of it. Nowhere do we specify use of it with third parties. I know that possibility is being discussed in some places, but that should be a separate discussion. I believe that this discussion has clarified the topic of this issue, which is the use of id_token_hint in OpenID Connect Core.

  6. Vittorio Bertocci

    It is single use as a credential. The two instances you mention do use it as a hint and not as a credential used to access something, for example in the logout case the id_tolen_hint is just a selector. If there is no corresponding session, nothing of consequence happens.

    Sent from a phone

  7. gffletch

    So as I think about this wording, I think it’s important to focus on what the OP MUST NOT do, that is return a positive response if the identity who authenticates is different from the identity specified in the id_token_hint.

    What is left out of scope of the spec is the decision on whether the OP chooses to use the id_token as “an input to a risk calculation” that allows the session to be authenticated silently or whether the OP chooses to require the user to present credentials. The decision is left up to the OP and there is no normative text that requires the OP to choose one solution over another.

    I don’t believe we should clarify that “is logged in by the request” could mean the user is authenticated without a prompt. The key point in the text is that there are two cases:

    1. The user identified by the id_token has an active session (is already logged in)
    2. The user identified by the id_token does NOT have an active session (is NOT logged in)

    The end result of the request can be either a positive response from the OP (the user identified by the id_token is logged in) or a negative response (the user identified by the id_token is NOT logged in).

    How the OP chooses to handle authentication in these cases and specifically in case 2 above (silently or via a challenge) is intentionally left out of scope of the spec. This is consistent with OIDC leaving how authentication is performed by the OP “out of scope” of the spec.

  8. Brian Campbell

    This has been debated previously and interpretations of the text and the original intent behind it vary and will continue to do so. Some clarification would probably be useful but it seems doubtful that agreement could be reached on what such a clarification would say.

    My interpretation is more inline with Vittorio and especially George’s last comment (although see Issue #968 for inconsistency around MUST NOT or SHOULD NOT and somewhat different wording about being logged in by the request). As George reminds us, how end user authentication is performed by the OP is “out of scope” of the OIDC spec. As such, an id_token_hint could be used by an OP to renew a session but the spec does not define how that works (or that it’s safe). Doing so would be outside spec and completely implementation/deployment specific and there should be no expectations of predictable interoperable behavior. And no assurances of security (basically all of the JWT validation needs to be ignored or inverted and just the act of using the id token as a hint likely increases opportunities for leakage).

    I don’t think there is anyplace that best practices around id_token_hint are documented. I don’t think there are established best practices. But, even though it can be done, I’d argue that using a id_token_hint to create a session is decidedly not a best practice.

  9. Michael Jones

    For what it’s worth, when we were designing OpenID Connect, at least one major IdP requested a mechanism that would enable no-user-interaction reauthentication of previously-logged-in users. prompt=none with id_token_hint is that mechanism. As George, Brian, and I have all pointed out, it’s entirely up to the OP whether to do so.

  10. Vittorio Bertocci

    George and Brian also pointed out that it’s not a good idea/not a best practice to use id_token_hint alone to revive a session, and I agree with that. Although OP can do whatever it wants, the id_token is an artifact generated by an OIDC transaction and as such it seems it would be responsible of us to surface those positions in guidance more discoverable than a bitbucket thread. People already abuse id_token in various other circumstances, hence leaving those consideration as exercise to the reader doesn’t seem like good stewardship to me.

    Sent from a phone

  11. Kristina Yasuda reporter

    From what I understood during the Connect call on Jan 24th. We want to add a language that clarifies that 1/if the OP can identify existing user session based on the id_token_hint, OP can log in the user with high confidence; 2/ if the OP cannot find existing session based on the id_token_hint, OP can decide to log the user in combined with some additional information.

    So something like? (suggested changes in bold)

    the AS returns a positive response, if the End-User identified by the ID Token (in the id_token_hint) is already logged in at the AS, or AS decides to log the user in based on additional evaluation such as <…> .

    @Vittorio Bertocci if you can fill in <…>, that would be wonderful

  12. Giuseppe De Marco

    I believe that within the text you can specify limits to the use of id_token_hint, on the following aspects:

    1. id_token_hint can be regarded as valid and useful, without any user interaction (prompt=none), only if the id_token used has not expired;
    2. id_token_hint can be used for an auth request at the OP that issued the id_token;
    3. id_token_hint can enable a RP to reuse an id_token, issued by an OP, for an authentication request to another OP (or a third RS) that’d different from the issuer of the id_token?

    on points 1 and 2, I believe that a clear specification can be defined and included in the text.

    Point 3, on the other hand, is much more complex and at the edge. The critical points of point 3 are the following:

    a) It is necessary to obtain proof of the user’s consent so that the id_token that concerns him can be exploited, by the RS, for different purposes with respect to which the user has given his consent to the OP that issued it.

    b) The party that receives id_token_hint must obtain evidence that this token has not been revoked. This could be covered by a token introspection request from the receiver (third OP/RS) to the OP that issued the id_token.

    The b point I believe can be covered with the use of introspection endpoint, while the a point is deficient in how the proof of the user’s consent can be created by the user, included by the RP and proven by the receiving party.

    In this case it would be necessary to specify how a proof of consent mechanism can enable a user and a RP (as its delegate) for the reuse of an id_token, to third parties, as an authentication proof or as an authentication factor.

  13. Vittorio Bertocci

    @Kristina Yasuda “such as transport based security (e.g. kerberos) or equivalent mechanisms.
    @Giuseppe De Marco I think that goes far beyond the scope of the discussion and I don't recommend we pursue that line on this thread, we can spin a new one- but for posterity landing on this thread:
    a) if the id_token is used as a selector or a signal, expiration might not matter. In practical use it’s quite likely that the id_token will be expired by the time it is used as a hint. That should be no more powerful than login_hint, apart from proving that a successful auth did occur in the past.
    b) see above for hint and validity. Also, the introspection endpoint is for access tokens, not id_tokens. Technically the client can simply request a new id_token, the issuer has a chance to reflect any revocation changes at that time.
    c) using an id_token alone with a 3rd party to issue another token seems to be an institutionalized MITM/elevation of privileges attack, as it requires disregarding essential checks from audience matching to lack of mechanisms to bind id_tokens to channels or clients past initial reception. As yesterday’s OIDC call hopefully clarified, the id_token is not meant to be used as credential outside of its first reception and definitely for recipients other than the RP.

  14. Giuseppe De Marco

    I fully agree with you, especially on points 2 and 3. I would never have said on the first point but I received it so well that I will not forget it.Talking about it yesterday was fun, developing it today, writing it and making it so clear as it is today is definitely a great thing

  15. Giuseppe De Marco

    Yet doubt as a worm devours me, and unworthy is my condition.
    I fully agree not to use id_token as an authentication factor for OP other than its Issuer but when you specify not to send it to recipients other than the RP that originally received it I wonder why rfc8693 cites it among the possible tokens subject to exchange

    https://datatracker.ietf.org/doc/html/rfc8693#section-3

  16. Brian Campbell

    For whatever it’s worth, the ID token URI was added to RFC8693 somewhat haphazardly with “since some use cases perform token exchanges for ID Tokens and no URI to indicate that a token is an ID Token had previously been defined” given as the reason. Arguably that was a mistake. There really should be more guidance/requirements about using it in a way that doesn’t invite the kinds of abuses or omissions that Vittorio warns about. That ship has sailed though. It’s mention in RFC8693 shouldn’t be considered an endorsement of skipping required claims validation or other “off-label” usage (for lack of a better term).

  17. Giuseppe De Marco

    thanks, you freed me from a burden. For whatever it’s worth I fully agree that "There really should be more guidance/requirements on use in a way that does not invite the kind of abuses or omissions that Vittorio warns" and that “it would be responsible of us to surface those positions in guidance more discoverable than a bitbucket thread

  18. Michael Jones
    • changed status to open

    We discussed this during the 23-Jan-23 working group call. It's not immediately clear what action we're being asked to take.

  19. Kristina Yasuda reporter

    I think the text needs clarification and below would be a proposed text as of now….

    the AS returns a positive response, if the End-User identified by the ID Token (in the id_token_hint) is already logged in at the AS, or AS decides to log the user in based on additional evaluation such as transport based security (e.g. kerberos) or equivalent mechanisms.

  20. Michael Jones

    On the 26-Jan-23 working group call, Kristina suggested using the text in the 24-Jan-22 comment and Vittorio’s subsequent comment.

  21. Michael Jones

    As discussed on the 31-Jul-23 call, I propose to create a PR talking about the OP being able to apply additional risk factors in the potential login decision, along the lines suggested by Kristina.

  22. Log in to comment