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

Benjamin Kaduk <kaduk@mit.edu> Wed, 03 March 2021 02:30 UTC

Return-Path: <kaduk@mit.edu>
X-Original-To: oauth@ietfa.amsl.com
Delivered-To: oauth@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 1E94C3A16DA; Tue, 2 Mar 2021 18:30:07 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.899
X-Spam-Level:
X-Spam-Status: No, score=-1.899 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id sFl6eYOjJ6t2; Tue, 2 Mar 2021 18:30:04 -0800 (PST)
Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id DB1DC3A16D8; Tue, 2 Mar 2021 18:30:03 -0800 (PST)
Received: from kduck.mit.edu ([24.16.140.251]) (authenticated bits=56) (User authenticated as kaduk@ATHENA.MIT.EDU) by outgoing.mit.edu (8.14.7/8.12.4) with ESMTP id 1232Tqjm025089 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 2 Mar 2021 21:29:57 -0500
Date: Tue, 02 Mar 2021 18:29:52 -0800
From: Benjamin Kaduk <kaduk@mit.edu>
To: Vladimir Dzhuvinov <vladimir@connect2id.com>
Cc: The IESG <iesg@ietf.org>, draft-ietf-oauth-jwt-introspection-response@ietf.org, oauth-chairs@ietf.org, oauth@ietf.org, Rifaat Shekh-Yusef <rifaat.s.ietf@gmail.com>
Message-ID: <20210303022952.GU21@kduck.mit.edu>
References: <161172193850.26768.7940243594405897258@ietfa.amsl.com> <dfeb978f-1977-af88-85c1-12b3a69e2633@connect2id.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
In-Reply-To: <dfeb978f-1977-af88-85c1-12b3a69e2633@connect2id.com>
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/VMEW2giYGExmFmocE_lGYcztqec>
Subject: Re: [OAUTH-WG] Benjamin Kaduk's Discuss on draft-ietf-oauth-jwt-introspection-response-10: (with DISCUSS and COMMENT)
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: OAUTH WG <oauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/oauth>, <mailto:oauth-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/oauth/>
List-Post: <mailto:oauth@ietf.org>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 03 Mar 2021 02:30:07 -0000

Hi Vladimir,

Thank you for the link to the proposed updates, and my apologies for having
taken so long to get back to you -- my inbox is in a bit of disarray at the
moment, and I have been (over)relying on the datatracker to tell me what I
need to be doing.

One note from the diff that struck me and I didn't have another place to
comment ont: it seems that we have changed from a "MUST" to a "SHOULD" in
"[t]he authorization server SHOULD be able to determine whether an RS is the
audience for a particular access token and what data it is entitled to
receive".  This does not inherently seem problematic to me; I just
couldn't remember what motivated the change.  So if you could jog my
memory, that would be appreciated.

Further comments inline...

On Tue, Feb 09, 2021 at 11:57:38AM +0200, Vladimir Dzhuvinov wrote:
> Hi Benjamin,
> 
> Thanks a lot for your comments.
> 
> We discussed them and applied several changes to the draft to address them.
> 
> Those changes can be previewed here:
> 
> https://github.com/oauthstuff/draft-ietf-oauth-jwt-introspection-response/compare/address-comments-benjamin-kaduk-2021-01-26
> 
> Further comments inline:
> 
> On 27/01/2021 06:32, Benjamin Kaduk via Datatracker wrote:
> > 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.
> 
> To recap, the moving of the RFC 7662 response parameters into a
> token_introspection claim was to keep the JWT-specific claims - iss,
> iat, aud (RFC 7519) and the introspection parameters nicely separated
> and thus prevent potential conflicts / confusion between them.
> 
> Speaking of the token introspection parameters, it was identified that
> certain applications need to obtain additional attributes related to the
> resource owner, besides the need to have the introspection response
> signed. For those attributes there happen to be suitable claims, such as
> email, name, etc., already registered in the JWT IANA registry, and it
> may make sense to reuse those names. Those are names from OpenID Connect
> intended to be used inside ID tokens and UserInfo JWTs.

I agree that reusing the well-established names makes a lot of sense.
What I'm stumbling over is the desire to press forward with a rather
informal means of enabling this when more robust/reliable mechanisms are
readily at hand. <more below>

> We updated the draft to state that when such claims get included, care
> must be taken.

This is much appreciated!

> > selected claims from the JSON Web Token Claims registry established by
> > RFC7519 MAY be included as members in the token_introspection claim,
> > provided their names don't collide with OAuth Token Introspection
> > Response registry claims and care is taken to prevent other potential
> > conflicts and ambiguity. 
> 
> In OpenID Connect there is a certain allowance for mixing claims from
> two "namespaces", for example in ID tokens which may include claims
> about the end-user besides those that are defined for the ID token
> itself. What helps here is having clear indication in the IANA JWT
> registry what the originating spec for a claim name is.

To be blunt, just because someone else did something doesn't mean that we
have to follow suit.  (I do recognize that a lot of recent OAuth
developments are occurring because OIDC has broken the trail for us and
made the initial innovation.)

Specifically (and in line with my comment above), it is at a technical
level quite easy to define a new introspection response parameter that's
defined to contain a JSON object of JWT claims.  It's also pretty
straightforward to register a bunch of JWT claims as introspection response
parameters that are expected to be useful, and it will continue to be
possible to make such cross-registrations in the future as new claims turn
out to be useful for introspection responses.  I don't remember seeing many
arguments raised against either of those options, so based on the data I
have available the most likely reason to go forward with intermingling JWT
claims and introspection response paramters in the "token_introspection"
claim body is something like laziness or expedience of deployment.  I am
not saying that that is what's happening, just that I don't have any data
to make some other motivation seem more likely -- more data is always
welcome!

Since the risk of comingling parameters from the different namespaces is
clearly mentioned, I am willing to change my position from Discuss to
Abstain in order to allow the draft to move forward, but I would still
encourage further improvements in this space.  Even if the proposals from
my previous paragraph prove infeasible for some reason, I think there is
still scope to adjust the phrasing of this text to make the described
behavior fit more naturally under the existing exception in Section 2.2 of
RFC 7662 that allows implementation- (or site-)specific response names in
the introspection response, by indicating that the decision to incoroprate
the JWT claims as introspection response parameters would be made at a
similar implementation- or deployment-level scope.

And to be clear, I am happy (and I assume Roman would also be happy) to
approve a manual posting of a revised draft during the submissions block,
in order to get the fixes into the datatracker and have the document
advance before the new IESG is seated.

> 
> > ----------------------------------------------------------------------
> > 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.
> 
> The draft was updated to make the MUST requirement for client
> authentication consistent.
> 
> Originally, the intent was to allow for RFC 7662 style behaviour
> alongside the JWT response style, but as you pointed out there are
> issues with that, and it was dropped entirely.

Thank you for working through the cases and making the document consistent!

> 
> >
> > 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.
> 
> The section was updated to
> 
> > The authorization server MAY additionally encrypt the token
> > introspection response JWTs. If encryption is used the authorization
> > server is provisioned with encryption keys and algorithms for the RS.
> 
> 
> >
> > 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".
> 
> Fixed.
> 
> 
> >
> >    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 draft was updated to make this consistent everywhere.
> 
> We now have:
> 
> > The AS MUST authenticate the caller at the token introspection
> > endpoint. Authentication can utilize client authentication methods or
> > a separate access token issued to the resource server and identifying
> > it as subject.
> 
> 
> 
> >
> >    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.)
> 
> Updated the example for private_key_jwt authentication.

Thank you!
This makes me very happy to see :)

> 
> >
> > 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.
> 
> Fixed.
> 
> 
> >
> >            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"?
> 
> Edited to
> 
> > The AS SHOULD narrow down the scope value to the scopes relevant to
> > the particular RS.
> 
> >
> >    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.
> 
> Thanks, fixed.
> 
> 
> >    The JWT is cryptographically secured as specified in [RFC7662].
> >
> > I think that this was intended to refer to 7519 (JWT), not 7662
> > (introspection)?
> 
> Thanks, the RFC ref was corrected.
> 
> 
> >
> >    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.
> 
> Clarified as suggested.
> 
> 
> >
> >    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 section was rewritten to
> 
> > Note: If the AS requires signed introspection responses for some or
> > all resource servers it MUST refuse to serve introspection requests
> > that don't authenticate the caller 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
> > "token_data_leakage").
> 
> This greatly simplified things and allowed the security recommendations
> section to be shortened significantly.

I think I see how the bulk of the simplifications happened here, but this
particular text still leaves me slightly confused.  Why would the AS
require signed responses for some RSes?  Isn't that like saying that the AS
requires the AS to behave in a certain way, e.g., local policy?  If the
sentence was saying that some *RS*es required signed responses, then having
the AS refuse to serve these requests seems to make sense for the stated
reason.

> 
> >
> >    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".
> 
> I'm not sure what the issue here is, but we'll keep an eye on the
> formatting of this example.

To be specific: I am most worried about the contents of the base64
payloads; it's easy to overlook those when doing the final stages of
review.

> 
> > 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?
> 
> This section was removed entirely with the requirement to have all
> requests authenticated.
> 
> The potential loophole of using a bearer access token for the
> introspection endpoint where the authorised subject is not identified
> (RFC 7662, section 2.2) is closed now.
> 
> https://tools.ietf.org/html/rfc7662#section-2.2

Thanks again,

Ben