Re: [OAUTH-WG] Token Mediating and session Information Backend For Frontend (TMI BFF)

Torsten Lodderstedt <torsten@lodderstedt.net> Mon, 15 February 2021 16:49 UTC

Return-Path: <torsten@lodderstedt.net>
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 D78DD3A0D7C for <oauth@ietfa.amsl.com>; Mon, 15 Feb 2021 08:49:02 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -0.199
X-Spam-Level:
X-Spam-Status: No, score=-0.199 tagged_above=-999 required=5 tests=[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=unavailable autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=lodderstedt.net
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 k2T7Y7DWnJPg for <oauth@ietfa.amsl.com>; Mon, 15 Feb 2021 08:49:00 -0800 (PST)
Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) (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 ECDC13A0D7A for <oauth@ietf.org>; Mon, 15 Feb 2021 08:48:59 -0800 (PST)
Received: by mail-wr1-x433.google.com with SMTP id v14so9696923wro.7 for <oauth@ietf.org>; Mon, 15 Feb 2021 08:48:59 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lodderstedt.net; s=google; h=mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=stBB5Tjm9JyDfqs42gVID2QmjZ/4oQ1vgykWwdT3yho=; b=3Cqx+fzNRjT0FqDSRlYd+Z3PMqpU1VzG1iSyKR3XaW8MV2xsN4g0iTKGvwfrF+H3/i tDssyeKIMs8GawvmmUGr+/gm9Uwp2Rtf0wKcVC88zxoa+hHHQZPf+o1pRnAckGgti15i vzmHKT96YcHwAQNPyMptkiJLu5XEN83J5FtLYiTOYcu83N7KHCs7hl4S6/ZwJ+JX1crM raeZWKSDKccQyGFPtCp0PaHOopSJSuy+a+q+9j4eg5KB7DQ146HlH5zuTrfttkLKHQMt QxwBakmsHJ32f9aY7VKGPM0LFc3fmb1lWD1ViEu7xstxa8O74OeHixZxsEy/yqA3Kpwm MT2Q==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=stBB5Tjm9JyDfqs42gVID2QmjZ/4oQ1vgykWwdT3yho=; b=mG6fyUnyulBuIjzN2YlTQ8vaOQlaMcIHKzXfQ9nZB4CzPGSGPoH3uT/i+1GZw1Em2K bFuTBRiWJuZ1zb/v4+bSwTFv9cw9i+hkzMGMlcWJjWP7y+bXt0OvYy3SgVPMH2Lgrz5g qFJCNVMyqWdx+mcxfe8OQnJZx8lBJM0A8sEnTEXlg4gzXfwvvBo+5jispv7m+zC00HnW tTdCuyaVVwvXWzE1iZB1uYJqGtMHDqXmdqpN9slmwBh6UYFNvNzle1mYlM07wJjuv7x1 Y4/iBnjd/u4ui+jQ1GGLKEpGAERgiWxMYbxLbMHj+QFXRY2HkxVwnUqvdt84npbLat6P iIlQ==
X-Gm-Message-State: AOAM531tXxiW0H+JEeRNflt8BHa0Th2QM58LnPKqpqbfVNyCbK5fwVXo aLPDZ5UP/hCtF4fdxEauJ0s2RQ==
X-Google-Smtp-Source: ABdhPJyAcZeserSqUz/WhdmpOVfX0NRGuFBTPoouB5/v82DufJkmecB7ve3PZuT01Ae4eaZCiy5WKw==
X-Received: by 2002:a05:6000:81:: with SMTP id m1mr19934919wrx.97.1613407738154; Mon, 15 Feb 2021 08:48:58 -0800 (PST)
Received: from p200300eb8f0611668d558860be74ade1.dip0.t-ipconnect.de (p200300eb8f0611668d558860be74ade1.dip0.t-ipconnect.de. [2003:eb:8f06:1166:8d55:8860:be74:ade1]) by smtp.gmail.com with ESMTPSA id i3sm23150542wrr.19.2021.02.15.08.48.57 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Feb 2021 08:48:57 -0800 (PST)
Content-Type: text/plain; charset="utf-8"
Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.60.0.2.21\))
From: Torsten Lodderstedt <torsten@lodderstedt.net>
In-Reply-To: <CO6PR18MB4052CE7A7AFF1FAD39EDB90FAE899@CO6PR18MB4052.namprd18.prod.outlook.com>
Date: Mon, 15 Feb 2021 17:48:56 +0100
Cc: "oauth@ietf.org" <oauth@ietf.org>, Brian Campbell <bcampbell@pingidentity.com>
Content-Transfer-Encoding: quoted-printable
Message-Id: <16CA5346-48EF-4B29-8397-EE6312366C63@lodderstedt.net>
References: <CO6PR18MB4052C85E4B5D5EE5E1DD357AAE899@CO6PR18MB4052.namprd18.prod.outlook.com> <5BE7C60F-84AB-431A-838F-D33459E551C6@lodderstedt.net> <CO6PR18MB4052CE7A7AFF1FAD39EDB90FAE899@CO6PR18MB4052.namprd18.prod.outlook.com>
To: Vittorio Bertocci <vittorio.bertocci=40auth0.com@dmarc.ietf.org>
X-Mailer: Apple Mail (2.3654.60.0.2.21)
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/04sBf58qTLePBsKJcKYyYlJljfg>
Subject: Re: [OAUTH-WG] Token Mediating and session Information Backend For Frontend (TMI BFF)
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: Mon, 15 Feb 2021 16:49:03 -0000

Thank you again for the explanation. 

I think your assumption about the overall flow should be described in the draft. 

As I understand it now the core contribution of your proposal is to move refresh token management from frontend to backend. Is that correct?  

> Am 14.02.2021 um 21:35 schrieb Vittorio Bertocci <vittorio.bertocci=40auth0.com@dmarc.ietf.org>:
> 
> Thanks!
> I expect the frontend (as in JS code) not to kick in until the initial authorization has been perfomed. Breaking it down as a classic possible flow:
> 
> - User navigates to the app page, clicks "sign in"
> - The backend redirects the user to the AS to perform a code grant (for the sake of argument let's also say they ask for an IDtoken as well tho it isn’t strictly necessary), with the purpose of gathering consent for the scopes required. No frontend code involved. 
> - The code grant concludes successfully, the backend now has a session with the user agent and an AT, RT stored on the server side
> - --> here TMI-BFF begins. Whenever the frontend needs a token to call an API, they use TMI-BFF to ask for that token to the backend
> - if the backend can return the requested token, via stored AT or by using the RT, it does it
> - if the backend cannot get the requested token with what it already has without suer interaction, it fails
> --> here there's where TMI-BFF ends- it's up to the backend to decide how to meet the new requirements, eg by triggering another authorization code grant for new scopes. The frontend is not involved apart from perhaps offering affordances to the end upper to start such process
> 
> TMI-BFF does not include the actual authorization requests mostly for simplicity. We don’t really know how the app is structured nor the reasons for which a backend might be unable to get the requested token. The RT might be expired; or the current scopes might be insufficient; or the AS might decide that now issuing an AT with that scope might require a different authentication method; and many other reasons I can’t think of. If we were to provide a mechanism that includes in the error message indications on what the frontent should do to remediate the error, we might need to either scope down the scenarios or create a very flexible mechanism. I am not opposed, but before venturing into that we wanted to see what the reaction would be.  
> 
> On 2/14/21, 11:45, "Torsten Lodderstedt" <torsten=40lodderstedt.net@dmarc.ietf.org> wrote:
> 
>    Hi Vittorio,
> 
>    thanks for the explanation. Do you assume the frontend passes the code or initial refresh token to the backend using an application specific mechanism? Why isn’t this part of the bff-token request?
> 
>    best regards,
>    Torsten.
> 
>> Am 14.02.2021 um 20:19 schrieb Vittorio Bertocci <vittorio.bertocci=40auth0.com@dmarc.ietf.org>:
>> 
>> Hi Torsten, thanks for looking into this!
>> The idea is that the application backend performed all the interactive token acquisition steps before TMI-BFF come into play.
>> Imagine that a regular web app performs an authorization code grant, requesting access token and refresh token in the process (and often also setting its own session with the user agent in the process, if the AS is also their IdP via OIDC or similar, but that's not strictly necessary). Now the app backend has an access token and refresh token persisted on the server side.
>> All TMI-BFF does is to describe how the backend can share those tokens with its fronted, either directly (if the persisted AT is still valid) or indirectly (if it has to use an RT to obtain a new AT before sending it back).
>> The frontend provides resource and scope to select what token it needs, but the current idea is that the backend already obtained both consent and artifacts to obtain those tokens from the AS. And if it doesn't, at the moment we simply fail and expect the app developer to take the steps required to prompt the user with whatever is necessary for updating the backend with the right permissions, eg creating a new authorization request asking for a scope the frontend needs and that the user wasn't prompted to consent yet. At the moment TMI-BFF does not provide a mechanism for that prompt to occur, it just errors out saying "you've got to  update your authorization artifacts before the frontend can get the token w the scopes it needs".
>> Another way to think about this: in TMI-BFF the frontend treats the backend is a tokens database. Indicating the resource and scopes is a query. If the backend can serve that query (with the ATs it saved, or by using the RTs it saved AND the grants the user already gave) it returns a token. If it doesn't, it fails the query. The frontend does not play a direct role into inserting in the DB more tokens. That is left to the backend, that can do so by initiating a new authorization grant, not described in TMI-BFF, that must conclude successfully for the frontend to be able to repeat its query and this time get the token they want out. Note that the backend might decide that it won’t try to get the token requested, or it might unable to do so (eg the user/app cannot meet some requirements as the AS is concerned), hence the request of it might at times be permanently denied. This last part is to say that providing in the error message details about the remediation might take more work than one realizes at first, and ultimately acting on the error situation to retrieve a new token is still up to the backend anyway, hence providing elaborate machinery to inform the frontend beyond the error situation might not be as effective as it might look at first glance. I am totally open to it, just making sure we understand what it can buy us.  
>> 
>> On 2/14/21, 06:11, "Torsten Lodderstedt" <torsten=40lodderstedt.net@dmarc.ietf.org> wrote:
>> 
>>   Hi,
>> 
>>   I’m trying to understand your proposal. 
>> 
>>   Section 1.2, bullet (B) states
>> 
>>   (B) If the backend does not already have a suitable access token
>>         obtained in previous flows and cached, it requests to the
>>         authorization server a new access token with the required
>>         characteristics, using any artifacts previousy obtained (eg
>>         refresh token) and grants that will allow the authorization server
>>         to issue the requested token without requiring user interaction.
>> 
>>   Can you please explain how the authorization process works towards the AS, especially in case of the authorisation code grant type. I would have expected to frontend to pass an authorisation code to the bff-token request. 
>> 
>>   But section 4.1. only defines the parameters „resource" and „scope" for the bff-token endpoint. 
>> 
>>   thanks,
>>   Torsten. 
>> 
>>> Am 12.02.2021 um 21:46 schrieb Vittorio Bertocci <vittorio.bertocci=40auth0.com@dmarc.ietf.org>:
>>> 
>>> Dear all,
>>> Brian and yours truly are proposing a new specification that shows how the user agent frontend of a web app can delegate token acquisition and persistence to its backend, and request such tokens when needed for direct access of protected resources from the frontend code.
>>> 
>>> The pattern is already in use, in proprietary form, by various modern development stacks, such as Next.JS. Variants of the pattern, often discussed under the catch-all term BFF (backend for frontend), have been often mentioned in this workgroup’s activity, but always left all implementation details to the reader.
>>> We believe the pattern has merit, as corroborated by its growing adoption. By delegating access token acquisition to the backend, we avoid many of the often brittle moving parts (and implied attack surface) required to acquire access tokens from a user agent. The topology also relieves the frontend from the need of persisting tokens in local storage, a well known sore point of using OAuth directly in JavaScript, by relying on its backend storage and session to preserve tokens.
>>> 
>>> Although the specification is very simple, providing explicit guidance on the scenario offers many advantages.  
>>> - It makes it possible to create interoperable SDKs, where frontend dev stacks (any JS flavor) can be mixed and matched with compliant backend stacks (middlewares in node, java, ASP.NET, PHP etc)
>>> - It allows us to provide guidance on how to properly tackle the scenario and warn implementers against security risks (scope escalations, using IDtokens instead of access tokens, etc)
>>> - It allows us to discuss (and when appropriate, promote) this pattern as part of the browser apps security guidance, and position the scenario where frontend only calls API on its own backed (hence doesn’t need access tokens) simply as a special case of this more general pattern
>>> - This approach makes mocking and testing apps very easy, possibly preventing developers from weakening the security of their system (eg turning on ROPG options)  or turning to risky practices like scraping
>>> 
>>> Needless to say, this specification doesn’t entirely eliminate the risks inherent to direct use of access tokens from a browser. But reality is that the pattern is in widespread use, and the circumstances leading to that (eg developers on a particular project only work with frontend stacks; components like reverse proxies might not always be viable; etc) aren’t going away any time soon. By providing simple guidance on this pattern, we can simplify the life of many developers while enshrining basic security hygiene in scenarios that would have otherwise be left to their own device.
>>> 
>>> Looking forward for your feedback!
>>> 
>>> B&V  
>>> 
>>> On 2/12/21, 12:41, "internet-drafts@ietf.org" <internet-drafts@ietf.org> wrote:
>>> 
>>> 
>>>  A new version of I-D, draft-bertocci-oauth2-tmi-bff-00.txt
>>>  has been successfully submitted by Vittorio Bertocci and posted to the
>>>  IETF repository.
>>> 
>>>  Name:        draft-bertocci-oauth2-tmi-bff
>>>  Revision:    00
>>>  Title:        Token Mediating and session Information Backend For Frontend
>>>  Document date:    2021-02-12
>>>  Group:        Individual Submission
>>>  Pages:        16
>>>  URL:            https://www.google.com/url?q=https://www.google.com/url?q%3Dhttps://www.google.com/url?q%253Dhttps://www.ietf.org/archive/id/draft-bertocci-oauth2-tmi-bff-00.txt%2526source%253Dgmail-imap%2526ust%253D1613767591000000%2526usg%253DAOvVaw3Rb-S0l6cEv0ytjDxtYLAP%26source%3Dgmail-imap%26ust%3D1613935165000000%26usg%3DAOvVaw3p5263a_rEePNbnX7jWFjq&source=gmail-imap&ust=1613939757000000&usg=AOvVaw0jgXsBeXKFC9n31Rg06yE6
>>>  Status:         https://www.google.com/url?q=https://www.google.com/url?q%3Dhttps://www.google.com/url?q%253Dhttps://datatracker.ietf.org/doc/draft-bertocci-oauth2-tmi-bff/%2526source%253Dgmail-imap%2526ust%253D1613767591000000%2526usg%253DAOvVaw3-qg5MDtY7kD1HpR5jR2QY%26source%3Dgmail-imap%26ust%3D1613935165000000%26usg%3DAOvVaw1YZmVHpENHa-bqqtbezRpa&source=gmail-imap&ust=1613939757000000&usg=AOvVaw0UWVw3PhVKKuwdIjaMHfce
>>>  Html:           https://www.google.com/url?q=https://www.google.com/url?q%3Dhttps://www.google.com/url?q%253Dhttps://www.ietf.org/archive/id/draft-bertocci-oauth2-tmi-bff-00.html%2526source%253Dgmail-imap%2526ust%253D1613767591000000%2526usg%253DAOvVaw05WK4GSEKcWjZzNhvb1p5d%26source%3Dgmail-imap%26ust%3D1613935165000000%26usg%3DAOvVaw2HibfQtTYv3talGT379MOu&source=gmail-imap&ust=1613939757000000&usg=AOvVaw3AuwQ6TPoW5MnsGXcMUh_S
>>>  Htmlized:       https://www.google.com/url?q=https://www.google.com/url?q%3Dhttps://www.google.com/url?q%253Dhttps://tools.ietf.org/html/draft-bertocci-oauth2-tmi-bff-00%2526source%253Dgmail-imap%2526ust%253D1613767591000000%2526usg%253DAOvVaw0qm45MWGbZf0zbBjZj3ggz%26source%3Dgmail-imap%26ust%3D1613935165000000%26usg%3DAOvVaw0gZZ0ZU8QVx7OBjxDcG8d-&source=gmail-imap&ust=1613939757000000&usg=AOvVaw2fIy9b1bQxvnk5QK9Nl7QI
>>> 
>>> 
>>>  Abstract:
>>>     This document describes how a JavaScript frontend can delegate access
>>>     token acquisition to a backend component.  In so doing, the frontend
>>>     can access resource servers directly without taking on the burden of
>>>     communicating with the authorization server, persisting tokens, and
>>>     performing operations that are fraught with security challenges when
>>>     executed in a user agent, but are safe and well proven when executed
>>>     by a confidential client running on a backend.
>>> 
>>> 
>>> 
>>> 
>>>  Please note that it may take a couple of minutes from the time of submission
>>>  until the htmlized version and diff are available at tools.ietf.org.
>>> 
>>>  The IETF Secretariat
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> OAuth mailing list
>>> OAuth@ietf.org
>>> https://www.google.com/url?q=https://www.google.com/url?q%3Dhttps://www.google.com/url?q%253Dhttps://www.ietf.org/mailman/listinfo/oauth%2526source%253Dgmail-imap%2526ust%253D1613767591000000%2526usg%253DAOvVaw1Bfu9fJ2Fj_BZJ3H9yw7od%26source%3Dgmail-imap%26ust%3D1613935165000000%26usg%3DAOvVaw3a73buBtPOBoDQ3SMH_XJW&source=gmail-imap&ust=1613939757000000&usg=AOvVaw3p0jGqda5qiL2KioFSSZ01
>> 
>> 
>