[OAUTH-WG] Benjamin Kaduk's Discuss on draft-ietf-oauth-jwsreq-19: (with DISCUSS and COMMENT)

Benjamin Kaduk via Datatracker <noreply@ietf.org> Wed, 03 July 2019 18:59 UTC

Return-Path: <noreply@ietf.org>
X-Original-To: oauth@ietf.org
Delivered-To: oauth@ietfa.amsl.com
Received: from ietfa.amsl.com (localhost [IPv6:::1]) by ietfa.amsl.com (Postfix) with ESMTP id 0ED1D1200D7; Wed, 3 Jul 2019 11:59:06 -0700 (PDT)
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
From: Benjamin Kaduk via Datatracker <noreply@ietf.org>
To: The IESG <iesg@ietf.org>
Cc: draft-ietf-oauth-jwsreq@ietf.org, oauth-chairs@ietf.org, Hannes.Tschofenig@gmx.net, oauth@ietf.org
X-Test-IDTracker: no
X-IETF-IDTracker: 6.98.1
Auto-Submitted: auto-generated
Precedence: bulk
Reply-To: Benjamin Kaduk <kaduk@mit.edu>
Message-ID: <156218034597.14836.482712385966674562.idtracker@ietfa.amsl.com>
Date: Wed, 03 Jul 2019 11:59:05 -0700
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/72dm4AroWjNaAwcCC8hq5H7CRr8>
Subject: [OAUTH-WG] Benjamin Kaduk's Discuss on draft-ietf-oauth-jwsreq-19: (with DISCUSS and COMMENT)
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.29
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 Jul 2019 18:59:06 -0000

Benjamin Kaduk has entered the following ballot position for
draft-ietf-oauth-jwsreq-19: 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-jwsreq/



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

My apologies; my previous position was incomplete.  Updated to note
namespacing issues, and one minor terminology nit about "DNS-ID".

There seem to be some pretty serious namespacing issues that are not
discussed at all in this document.  Specifically, using JWT as a
container for OAuth 2.0 authorization request parameters (including
extension parameters) introduces the usage of many new names (of JSON
name/value pairs) into the JWT claims namespace.  Furthermore, the
addition is not bounded, as any new OAuth extension parameters are
implicitly permitted to be used as well!  The IANA Considerations make
no mention of the collapsed namespace for JWT claims and OAuth 2.0
(authorization request) parameters, leaving substantial potential for
collisions in the future.
Relatedly, using "application/jwt" as the Content-type of the
HTTP response from dereferencing the request_uri with no explicit
indication of the type/profile of JWT used (whether in the content type
or in the JWT claims themselves) gives some risk of misinterpretation of
the content.  Consider, for example, when that request_uri is
dereferenced not by the authorization server in the process of
fulfilling an authorization request, but instead by some other service
that expects a different type of JWT.


This second point is a "discuss discuss" -- it's an important question
and I'd like to talk about it, but it's not clear that any change to the
document will be needed.

The introduction notes as an advantage of JWT that:

   (d)  (collection minimization) The request can be signed by a third
        party attesting that the authorization request is compliant with
        a certain policy.  For example, a request can be pre-examined by
        a third party that all the personal data requested is strictly
        necessary to perform the process that the end-user asked for,
        and statically signed by that third party.  The authorization
        server then examines the signature and shows the conformance
        status to the end-user, who would have some assurance as to the
        legitimacy of the request when authorizing it.  In some cases,
        it may even be desirable to skip the authorization dialogue
        under such circumstances.

I'm pretty uncomfortable about suggesting that the authorization
dialogue can/should be skipped; do we need to keep this example?


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

Section 1

   While it is easy to implement, the encoding in the URI does not allow
   application layer security with confidentiality and integrity
   protection to be used.  While TLS is used to offer communication

nit: this wording is a little hard to read; it might be easier to
reorder to "does not allow application layer security to be used to
provide confidentiality and integrity protection".

   The use of application layer security allows requests to be prepared
   by a third party so that a client application cannot request more
   permissions than previously agreed.  This offers an additional degree
   of privacy protection.

(side note) what would an example of such a third party be.  (We already
have the resource owner, the client, and the authorization server ...
maybe it's a fourth party?)

   Furthermore, the request by reference allows the reduction of over-
   the-wire overhead.

We only barely mentioned by-reference at this point (one line in the
Abstract), so I'd suggest "passing the request by reference".

   (4)  its development status that it is an RFC and so is its
        associated signing and encryption methods as [RFC7515] and
        [RFC7516]

nit: I'd suggest "its development status as a Proposed Standard, along
with the associated signing and encryption methods [RFC7515] [RFC7516]."

   (c)  (confidentiality protection) The request can be encrypted so
        that end-to-end confidentiality can be provided even if the TLS
        connection is terminated at one point or another.

nit: TLS is always terminated at or before the user-agent, though.  So
maybe the user agent needs to get called out here as well (there could
of course be TLS termination earlier than the user-agent in some cases,
too).

   2.  When the client does not want to do the crypto.  The
       Authorization Server may provide an endpoint to accept the
       Authorization Request through direct communication with the
       Client so that the Client is authenticated and the channel is TLS
       protected.

How can you "not want to do [the] crypto" but still be doing TLS (with
crypto)?  Perhaps we're looking for "not want to pay the additional
overhead of JWS/JWE cryptography on top of TLS"?

Section 1.1

RFC 8174 has updated BCP 14 boilerplate text to use.

Section 3

nit: should this section be 2.3 to get wrapped into "terminology"?

It might also be worth putting references in for the terms, though they
are largely common knowledge at this point.

Section 4

   A Request Object (Section 2.1) is used to provide authorization
   request parameters for an OAuth 2.0 authorization request.  It MUST
   contains all the OAuth 2.0 [RFC6749] authorization request parameters
   including extension parameters.  The parameters are represented as

nit: "all the parameters" kind of sounds like "all that are defined".
But I think the intent here is "any parameter used to process the
request must come from the request object and URL query parameters are
ignored", so maybe "MUST contain all the parameters (including extension
parameters) used to process the OAuth 2.0 [RFC6749] authorization
request; parameters from other sources MUST NOT be used", akin to what
we say down in Sections 5 and 6.3.
But we need to be careful about the wording to not exclude the usage of
the "request" and "request_uri" query parameters to  find the Request
Object!

   the JWT claims.  Parameter names and string values MUST be included

nit: maybe "the JWT claims of the object"?

   any extension parameters.  This JSON [RFC7159] constitutes the JWT
   Claims Set defined in JWT [RFC7519].  The JWT Claims Set is then
   signed or signed and encrypted.

nit: I  think we want "This JSON [RFC7159] object".

(Long quote incoming)

   The following is an example of the Claims in a Request Object before
   base64url encoding and signing.  Note that it includes extension
   variables such as "nonce" and "max_age".

     {
      "iss": "s6BhdRkqt3",
      "aud": "https://server.example.com",
      "response_type": "code id_token",
      "client_id": "s6BhdRkqt3",
      "redirect_uri": "https://client.example.org/cb",
      "scope": "openid",
      "state": "af0ifjsldkj",
      "nonce": "n-0S6_WzA2Mj",
      "max_age": 86400
     }

   Signing it with the "RS256" algorithm results in this Request Object
   value (with line wraps within values for display purposes only):

     eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ew0KICJpc3MiOiAiczZCaGRSa3
     F0MyIsDQogImF1ZCI6ICJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsDQogInJl
     c3BvbnNlX3R5cGUiOiAiY29kZSBpZF90b2tlbiIsDQogImNsaWVudF9pZCI6ICJzNk
     JoZFJrcXQzIiwNCiAicmVkaXJlY3RfdXJpIjogImh0dHBzOi8vY2xpZW50LmV4YW1w
     bGUub3JnL2NiIiwNCiAic2NvcGUiOiAib3BlbmlkIiwNCiAic3RhdGUiOiAiYWYwaW
     Zqc2xka2oiLA0KICJub25jZSI6ICJuLTBTNl9XekEyTWoiLA0KICJtYXhfYWdlIjog
     ODY0MDAsDQogImNsYWltcyI6IA0KICB7DQogICAidXNlcmluZm8iOiANCiAgICB7DQ
     ogICAgICJnaXZlbl9uYW1lIjogeyJlc3NlbnRpYWwiOiB0cnVlfSwNCiAgICAgIm5p
     Y2tuYW1lIjogbnVsbCwNCiAgICAgImVtYWlsIjogeyJlc3NlbnRpYWwiOiB0cnVlfS
     wNCiAgICAgImVtYWlsX3ZlcmlmaWVkIjogeyJlc3NlbnRpYWwiOiB0cnVlfSwNCiAg
     ICAgInBpY3R1cmUiOiBudWxsDQogICAgfSwNCiAgICJpZF90b2tlbiI6IA0KICAgIH
     sNCiAgICAgImdlbmRlciI6IG51bGwsDQogICAgICJiaXJ0aGRhdGUiOiB7ImVzc2Vu
     dGlhbCI6IHRydWV9LA0KICAgICAiYWNyIjogeyJ2YWx1ZXMiOiBbInVybjptYWNlOm
     luY29tbW9uOmlhcDpzaWx2ZXIiXX0NCiAgICB9DQogIH0NCn0.nwwnNsk1-Zkbmnvs
     F6zTHm8CHERFMGQPhos-EJcaH4Hh-sMgk8ePrGhw_trPYs8KQxsn6R9Emo_wHwajyF
     KzuMXZFSZ3p6Mb8dkxtVyjoy2GIzvuJT_u7PkY2t8QU9hjBcHs68PkgjDVTrG1uRTx
     0GxFbuPbj96tVuj11pTnmFCUR6IEOXKYr7iGOCRB3btfJhM0_AKQUfqKnRlrRscc8K
     ol-cSLWoYE9l5QqholImzjT_cMnNIznW9E7CDyWXTsO70xnB4SkG6pXfLSjLLlxmPG
     iyon_-Te111V8uE83IlzCYIb_NMXvtTIVc1jpspnTSD7xMbpL-2QgwUsAlMGzw

Decoding the base64 of the body, we see:
{
 "iss": "s6BhdRkqt3",
 "aud": "https://server.example.com",
 "response_type": "code id_token",
 "client_id": "s6BhdRkqt3",
 "redirect_uri": "https://client.example.org/cb",
 "scope": "openid",
 "state": "af0ifjsldkj",
 "nonce": "n-0S6_WzA2Mj",
 "max_age": 86400,
 "claims":
  {
   "userinfo":
    {
     "given_name": {"essential": true},
     "nickname": null,
     "email": {"essential": true},
     "email_verified": {"essential": true},
     "picture": null
    },
   "id_token":
    {
     "gender": null,
     "birthdate": {"essential": true},
     "acr": {"values": ["urn:mace:incommon:iap:silver"]}
    }
  }
}

I'm not sure where the "claims" claim is coming from -- 6749 doesn't
seem to talk about it.  (Note that this example is used later on as
well.)

Section 5.2.1

   It is possible for the Request Object to include values that are to
   be revealed only to the Authorization Server.  As such, the
   "request_uri" MUST have appropriate entropy for its lifetime.  For
   the guidance, refer to 5.1.4.2.2 of [RFC6819].  It is RECOMMENDED
   that it be removed after a reasonable timeout unless access control
   measures are taken.

It sounds like a link to https://www.w3.org/TR/capability-urls/ might
also be useful.

Section 5.2.2

Do we want to remind the reader that the other query parameters are just
for backwards compatibility?

Section 5.2.3

   The following is an example of this fetch process:

     GET /request.jwt HTTP/1.1
     Host: tfp.example.org

It's useful to show good hygeine in examples; can we get the extra
entropy in this request that we have in the previous example(s)?

Section 6.2

   The Authorization Server MUST perform the signature validation of the
   JSON Web Signature [RFC7515] signed request object.  For this, the
   "alg" Header Parameter in its JOSE Header MUST match the value of the
   pre-registered algorithm.  The signature MUST be validated against
   the appropriate key for that "client_id" and algorithm.

Does "the pre-registered algorithm" concept exist in the specs outside
of draft-ietf-oauth-jwt-bcp?

Section 8

   HTTP clients MUST also verify the TLS server certificate, using
   subjectAltName dNSName identities as described in [RFC6125], to avoid
   man-in-the-middle attacks.  The rules and guidelines defined in

It's probably easier to just say "using DNS-ID [RFC6125], to avoid
man-in-the-middle attacks".

Section 9

The error codes we list in Section 7 are already registered, for the
OIDC usage.  Do we want to say anything about that?   (I guess it would
be disallowed by process to try to update the existing registration to
also point at this document.)

Section 10

We probably also want to reference draft-ietf-oauth-jwt-bcp.

Section 10.1

   When sending the authorization request object through "request"
   parameter, it MUST either be signed using JWS [RFC7515] or encrypted
   using JWE [RFC7516] with then considered appropriate algorithm.

Up in Section 5 we only allow (a) signed and (b) signed then encrypted;
similarly, in Section 4 we reiterate "signed then encrypted".  Why is it
okay to talk about just "signed or encrypted" here?

Section 10.2

   (b)  Verifying that the symmetric key for the JWE encryption is the
        correct one if the JWE is using symmetric encryption.

Similarly to the previous point, you also need to check the signature,
which will always be there.

   (d)  Authorization Server is providing an endpoint that provides a
        Request Object URI in exchange for a Request Object.  In this

I don't think this is a complete sentence (and it's definitely not a
parallel construction with (a)-(c)!).  I think perhaps a crisp one-line
summary of this method would be "Delegating the authorization check to a
separate "Request Object to Request Object URI" endpoint on the
Authorization Server".  (The writing in the rest of this paragraph could
also use an editing pass.)

   (e)  A third party, such as a Trust Framework Provider, provides an
        endpoint that provides a Request Object URI in exchange for a
        Request Object.  The same requirements as (b) above apply.  In
        addition, the Authorization Server MUST know out-of-band that
        the Client utilizes the Trust Framework Operator.

The Authorization Server also has to trust the third-party provider to
actually do its job and not misbehave, right?

Section 10.3

I'm not entirely sure what "[t]he endpoints ithat come into question in
this specification" is supposed to mean -- is it just "the OAuth 2.0
endpoints presently defined in Standards-Track RFCs"?

   In [RFC6749], while Redirection URI is included, others are not
   included in the Authorization Request.  As the result, the same
   applies to Authorization Request Object.

nit: included in what?

Section 10.4

It's probably also worth citing the generic URI security considerations
from RFC 3986, here.

Section 10.4.1

   "request_uri", and (d) do not perform recursive GET on the
   "request_uri".

nit: remove the "do" in order to make the construction parallel.

Section 12.1

   It is often hard for the user to find out if the personal data asked
   for is strictly necessary.  A Trust Framework Provider can help the
   user by examining the Client request and comparing to the proposed
   processing by the Client and certifying the request.  After the
   certification, the Client, when making an Authorization Request, can
   submit Authorization Request to the Trust Framework Provider to
   obtain the Request Object URI.

side note: In my head the act of certification was the act of making the
translation to a Request Object URI, so I'm kind of curious where my
vision differs from reality.

The third paragraph seems to mostly just be describing the procedure of
how this flow works, which would not necessarily be specific to the
privacy considerations section.

Section 12.2.2

   Even if the protected resource does not include a personally
   identifiable information, it is sometimes possible to identify the
   user through the Request Object URI if persistent per-user Request
   Object URI is used.  A third party may observe it through browser

nit: need an article for "persistent per-user Request Object URI" (or
make it plural, as "URIs are used").

   Therefore, per-user Request Object URI should be avoided.

nit: I think this is better as "static per-user Requeste Object URIs".

Section 13

Are there two different paragraphs for "contributions from the OAuth WG
members"?  Are they reflecting different types of contribution?