Subject: [OAUTH-WG] Benjamin Kaduk's Discuss on draft-ietf-oauth-jwt-introspection-response-10: (with DISCUSS and COMMENT)

From: Benjamin Kaduk via Datatracker <[email-masked]>
Date: Tue, 26 Jan 2021 20:32:18 -0800

Benjamin Kaduk has entered the following ballot position for
draft-ietf-oauth-jwt-introspection-response-10: Discuss

When responding, please keep the subject line intact and reply to all
email addresses included in the To and CC lines. (Feel free to cut this
introductory paragraph, however.)

Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
for more information about IESG DISCUSS and COMMENT positions.

The document, along with other ballot positions, can be found here:
https://datatracker.ietf.org/doc/draft-ietf-oauth-jwt-introspection-response/

----------------------------------------------------------------------
DISCUSS:
----------------------------------------------------------------------

We've made a lot of progress at unravelling the gnarly issues relating
to merging the introspection response and JWT claims namespaces, which
is good.  That said, I'd still like to discuss a little bit more the
behavior described in Section 5, where the "token_introspection" claim
in the response can also contain JWT claims (''' In addition, claims
from the JSON Web Token Claims registry [IANA.JWT] established by
[RFC7519] MAY be included as members in the "token_introspection"
claim.''')  That seems to be granting carte blanche to do the thing that
was deemed problematic, i.e., mix the namespaces.  As such, the current
formulation in the document, in the general case of independent
uncoordinated implementations, seems to admit the prospect of an AS
adding something to an introspection response under the guise of the JWT
claim exception that is interpreted by the recipient RS as a new
introspection response parameter (or, I think, vice versa).  Yes, this
would require conflicting registrations to occur, but we still don't
have a procedure in place that would prevent such conflicting
registrations from occurring in the future.  How can we add some
low-cost safety controls that mitigate the risk while still enabling the
desired functionality?

I have a couple thoughts on this: there is already an exception for
implementation/service-specific (unregistered) claims in the
introspection response, which could apply to JWT claims under the same
requisite conditions of administrative control, if that's going to cover
the scenarios in question.  One could also imagine a new registration
procedure for introspection response parameters whereby (for example)
any non-conflicting value already registered as a JWT claim can be
mechanically propagated into the introspection response registry
potentially just by IANA without even expert review.  Then we would just
require the contents to be registered introspection response parameters,
and someone who wants to use JWT claims can trivially get them
registered before using them.

----------------------------------------------------------------------
COMMENT:
----------------------------------------------------------------------

I'm not balloting this at a DISCUSS-level, because it may just be me
failing to understand the intended meaning (or being forgetful), but I'm having a hard time
seeing how we're self-consistent about the requirement for an RS to
authenticate and authorize a given RS for a given introspection
transaction.  In particular, in Section 3 we see that "the authorization
server MUST be able to identify, authenticate and authorize resource
servers" and that "[t]he authorization server MUST be able to determine
whether an RS is the audience for a particular access token and what
data it is entitled to receive, otherwise the RS is not authorized to
obtain data for the access token".  While I see that there is also some
discussion about using the "scope" parameter of the token being
introspected as an indicator of the RS it is to be used for (and thus
the identity of the RS that would legitimately be making an
introspection request), and I also see discussion of using an encrypted
introspection response as a way to ensure that the contents are only
viewable by the intended RS, I'm not sure how clearly either (or both)
mechanisms constitute "authentication" of the introspection request.
Since we already require a "strong two-way trust relationship", it's not
clear to me that it would be difficult to strongly authenticate the
actual introspection request itself or that there is much gained by
skipping such a check in favor of other mechanisms.  Several of my
inline comments touch on this topic (on the assumption that there is a
strong MUST for strong authentication); I left them in place to benefit
from the context of where they appear, rather than constructing a
laundry list of all of them.  That said, it will suffice to explain how
I'm wrong/confused just once; there's no need to repeat it at each place
I bring up the topic.

Section 3

   To support encrypted token introspection response JWTs, the
   authorization server MUST also be provided with the respective
   resource server encryption keys and algorithms.

That seems more of a descriptive than a normative "must", to me.

Section 4

   A resource server requests a JWT introspection response by including
   an "Accept" HTTP header "application/token-introspection+jwt" in the
   introspection request.

nit: "header field". and probably also something about "containing" or
"with body".

   The AS SHOULD authenticate the caller at the token introspection
   endpoint.  Authentication can utilize client authentication methods
   or a separate access token issued to the resource server.  Whether a
   resource server is required to authenticate is determined by the
   respective RS-specific policy at the AS.

I don't think this can be only a SHOULD-level requirement and be
consistent with the MUST-level requirements in the previous section
(most notably, "[AS] MUST be able to determine whether an RS is the
audience for a particular access token".  It is hard to believe that an
unauthenticated RS could have such authorization.

   The following is a non-normative example request with client
   authentication:

   POST /introspect HTTP/1.1
   Host: as.example.com
   Accept: application/token-introspection+jwt
   Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

(side note: "Authorization: Basic" makes me sad.)

Section 5

   The introspection endpoint responds with a JWT, setting the "Content-
   Type" HTTP header to "application/token-introspection+jwt" and the

nit: "header field" again.

           If possible, the AS MUST narrow down the "scope" value to the
           scopes relevant to the particular RS.

What's the difference between "if possible, <X> MUST" and "<X> SHOULD"?

   The JWT MAY include other claims, including those from the "JSON Web
   Token Claims" registry established by [RFC7519].  The JWT SHOULD NOT
   include the "sub" and "exp" claims as an additional prevention
   against misuse of the JWT as an access token (see Section 8.1).

nit: I think a comma after "'exp' claims" would increase clarity.

   The JWT is cryptographically secured as specified in [RFC7662].

I think that this was intended to refer to 7519 (JWT), not 7662
(introspection)?

   Depending on the specific resource server policy the JWT is either
   signed, or signed and encrypted.  If the JWT is signed and encrypted
   it MUST be a Nested JWT, as defined in JWT [RFC7519].

   Note: If the resource server policy requires a signed and encrypted

(nit?) Just to confirm: the "resource server policy" here is a policy
that's applied at the AS on a per-resource-server basis?  If so, perhaps
writing it "resource-server-specific policy" would clarify.

   response and the authorization server receives an unauthenticated
   request containing an "Accept" header with content type other than
   "application/token-introspection+jwt", it MUST refuse to serve the
   request and return an HTTP status code 400.  This is done to prevent
   downgrading attacks to obtain token data intended for release to
   legitimate recipients only (see Section 8.2).

An unauthenticated request should be denied unconditionally, right?
Should this MUST apply to just requests containing the "Accept" header
(field) with other content-types?

   The example response JWT payload contains the following JSON
   document:
   [...]
     "token_introspection":
        {
           [...]
           "scope":"read write dolphin",

Is there any chance the minimizer that was run on this payload as input
to JWT generation also removed the spaces in the scope string?  I seem
to be having some unexpected behavior from my local tooling, but it is
looking like the claims set from the example HTTP payload lists
"scope":"readwritedolphin".

Section 8.2

   To prevent introspection of leaked tokens and to present an
   additional security layer against token guessing attacks the
   authorization server MAY require all requests to the token
   introspection endpoint to be authenticated.  As an alternative or as
   an addition to the authentication, the intended recipients MAY be set
   up for encrypted responses.

Isn't this ("require all requests to be authenticated") also a MUST now?