Re: [OAUTH-WG] WGLC on "JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens"

Vittorio Bertocci <vittorio.bertocci@auth0.com> Tue, 24 March 2020 22:30 UTC

Return-Path: <vittorio.bertocci@auth0.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 DE3BE3A0528 for <oauth@ietfa.amsl.com>; Tue, 24 Mar 2020 15:30:06 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.099
X-Spam-Level:
X-Spam-Status: No, score=-2.099 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=auth0.com
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 BvwRO2xk7e1q for <oauth@ietfa.amsl.com>; Tue, 24 Mar 2020 15:30:04 -0700 (PDT)
Received: from mail-qt1-x82c.google.com (mail-qt1-x82c.google.com [IPv6:2607:f8b0:4864:20::82c]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id CC4B93A0496 for <oauth@ietf.org>; Tue, 24 Mar 2020 15:30:03 -0700 (PDT)
Received: by mail-qt1-x82c.google.com with SMTP id d12so481742qtj.4 for <oauth@ietf.org>; Tue, 24 Mar 2020 15:30:03 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=auth0.com; s=google; h=from:to:subject:thread-topic:thread-index:date:message-id :references:in-reply-to:accept-language:content-language :content-transfer-encoding:mime-version; bh=bf6Pu8c5i3lF/ZA+0cBhOYb9dD07AwqB2p5QgsFh6eY=; b=HADuTwKm//FZO52oDms6rqOgCtnlPFOvmt5YvQbQKJEhK6aR0ZVXItFqr0gU98nGQN DpRzULv+sr5tbJZKcZT7MFJDS7g9pY+zTGZJNhgLrJ/Wxl9u449EbnYblxQR3Fy7X3XU +znlTh47iKN2gDU9SJIRqL/eCi2eL5Bf1tYT64hO/j8iZAjWkFfNUZEAWJLKS1r5fGrb qyEvPJrvxzJkKnISgozcjsrF/83x7GP1jlfsiS/nORpgWoFkoDCdQUcls6/dBwWEv039 PhQCy2IyxvAxTEy3oC0QLhEiFMfWTJ8ygqEWDXXKHrbjsPDs+CyCpsHqCUjBQUtpMAWD MR1g==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:thread-topic:thread-index:date :message-id:references:in-reply-to:accept-language:content-language :content-transfer-encoding:mime-version; bh=bf6Pu8c5i3lF/ZA+0cBhOYb9dD07AwqB2p5QgsFh6eY=; b=iO3zF4hFmq5HZfYYhfUAOwXWOb1zUHzRz5hULHffA6NrjBfSvFGIzQ++92A8v/7e2W lhFA3StmYt7w8QWcKOAEHPc924GOwgU7C5vrAeMFTARES8+7FCeLdEOo/pIAoE60pq1K 98Z2/R6VgmMw3O5hehyOcDatBPDdFq7OraNyp53tUYTyNMg9lFlWkIn9bHfgdO8h9CkV oe3eG9Cyn87n6Oe3gzaSkdWNspuFiE9ilTs8eYPkssvTeXaWJEFWOhtx9be9F8qZ257o 9OGnxoKqqSjFBAD06sFSEtagiKt0lLLGdQ3QkntAb9k8K/Nlq8BTIf7BbIl70Y2rs5Pq ilzg==
X-Gm-Message-State: ANhLgQ0TOXcN5+iA4FtPPZfvATdmHNeQvw6IdbSE01z5iun4YUV6V+Vo ccxiQpqC+ynhaaFUbRA9rpncQQ==
X-Google-Smtp-Source: ADFU+vum8iZw5CRLd66Bs6pXy8IzYoyez9ygSK50yjrHrJ9Lfto8F3zFG7Wh+5ldWrggvlPJei3ZlQ==
X-Received: by 2002:aed:39c9:: with SMTP id m67mr120666qte.107.1585089002039; Tue, 24 Mar 2020 15:30:02 -0700 (PDT)
Received: from BL0PR08MB5394.namprd08.prod.outlook.com ([2603:1036:302:851::5]) by smtp.gmail.com with ESMTPSA id r29sm14400680qkk.85.2020.03.24.15.30.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 24 Mar 2020 15:30:01 -0700 (PDT)
From: Vittorio Bertocci <vittorio.bertocci@auth0.com>
To: George Fletcher <gffletch@aol.com>, Hannes Tschofenig <Hannes.Tschofenig@arm.com>, oauth <oauth@ietf.org>, Vittorio Bertocci <Vittorio@auth0.com>
Thread-Topic: [OAUTH-WG] WGLC on "JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens"
Thread-Index: ATBEMUEzVgkZHyweZLG8Yidi1aurtmY3YmE0yEo57ds=
X-MS-Exchange-MessageSentRepresentingType: 1
Date: Tue, 24 Mar 2020 22:30:00 +0000
Message-ID: <BL0PR08MB53947083829E2DD91F608F6AAEF10@BL0PR08MB5394.namprd08.prod.outlook.com>
References: <AM0PR08MB37160B8A021052198699CD17FAF00@AM0PR08MB3716.eurprd08.prod.outlook.com> <c0343474-6470-a5a6-e1bf-3ca87b842b7f@aol.com>
In-Reply-To: <c0343474-6470-a5a6-e1bf-3ca87b842b7f@aol.com>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach:
X-MS-Exchange-Organization-SCL: -1
X-MS-TNEF-Correlator:
X-MS-Exchange-Organization-RecordReviewCfmType: 0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
MIME-Version: 1.0
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/NxciOtyysrUVAfwHbEOoT6g66Vw>
Subject: Re: [OAUTH-WG] WGLC on "JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens"
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, 24 Mar 2020 22:30:08 -0000

Thanks George for the super thorough review and feedback! 
Inline

  >  Section 1. Introduction
     ��� second line: scenario should be plural --> scenarios
     ��� second sentence: "are not ran by" --> "are not run by"
    �� cofidentiality --> confidentiality
Fixed. Thanks!

>     Section 2.2.1 Authentication Information Claims
     ��� I'm not sure that this definition of `auth_time` allows for the 
    case where a user is required to solve an additional challenge.
If the challenge entails going back to the AS, then I believe the language (in the initial paragraph of 2.2.1 and in auth_time itself)  accommodates for that and does require the auth_time to be updated. 
If you hit the AS and present an authentication factor (such as your challenge) and obtain a new token in the process, the auth_time will reflect the time of your latest authentication just like an id_token would in the same circumstances (think protected route in a web app requiring step up auth) and (likely) associated session artifacts (think RTs or cookies with sliding expiration, the challenge would count as activity and move the expiration).

>     ��� I think there is a difference between session_start_time and last 
    auth_time. This feels more like it's defining the session_start_time 
    concept.
>    �� These same issues can apply to the `acr` and `amr` values as well.
Per the above, the intent is more to express the last time the user performed any authentication action rather than the start time. The intent is to provide information as current as possible, as it might be relevant to the RS decisions whereas the history before current conditions might not be consequential.

  >   �� Even if for this secondary challenge a new refresh_token is issued, 
    it is unlikely many relying parties will want to treat that as issuing a 
    new session. The goal is to keep the user logged in to a single session.
Could you expand on the practical implications of the above? The intent isn't as much to reflect session identifying information per se, but to provide the RS with the most up to date information about the circumstances in which the current AT was obtained. The fact that a session was initially established using acr level 0 doesn’t really matter if the AT I am receiving now has been obtained after a stepup that brought acr to 1, if my RS cares auth authentication levels my authorization decision shouldn't be influenced by whether somewhere the session artifact didn’t change its sessionID after the stepup. Same for acr, auth_time

>     Section 2.2.3 Authorization Claims
     �� I find the statement "All the individual scope strings in the scope 
    claim MUST have meaning for the resource indicated in the aud claim" 
    somewhat problematic. In many deployments today for 1st party clients to 
    the authorization server and taking into account mobile applications, 
    the access token most like contains scopes for many of the 1st party 
    backend APIs. It's possible to get around this by setting the 'aud' 
    claim to something like "com.example.apis" and hence all the issued 
    scopes map to that audience claim but that is just working around the 
    MUST in the spec. Given the lack of specificity of the 'aud' claim and 
    the 'resource indicator' claim for that matter, pretty much anything can 
    be made to comply. In that context, it seems like RECOMMEND is a better 
    normative clause.
For 1st party solutions, I would argue that delegation might not be the right primitive hence I wouldn't necessarily use scopes to express permissions; but that's a rabbit hole I'll try to avoid for the time being __
For the aud, I think that what you characterized as workaround would actually be by design. The aud defines the applicability of the current token, so that in case of leakage the blast radius of the incident can be contained. If the solution designed decides that this particular token should be reusable across multiple assets, I think it makes sense for the aud to reflect that explicitly. That's the system designing volunteering a scope xpansion of the scope, and given that it has security implications I think it's good to require it to be an explicit, opt in action. At the same time, given that scopes are often used to define permissions, I believe it makes sense to find mechanisms to minimize the chance that RSes would misinterpret the applicability of a scope (see discussion with Takahiko/Nikos). Summing all the above, I'd be inclined to keep the MUST.

> Section 3. Requesting a JWT Access Token
     �� Per my comments above I suspect that requiring all JWT access tokens 
    to include an audience claim will just devolve to audience claims that 
    are somewhat pointless (in order to meet this MUST in the spec). Given 
    the mobile app environment today, it is unreasonable to ask the mobile 
    apps to downscope every access token before making an API call to the 
    backend APIs which is what the spirit of audience and resource 
    indicators seem to imply.
Partly addressed in the preceding point, but this is a great opportunity to clarify the intent further. The mobile client isn't required to downscope; rather, the fact that a token cab be applied to a broad range of API should be clearly identified and expressed by the logical audience. The system designer can even choose to have a single token that can be used to call any API, containing every scope for every API; the profile only asks for this choice to be manifest, by choosing an appropriate audience identifier and acknowledging that all the scopes in the token are applicable to the same logical resource (that is, the aggregate of all the APIs). 

     >  �� Why MUST the AS reject a request with more than one resource 
    parameter? If a request comes in with no resource parameter and multiple 
    scopes the AS is not required to reject that request. Is there much of a 
    semantic difference between the two? In the case of no resource 
    parameter and multiple scopes the AS might issue an access token with 
    multiple audience values (as is allowed by RFC 7519).
This is another consequence of making extra clear what the token refers to, and what the intended semantic of the scopes is. The idea is that the token is always restricted to ONE specific audience. The profile allows for different mechanisms for the AS to determine what value the audience should be, including via inference from scopes, but coherently with the scope confusion prevention principle, if that inference cannot lead to a single resource identifier in the audience, the request should be rejected.
The intent is really to be as simple as unambiguous as possible, and capture what most mainstream providers already do in JWT ATs. If a RS has more sophisticated requirements, they can always decide to do more and not follow the interop profile. Defining more complex rules to prevent scope/resource association confusion simply doesn’t seem to be justified by the frequency of the scenario in the wild.


>  Also, the audience 
    claim is not solely for resource indicator values but is defined to just 
    be a string. To me it feels like the text is implying that the only 
    valid audience value is also a resource indicator (which from previous 
    discussions on the list it was implied they have a slightly different 
    semantic).
Section 3 of the profile does define aud as a resource indicator, enumerating an exhaustive list of possible requests that all end in a resource indicator as aud, or an error. Did I miss some cases? I don’t recall specifics about aud values in this profile having other possible values, sorry for having missed that. Do you have a snippet referring to those discussions? Thx

    >  �� The model described here works well if myco.example really only 
    provides a single service. But if instead myco.example provides multiple 
    services each with their own endpoints (srva.myco.example, 
    srvb.myco.example) and scopes, for me this model begins to break down. 
    Either mobile apps are required to downscope all tokens to just the 
    service they are calling at that point in time (which can have latency 
    and connectivity issues), or myco.example has to create a generic 
    "audience" string that represents all of example.com which doesn't seem 
    to be the spirit of the existing specs.
I think that the granularity of the calls is fully within the control of the designer. If srva.myco.example and srvb.myco.example share analogous characteristics (same policies, lifecycle, resource ownership, etc) them it's perfectly valid to assign a logical myco.example audience encompassing them all, regardless of deployment model. If there are differences in terms of policies, auth strength requirements, lifecycle, risk and impact of a leak, or any other boundary, then the audience requirement will guarantee that those differences are reflected in tokens requested and cached, in the way in which access is partitioned, and so on and so forth. If there are security requirements such as the ones enumerated, the latency and connectivity issues aren’t a blocking factor; and if there aren't, nothing prevents you from having a logical audience value. From the expressive power point of view, the requirement of having a single audience doens't prevent you from doing any of the single token logic you are hinting at- especially if you plan to use specialized scopes anyway.

   >   �� In summary, I feel that this text is binding too tightly resource 
    indicators to the audience claim. What is described is perfectly 
    reasonable in a use case that is applying resource indicators in this 
    way but is not indicative of the widely deployed models that already exist.
We might have different experiences here. The JWT access tokens from popular products I studied in the research I presented in Stuttgart were almost all using the aud claim in this way. I am sure that there are other models, and there was at least one exception, but in interop terms this seems to be the most common way of using JWT for ATs- and it has the advantage of being very simple and unambiguous.

> Section 4. Validating JWT Access Tokens
     �� Step 4. -- Can we change the wording to not require resource 
    indicators? What about... "The resource server MUST validate that the 
    'aud' claim contains a string that represents the audience of this 
    resource server."
Could you make an example in which you'd want to use an identifier that is not a resource indicator? Given that we have the spec, and "audience of the resource server" seems to be the exact semantic of resource indicators, it seemed a slam dunk to use it here... 

   > Section 5. "cross-JWT confusion"
     �� I think there may be confusion around what is meant by "distinct 
    resources". In my example above, are srva.myco.example and 
    srvb.myco.example "distinct resources"? or is the goal here to say that 
    we want different audience values generated for cross-organization 
    resources. For example, are mail.google.com and youtube.com "distinct 
    resources"? or would an audience for google suffice in meeting the 
    meaning of this paragraph?
I think the key point here is - we don’t know. I agree the language isn't clear there. Let me expand on the intent, and perhaps we can get to a better formulation.
OAuth2 doesn’t demand that RS and AS are run by the same entity, but that's the most common scenario. FB doesn't need to specify a resource, because the resource is implicit.. it's the FB graph, you can’t get a token for anything else. The only differentiator ends up being the scopes. Same for many other providers, google, Microsoft for its own Graph, etc.
However many AS as a service don’t have the benefit of a default, implicit resource, especially in multi tenancy scenarios, given that they'll need to issue tokens for a number of different recipients. Whether resources are cross organization, or cross department, or following any other arbitrary segregation/factoring model is something we cannot infer- it's up to the developer to determine that. What I am trying to express here is that the operator of the AS as a service (or any other form of "AS for rent") should surface resources as a primitive for modeling and identifying intended recipients of ATs. Does tis help? How would you express that? 

>      � I'm having the same confusion in the next paragraph regarding the 
    phrase "different resources". Are services provided by the same company 
    "different resources" or are they all considered the same resource. Can 
    an access token be issued with scopes for both mail.google.com and 
    youtube.com? And if not, why note? Preventing this puts undue burden on 
    mobile based applications.
See preceding point. We can't enter in the merit of what constitutes a resource, as that depends on the modeling of the domain specific problem the developer is tackling. The highest order bit is that if two entities (API, etc.. intended token recipients) have different security characteristics (e.g. leaking a token for one has different consequences than if you'd leak a token for the other), they should be modeled as different resources. And if they are different resources, we should do what we can to avoid confusion in how we express access grants to them (hence the big discussion on multiresource, scope confusion, etc).


---------
On 3/24/20, 10:39, "George Fletcher" <gffletch@aol.com> wrote:

    Feedback on the spec...
    
    Section 1. Introduction
     ��� second line: scenario should be plural --> scenarios
     ��� second sentence: "are not ran by" --> "are not run by"
    
    Section 2.2.1 Authentication Information Claims
     ��� I'm not sure that this definition of `auth_time` allows for the 
    case where a user is required to solve an additional challenge. Take the 
    case of a user who is required to pass a secondary challenge before the 
    "stock purchase" action can be completed. According to the current spec 
    definition, the `auth_time` value MUST NOT be updated when this 
    secondary challenge is completed.
    
     ��� I think there is a difference between session_start_time and last 
    auth_time. This feels more like it's defining the session_start_time 
    concept.
    
     �� These same issues can apply to the `acr` and `amr` values as well.
    
     �� Even if for this secondary challenge a new refresh_token is issued, 
    it is unlikely many relying parties will want to treat that as issuing a 
    new session. The goal is to keep the user logged in to a single session.
    
    Section 2.2.3 Authorization Claims
     �� I find the statement "All the individual scope strings in the scope 
    claim MUST have meaning for the resource indicated in the aud claim" 
    somewhat problematic. In many deployments today for 1st party clients to 
    the authorization server and taking into account mobile applications, 
    the access token most like contains scopes for many of the 1st party 
    backend APIs. It's possible to get around this by setting the 'aud' 
    claim to something like "com.example.apis" and hence all the issued 
    scopes map to that audience claim but that is just working around the 
    MUST in the spec. Given the lack of specificity of the 'aud' claim and 
    the 'resource indicator' claim for that matter, pretty much anything can 
    be made to comply. In that context, it seems like RECOMMEND is a better 
    normative clause.
    
    Section 3. Requesting a JWT Access Token
     �� Per my comments above I suspect that requiring all JWT access tokens 
    to include an audience claim will just devolve to audience claims that 
    are somewhat pointless (in order to meet this MUST in the spec). Given 
    the mobile app environment today, it is unreasonable to ask the mobile 
    apps to downscope every access token before making an API call to the 
    backend APIs which is what the spirit of audience and resource 
    indicators seem to imply.
    
     �� Why MUST the AS reject a request with more than one resource 
    parameter? If a request comes in with no resource parameter and multiple 
    scopes the AS is not required to reject that request. Is there much of a 
    semantic difference between the two? In the case of no resource 
    parameter and multiple scopes the AS might issue an access token with 
    multiple audience values (as is allowed by RFC 7519). Also, the audience 
    claim is not solely for resource indicator values but is defined to just 
    be a string. To me it feels like the text is implying that the only 
    valid audience value is also a resource indicator (which from previous 
    discussions on the list it was implied they have a slightly different 
    semantic).
    
     �� The model described here works well if myco.example really only 
    provides a single service. But if instead myco.example provides multiple 
    services each with their own endpoints (srva.myco.example, 
    srvb.myco.example) and scopes, for me this model begins to break down. 
    Either mobile apps are required to downscope all tokens to just the 
    service they are calling at that point in time (which can have latency 
    and connectivity issues), or myco.example has to create a generic 
    "audience" string that represents all of example.com which doesn't seem 
    to be the spirit of the existing specs.
    
     �� In summary, I feel that this text is binding too tightly resource 
    indicators to the audience claim. What is described is perfectly 
    reasonable in a use case that is applying resource indicators in this 
    way but is not indicative of the widely deployed models that already exist.
    
    Section 4. Validating JWT Access Tokens
     �� Step 4. -- Can we change the wording to not require resource 
    indicators? What about... "The resource server MUST validate that the 
    'aud' claim contains a string that represents the audience of this 
    resource server."
    
    Section 5. "cross-JWT confusion"
     �� I think there may be confusion around what is meant by "distinct 
    resources". In my example above, are srva.myco.example and 
    srvb.myco.example "distinct resources"? or is the goal here to say that 
    we want different audience values generated for cross-organization 
    resources. For example, are mail.google.com and youtube.com "distinct 
    resources"? or would an audience for google suffice in meeting the 
    meaning of this paragraph?
    
     � I'm having the same confusion in the next paragraph regarding the 
    phrase "different resources". Are services provided by the same company 
    "different resources" or are they all considered the same resource. Can 
    an access token be issued with scopes for both mail.google.com and 
    youtube.com? And if not, why note? Preventing this puts undue burden on 
    mobile based applications.
    
    Section 6. Privacy
     �� cofidentiality --> confidentiality
    
    
    Thanks,
    George