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

Vladimir Dzhuvinov <vladimir@connect2id.com> Tue, 09 February 2021 09:57 UTC

Return-Path: <vladimir@connect2id.com>
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 33CF03A0D82 for <oauth@ietfa.amsl.com>; Tue, 9 Feb 2021 01:57:45 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.917
X-Spam-Level:
X-Spam-Status: No, score=-1.917 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, NICE_REPLY_A=-0.001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_NONE=0.001, URIBL_BLOCKED=0.001] autolearn=unavailable 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 mv7IF_vfZjzj for <oauth@ietfa.amsl.com>; Tue, 9 Feb 2021 01:57:42 -0800 (PST)
Received: from p3plsmtpa09-08.prod.phx3.secureserver.net (p3plsmtpa09-08.prod.phx3.secureserver.net [173.201.193.237]) (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 176153A0D47 for <oauth@ietf.org>; Tue, 9 Feb 2021 01:57:42 -0800 (PST)
Received: from [192.168.88.211] ([94.155.17.31]) by :SMTPAUTH: with ESMTPSA id 9Pm6lqohS06jR9Pm7lqDH3; Tue, 09 Feb 2021 02:57:40 -0700
X-CMAE-Analysis: v=2.4 cv=GueHRm5C c=1 sm=1 tr=0 ts=60225c94 a=+I3yL00+yDwT8KNLgfs+4A==:117 a=+I3yL00+yDwT8KNLgfs+4A==:17 a=q0rX5H01Qin5IyBaTmIA:9 a=r77TgQKjGQsHNAKrUKIA:9 a=Wo1p0_sIAAAA:20 a=48vgC7mUAAAA:8 a=A1X0JdhQAAAA:8 a=JR3aLk_0Lp47AqYsvSAA:9 a=IeD2jsKuOu93BWtY:21 a=Rt5cFkbOw895cxyp:21 a=QEXdDO2ut3YA:10 a=mYAOWqAtFUkA:10 a=1dbGxDndw2gA:10 a=jGqiy6jZAAAA:8 a=PMt0SfQCIEJMTvNWhfMA:9 a=Aazfm-kxexYvZmxB:21 a=JiRLk17tKzU3IRD7:21 a=Adz7Y9YshWs3vJFl:21 a=_W_S_7VecoQA:10 a=D8lnhvtxf0AONpHuB7QA:9 a=ZVk8-NSrHBgA:10 a=30ssDGKg3p0A:10 a=w1C3t2QeGrPiZgrLijVG:22 a=Df3jFdWbhGDLdZNm0fyq:22 a=jHrLhlbFqA1ZHZAWynec:22
X-SECURESERVER-ACCT: vladimir@connect2id.com
To: Benjamin Kaduk <kaduk@mit.edu>, The IESG <iesg@ietf.org>
Cc: draft-ietf-oauth-jwt-introspection-response@ietf.org, oauth-chairs@ietf.org, oauth@ietf.org, Rifaat Shekh-Yusef <rifaat.s.ietf@gmail.com>
References: <161172193850.26768.7940243594405897258@ietfa.amsl.com>
From: Vladimir Dzhuvinov <vladimir@connect2id.com>
Autocrypt: addr=vladimir@connect2id.com; prefer-encrypt=mutual; keydata= mQENBFQZaoEBCACnP2YMDex9fnf+niLglTHGKuoypUSVKPQeKDHHeFQVzhRke+HBEZBwmA9T kZ+kEhyrNqibDPkPYVPmo23tM8mbNcTVQqpmN7NwgMpqkqcAqNsIyBtt09DjWOQVm57A3K+y uXI7SdNErdt79p2xQseOhqSC9+LgWuyh+mZsl2oFD4glFFfKSCMp2jATXrAMeGzigTnW+Xe0 tRzrwFN9zqykKxhUq9oHg1cNvoDtfxgsc9ysVHbxM/PM8o9lgj3YTQwKMBcCFclTqohji7ML fQ08eQo+acKTwC1WRzeLt9PknGt3C4TmvdCl0c1BQTTTNiF96Hu4kbaiBIbsfxJOR8+VABEB AAG0LFZsYWRpbWlyIER6aHV2aW5vdiA8dmxhZGltaXJAY29ubmVjdDJpZC5jb20+iQE+BBMB AgAoBQJUGWqBAhsjBQkJZgGABgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRAZ0vUyOqri Ql62B/wOO0s2JC/QvO6w9iSsRhCOa/JZi+wO+l01V7eGCQ1cYf1W26Y7iKiUlY4/Kz+cr69D pMtkv3UpDTGejKEfspLUxz5Vo3T4oAKbTtNtVIZL/XxH3/JhJ719Jj4eLoe9/djKkGYTX2O5 bMk8TpO1DDjbIw4r9XKI9ZIk96zlKnZvrg7Ho7oOl0ZIf8AzcvdqZEUogDwyr8uwOU+jIyux mOTthepBzXCNjjBjnc8I1//9YppAIaGJ5nnXelVVD1/dyOszogervzFNANEIOvNvCd9G5u4e s7qkDKWKY7/Lj1tF+tMrDTrOh6JqUKbGNeTUB8DlPvIoNyqHUYfBELdpw1Nd
X-Enigmail-Draft-Status: N11100
Organization: Connect2id Ltd.
Message-ID: <dfeb978f-1977-af88-85c1-12b3a69e2633@connect2id.com>
Date: Tue, 09 Feb 2021 11:57:38 +0200
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0
MIME-Version: 1.0
In-Reply-To: <161172193850.26768.7940243594405897258@ietfa.amsl.com>
Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg="sha-256"; boundary="------------ms030005030707000403080401"
X-CMAE-Envelope: MS4xfN3PbmzdsW4k4DmOJKfM6sq87EXUmvvk4erRl93SaEvtRJdd9dOiSac3Ne0+QTTVn7YHA4NqKMKmhsAYJE86ci7mq6n8EMWKuAJTjh6CwgeUG1MZM5Zc 3jPvQizTiOJ5etZFUOSPSOvO6yqZo7Z8rKA+PetiiaJoIc2h871Ei0iJZtgo1I2GDjRBtiISzsI/uWskgOaQhjaUXbGL+bQd9ZOERQdQbLEw4NDWRFj4zQH9 dgfYg4q35dljASppP5Geqk8eq97OlDkFXx9t0zh9UBxkKNOdDZ82b6nvHkspIlzNNhuBLjgPlIYheRQTxlbc9XwWhZQRCieniYpMQaKHWMSQrR5kcas71ayA Jxdw8SiW4Y2eNOMu52Gdeiej3WWZlA==
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/Yonkj_UfE7OkM2qVByRlwoVJxA0>
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: Tue, 09 Feb 2021 09:57:45 -0000

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.

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

> 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.


> ----------------------------------------------------------------------
> 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.


>
> 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.


>
> 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.



>
>    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.


> 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


Vladimir

-- 
Vladimir Dzhuvinov