Re: [OAUTH-WG] Evaluation of Scope Management in Refresh Token Behavior

Judith Kahrer <judith.kahrer@curity.io> Wed, 21 February 2024 11:18 UTC

Return-Path: <judith.kahrer@curity.io>
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 DCE55C14F61E for <oauth@ietfa.amsl.com>; Wed, 21 Feb 2024 03:18:50 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.086
X-Spam-Level:
X-Spam-Status: No, score=-2.086 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, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_ZEN_BLOCKED_OPENDNS=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_KAM_HTML_FONT_INVALID=0.01, T_REMOTE_IMAGE=0.01, T_SCC_BODY_TEXT_LINE=-0.01, URIBL_DBL_BLOCKED_OPENDNS=0.001, URIBL_ZEN_BLOCKED_OPENDNS=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=curity.io
Received: from mail.ietf.org ([50.223.129.194]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 88yx5CzqORY9 for <oauth@ietfa.amsl.com>; Wed, 21 Feb 2024 03:18:46 -0800 (PST)
Received: from mail-lj1-x22c.google.com (mail-lj1-x22c.google.com [IPv6:2a00:1450:4864:20::22c]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 1468BC14F5FC for <oauth@ietf.org>; Wed, 21 Feb 2024 03:18:46 -0800 (PST)
Received: by mail-lj1-x22c.google.com with SMTP id 38308e7fff4ca-2d10ad265d5so71504471fa.0 for <oauth@ietf.org>; Wed, 21 Feb 2024 03:18:45 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=curity.io; s=google; t=1708514324; x=1709119124; darn=ietf.org; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=O5ChNug7tsXsqPBngVwH/pXWUdJEcTOyDK4T6WIHWDQ=; b=Wth/SyutY7HIozkVCPbi2UbMjK9+hPiHYzVWWOYpKSiprOkSiJc2jpjLwLHBKoqaWm nmKyi73pdiVD5Wl/j6a8EK/jybL+VTDzljEb41wDKeUpra+rWerNay7Tai+V7zxSkOgY XpdWVFyo14zefeY/TAJQEP1ZOqtRmmeiW8yvTSZVPytXbQ3IQ2tIeaIWwrNGig0MqVYh oLT55vzcesFeSp3ypx0Qe4j/E2pc+8eA8e//V+5sr60J5K7CI3kHouw6AhLKEvFpzdMw 3FeVIx8epfFFaq+BBQLnh2inP+NoCzdYteHRZXnb0psafJTy8ZadMSr4PvK9fFjL3r5Z dxvQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708514324; x=1709119124; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=O5ChNug7tsXsqPBngVwH/pXWUdJEcTOyDK4T6WIHWDQ=; b=Isg7i8dc6tD2gpMAvyhoMTLwpbsvukbepPlcVvrNN+5U6FLjadAxhEVZJIw2CDgn0o 2WvgnjMguEzo8YMHSrlTZu9I+cNDm9S/AGINSuhXNz95Z1PTdGKoXSR3xS049c5ldz/p qX7HUfyUNIeq6CRY/tr2o7hI7X1vqpUAkf3liTyFCjCz7pKj3t9xmDtUL2SJ7p4e1pU6 5WCsERViqH5NK5eeihSG557bfeBszFYaLp5GP6LW1QedbWCoFDMGq/YxuFkwQ06jE1UR fB71PTnkmrg7JWoAWDozVLZc8XeHXg+ZVXKKST+J05dBtxRk3pJZ5CkttYZq6Kv8QxUI 3gkQ==
X-Forwarded-Encrypted: i=1; AJvYcCUccWg0vBX6U51VGhCgLkookWbKhU4kNsjtmqNtSOghaz9hGMVsIN0NCV1uT2gHLOgxDOa8UTS1TbSq4A1F9g==
X-Gm-Message-State: AOJu0Yx3oBQFp9h/6fG7/32TIlR6XpVFvgTx0iOf696E3Pr9FD9w7H0U uoX8KgZR9b6D2ku/6x/B38/tuDKwZ2FjrCzvnuQF23yf/1qXyGBz6SF8v4y5a1c=
X-Google-Smtp-Source: AGHT+IGCVtQfuLNtl07MyuskeenLEneZvv4w5Yz9iqlz1TkITGWN5pJugmyef3yqUjDO5Na6ZvZRzw==
X-Received: by 2002:a05:6512:358b:b0:512:ab03:1b with SMTP id m11-20020a056512358b00b00512ab03001bmr5994632lfr.53.1708514323560; Wed, 21 Feb 2024 03:18:43 -0800 (PST)
Received: from smtpclient.apple ([185.209.196.243]) by smtp.gmail.com with ESMTPSA id 17-20020a05600c029100b0041270be311bsm2208771wmk.0.2024.02.21.03.18.42 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Feb 2024 03:18:43 -0800 (PST)
From: Judith Kahrer <judith.kahrer@curity.io>
Message-Id: <375958FB-0DF0-4B00-BEAC-79783A0F5272@curity.io>
Content-Type: multipart/alternative; boundary="Apple-Mail=_362C2137-F3B3-4310-9136-EC3D03AD79D1"
Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3774.200.91.1.1\))
Date: Wed, 21 Feb 2024 12:18:32 +0100
In-Reply-To: <CAD=XBCrkFr3L2AyXtKRPSAmHg9khQctENZ-2+oR1af7JBbcJ-g@mail.gmail.com>
Cc: Neil Madden <neil.e.madden@gmail.com>, wparad@rhosys.ch, oauth <oauth@ietf.org>, janak@wso2.com, thilinasenarath97@gmail.com, "piraveena@wso2.com" <piraveena@wso2.com>
To: Sachin Mamoru <sachinmamoru@gmail.com>
References: <CAD=XBCog_o8GzpDMTYKvvi=2mneM0nW0vfCc=FubtOFNF5WM=A@mail.gmail.com> <374ADB2C-2F74-4B95-8CDA-3266089CD00C@gmail.com> <CAD=XBCqs-Qf7P--KvqQcJq37Agh3gn-bfwfj7tZvwdngx+4k+A@mail.gmail.com> <13C59DD4-94E0-47AC-9A7E-D7B463BD1552@gmail.com> <CAD=XBCpgLZObed8Kj2ST6engpFR47psFrrbNKw5rwaN=_E25qA@mail.gmail.com> <CAD=XBCrkFr3L2AyXtKRPSAmHg9khQctENZ-2+oR1af7JBbcJ-g@mail.gmail.com>
X-Mailer: Apple Mail (2.3774.200.91.1.1)
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/D6iiWhMD_yOZm2fj1yIjzA9lJ4I>
Subject: Re: [OAUTH-WG] Evaluation of Scope Management in Refresh Token Behavior
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.39
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, 21 Feb 2024 11:18:51 -0000

Hi Sachin,

You’re right, the scope of the refresh token MUST remain the same. That means a refresh token should enable a client to request a new access token with the “scope originally granted by the resource owner”. Even if a refresh token entitles a client to request certain scopes (identical to what the resource owner authorized), a new access token may always have a narrow scope nevertheless. 

According to section 3.3, it is at the discretion of the authorization server to decide which scope it issues (i.e. provide “narrower scope” than authorized by the resource owner) for access tokens. I cite the relevant part for reference:

> The authorization server MAY fully or partially ignore the scope requested by the client, based on the authorization server policy or the resource owners instructions.

Section 6 in RFC 6749 says the following with regard to requesting scopes when refreshing an access token:

> [..] if omitted [the requested scope] is treated as equal to the scope originally granted by the resource owner. 

The emphasis is on “requested scope”. While you may expect the client to get whatever it requests, "the authorization server MAY fully or partially ignore the requested scope". That is, even in the refresh flow, the authorization server can return access tokens with different scopes than requested (provided they do not imply a privilege escalation). However, the authorization server must inform the client about any differences between requested and granted scopes, i.e. it must include the scope parameter in the response. That is, when narrowing the scope as part of a token refresh, the authorization server must return the scope parameter with the narrow scope values together with the new access token. What may seem to violate the spec at first sight, is indeed fully compliant. The client can explicitly request the “scope originally granted by the resource owner” or omit the scope parameter but that does not mean that the authorization server respects that request and issues an access token with the “full scope". The authorization server, like the Curity Identity Server, can apply different policies depending on, e.g., whether the client requests scopes explicitly or not, and narrow the scope. Maybe we should make that clearer in our docs. Anyways, I hope my answer helps you to better understand scope management. This mailing list is not an appropriate place to discuss vendor specifics, so if you want to provide feedback regarding our docs or product, feel free to reach out. I will be happy to answer or forward your questions. 


Judith Kahrer
Product Marketing Engineer
Curity AB

E: judith.kahrer@curity.io
W: curity.io



> On 21 Feb 2024, at 09:24, Sachin Mamoru <sachinmamoru@gmail.com> wrote:
> 
> Hi Warren and Neil,
> 
> My basis for asking this is due to the following definition [1],
> 
> Refresh tokens are credentials used to obtain access tokens.  Refresh
>    tokens are issued to the client by the authorization server and are
>    used to obtain a new access token when the current access token
>    becomes invalid or expires, or to obtain additional access tokens
>    with identical or narrower scope (access tokens may have a shorter
>    lifetime and fewer permissions than authorized by the resource
>    owner).  Issuing a refresh token is optional at the discretion of the
>    authorization server.  If the authorization server issues a refresh
>    token, it is included when issuing an access token (i.e., step (D) in
>    Figure 1).
> 
> [1] https://datatracker.ietf.org/doc/html/rfc6749#section-1.5
> 
> Thanks & Regards,
> Sachin
> 
> On Wed, 21 Feb 2024 at 13:36, Sachin Mamoru <sachinmamoru@gmail.com <mailto:sachinmamoru@gmail.com>> wrote:
>> Hi Warren and Neil,
>> 
>> Thanks for the valuable input and sorry for mentioning other products, I just wanted to provide an example. 
>> So Warren according to you following is the behaviour that spec suggested.
>> 
>> When we request an access token using 3 scopes (scope1, scope2, scope3).
>> 
>> Then will receive a refresh token (refresh_token1) with the access token.
>> 
>> After that will request another access token with refresh_token1 and provide the scope list as scope1 and scope2 (Narrow down scopes).
>> 
>> Similarly, get another refresh token (refresh_token2) with the access token.
>> 
>> Now if we request another access token with refresh_token2, we should be able to request scope3 also.
>> That means the refresh token will not be narrowed down instead only the access token will get narrowed down.
>> 
>> So Warren and Neil, if possible can you pinpoint to me the exact place in the spec where it does explicitly say that the refresh token should not be narrowed down based on the given scopes?
>> 
>> Thanks & Regards,
>> Sachin
>> 
>> On Wed, 21 Feb 2024 at 01:12, Neil Madden <neil.e.madden@gmail.com <mailto:neil.e.madden@gmail.com>> wrote:
>>> It sounds like they are violating the spec then. On the other hand, the fact that the scope can be "increased back to the original scope" maybe suggests the effective scope of the refresh token is still the same? Either way, the spec is pretty clear, regardless of what some vendor does.
>>> 
>>> -- Neil
>>> 
>>>> On 20 Feb 2024, at 19:26, Sachin Mamoru <sachinmamoru@gmail.com <mailto:sachinmamoru@gmail.com>> wrote:
>>>> 
>>>> Hi Neil,
>>>> 
>>>> Thanks for the clarification.
>>>> But Curity has a different approach and they implemented it according to the concept of narrowing down the refresh token scopes.
>>>> 
>>>> "The scope was originally read openid profile and after refresh the access was reduced to read profile (i.e., the access_token now only has read profile scope and any new tokens obtained using the refresh token daa38700-ba96-4ef1-8b30-5cb3527aae19 will have the same, reduced scope). Note that increasing the scope of access cannot be done in this way unless first reduced and increased back to the original scope."
>>>> 
>>>> [1] https://curity.io/resources/learn/refresh-tokens/#changing-scope-of-access-token-on-refresh
>>>> 
>>>> Thanks & Regards,
>>>> Sachin
>>>> 
>>>> On Tue, 20 Feb 2024 at 21:59, Neil Madden <neil.e.madden@gmail.com <mailto:neil.e.madden@gmail.com>> wrote:
>>>>> 
>>>>> 
>>>>>> On 20 Feb 2024, at 11:02, Sachin Mamoru <sachinmamoru@gmail.com <mailto:sachinmamoru@gmail.com>> wrote:
>>>>>> 
>>>>>> 
>>>>>> Hi Neil,
>>>>>> 
>>>>>> Does that mean it should be identical to the narrowed scope request or the original request scope?
>>>>> 
>>>>> It says it has to be identical to the scope of the existing refresh token in the request, not the scope specified in the request. So effectively you can never downscope a refresh token in this way. Whatever scope you specify, any RT returned must always retain the original scope. 
>>>>> 
>>>>> (There are other ways to downscope a RT, eg ForgeRock’s macaroons allow you to attenuate the scope if you wish). 
>>>>> 
>>>>> — Neil
>>>>> 
>>>>>> 
>>>>>> On Tue, 20 Feb 2024 at 16:31, Sachin Mamoru <sachinmamoru@gmail.com <mailto:sachinmamoru@gmail.com>> wrote:
>>>>>>> 
>>>>>>> 
>>>>>>> On Tue, 20 Feb 2024 at 12:23, Neil Madden <neil.e.madden@gmail.com <mailto:neil.e.madden@gmail.com>> wrote:
>>>>>>>> 
>>>>>>>>> On 20 Feb 2024, at 06:44, Sachin Mamoru <sachinmamoru@gmail.com <mailto:sachinmamoru@gmail.com>> wrote:
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Hi All,
>>>>>>>>> 
>>>>>>>>> When we request an access token using 3 scopes (scope1, scope2, scope3).
>>>>>>>>> Then will receive a refresh token (refresh_token1) with the access token.
>>>>>>>>> 
>>>>>>>>> After that will request another access token with refresh_token1 and provide the scope list as scope1 and scope2 (Narrow down scopes).
>>>>>>>>> Similarly, get another refresh token (refresh_token2) with the access token.
>>>>>>>>> 
>>>>>>>>> Now if we request another access token with refresh_token2, we cannot request scope3, instead, we can either request both scope1 and scope2 or one of them.
>>>>>>>>> 
>>>>>>>>> But in the specification, didn't able to find anything related to narrow-down scopes with refresh token.
>>>>>>>>> 
>>>>>>>>> From Spec
>>>>>>>>> 
>>>>>>>>> 1.5.  Refresh Token - Refresh tokens are issued to the client by the authorization server and are used to obtain a new access token when the current access token becomes invalid or expires or to obtain additional access tokens with identical or narrower scope (access tokens may have a shorter lifetime and fewer permissions than authorized by the resource owner).
>>>>>>>>> 
>>>>>>>>> 6.  Refreshing an Access Token
>>>>>>>>> The scope of the access request as described by Section 3.3.  The requested scope MUST NOT include any scope not originally granted by the resource owner, and if omitted is treated as equal to the scope originally granted by the resource owner.
>>>>>>>>> 
>>>>>>>>> https://datatracker.ietf.org/doc/html/rfc6749
>>>>>>>>> 
>>>>>>>>> IMO, from a security aspect, the current behaviour is much more secure because it is designed to maintain the principle of least privilege, where it updates the refresh token authorised scopes based on the requested ones.
>>>>>>>>> 
>>>>>>>>> What should be the correct behaviour?
>>>>>>>>> narrow-down scope refresh token should also be able to request access token with original scope list?
>>>>>>>> 
>>>>>>>> Also from section 6:
>>>>>>>> 
>>>>>>>> If a
>>>>>>>>    new refresh token is issued, the refresh token scope MUST be
>>>>>>>>    identical to that of the refresh token included by the client in the
>>>>>>>>    request.
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> — Neil
>>>>>>> 
>>>>>>> 
>>>>>>> -- 
>>>>>>> 
>>>>>>>  	
>>>>>>> Sachin Mamoru 
>>>>>>> Software Engineer, WSO2
>>>>>>> +94771292681 <tel:+94771292681>	
>>>>>>> | 	sachinmamoru.me  <https://sachinmamoru.me/>
>>>>>>> sachinmamoru@gmail.com  <mailto:sachinmamoru@gmail.com>
>>>>>>>  <https://www.linkedin.com/in/sachin-mamoru/>	 <https://twitter.com/MamoruSachin>
>>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> -- 
>>>>>> 
>>>>>>  	
>>>>>> Sachin Mamoru 
>>>>>> Software Engineer, WSO2
>>>>>> +94771292681 <tel:+94771292681>	
>>>>>> | 	sachinmamoru.me  <https://sachinmamoru.me/>
>>>>>> sachinmamoru@gmail.com  <mailto:sachinmamoru@gmail.com>
>>>>>>  <https://www.linkedin.com/in/sachin-mamoru/>	 <https://twitter.com/MamoruSachin>
>>>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> 
>>>>  	
>>>> Sachin Mamoru 
>>>> Software Engineer, WSO2
>>>> +94771292681 <tel:+94771292681>	
>>>> | 	sachinmamoru.me  <https://sachinmamoru.me/>
>>>> sachinmamoru@gmail.com  <mailto:sachinmamoru@gmail.com>
>>>>  <https://www.linkedin.com/in/sachin-mamoru/>	 <https://twitter.com/MamoruSachin>
>>>> 
>>> 
>> 
>> 
>> -- 
>> 
>>  	
>> Sachin Mamoru 
>> Software Engineer, WSO2
>> +94771292681 <tel:+94771292681>	
>> | 	sachinmamoru.me  <https://sachinmamoru.me/>
>> sachinmamoru@gmail.com  <mailto:sachinmamoru@gmail.com>
>>  <https://www.linkedin.com/in/sachin-mamoru/>	 <https://twitter.com/MamoruSachin>
>> 
> 
> 
> -- 
> 
>  	
> Sachin Mamoru 
> Software Engineer, WSO2
> +94771292681 <tel:+94771292681>	
> | 	sachinmamoru.me  <https://sachinmamoru.me/>
> sachinmamoru@gmail.com  <mailto:sachinmamoru@gmail.com>
>  <https://www.linkedin.com/in/sachin-mamoru/>	 <https://twitter.com/MamoruSachin>
> 
> _______________________________________________
> OAuth mailing list
> OAuth@ietf.org <mailto:OAuth@ietf.org>
> https://www.ietf.org/mailman/listinfo/oauth