idnits 2.17.1 draft-bertocci-oauth2-tmi-bff-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (25 April 2021) is 1097 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) ** Obsolete normative reference: RFC 5785 (Obsoleted by RFC 8615) == Outdated reference: A later version (-26) exists of draft-ietf-oauth-security-topics-16 == Outdated reference: A later version (-13) exists of draft-ietf-httpbis-rfc6265bis-07 == Outdated reference: A later version (-10) exists of draft-ietf-oauth-v2-1-00 Summary: 1 error (**), 0 flaws (~~), 4 warnings (==), 2 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Web Authorization Protocol V. Bertocci 3 Internet-Draft auth0.com 4 Intended status: Standards Track B. Campbell 5 Expires: 27 October 2021 Ping Identity 6 25 April 2021 8 Token Mediating and session Information Backend For Frontend 9 draft-bertocci-oauth2-tmi-bff-01 11 Abstract 13 This document describes how a JavaScript frontend can delegate access 14 token acquisition to a backend component. In so doing, the frontend 15 can access resource servers directly without taking on the burden of 16 communicating with the authorization server, persisting tokens, and 17 performing complex operations within the user agent that would 18 require configuration, error management and reliance on authorization 19 server capabilities (such as refresh token rotation) that aren't 20 widely available today. 22 Status of This Memo 24 This Internet-Draft is submitted in full conformance with the 25 provisions of BCP 78 and BCP 79. 27 Internet-Drafts are working documents of the Internet Engineering 28 Task Force (IETF). Note that other groups may also distribute 29 working documents as Internet-Drafts. The list of current Internet- 30 Drafts is at https://datatracker.ietf.org/drafts/current/. 32 Internet-Drafts are draft documents valid for a maximum of six months 33 and may be updated, replaced, or obsoleted by other documents at any 34 time. It is inappropriate to use Internet-Drafts as reference 35 material or to cite them other than as "work in progress." 37 This Internet-Draft will expire on 27 October 2021. 39 Copyright Notice 41 Copyright (c) 2021 IETF Trust and the persons identified as the 42 document authors. All rights reserved. 44 This document is subject to BCP 78 and the IETF Trust's Legal 45 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 46 license-info) in effect on the date of publication of this document. 47 Please review these documents carefully, as they describe your rights 48 and restrictions with respect to this document. Code Components 49 extracted from this document must include Simplified BSD License text 50 as described in Section 4.e of the Trust Legal Provisions and are 51 provided without warranty as described in the Simplified BSD License. 53 Table of Contents 55 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 56 1.1. Topology and Roles . . . . . . . . . . . . . . . . . . . 5 57 1.2. Protocol Flow . . . . . . . . . . . . . . . . . . . . . . 5 58 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 7 59 3. Endpoints . . . . . . . . . . . . . . . . . . . . . . . . . . 7 60 3.1. The bff-token Endpoint . . . . . . . . . . . . . . . . . 8 61 3.2. The bff-sessioninfo Endpoint . . . . . . . . . . . . . . 8 62 4. Requesting Access Tokens to the Backend . . . . . . . . . . . 8 63 4.1. Access Token Request . . . . . . . . . . . . . . . . . . 9 64 4.2. Access Token Response . . . . . . . . . . . . . . . . . . 10 65 4.3. Errors . . . . . . . . . . . . . . . . . . . . . . . . . 11 66 4.3.1. No valid session found . . . . . . . . . . . . . . . 11 67 4.3.2. Backend cannot perform a request to the authorization 68 server . . . . . . . . . . . . . . . . . . . . . . . 12 69 4.3.3. The backend request to the authorization server 70 fails . . . . . . . . . . . . . . . . . . . . . . . . 12 71 5. Requesting Session Information from the Backend . . . . . . . 12 72 5.1. Session Information Request . . . . . . . . . . . . . . . 12 73 5.2. Session Information Response . . . . . . . . . . . . . . 13 74 5.3. Error . . . . . . . . . . . . . . . . . . . . . . . . . . 13 75 6. Security Considerations . . . . . . . . . . . . . . . . . . . 14 76 6.1. Frontend should not persist access tokens in local 77 storage . . . . . . . . . . . . . . . . . . . . . . . . . 14 78 6.2. Mismatch between security characteristics of token 79 requestor and API caller . . . . . . . . . . . . . . . . 14 80 6.3. Mismatch between scopes in a request vs cached tokens . . 14 81 6.4. Resource server colocated with the backend . . . . . . . 15 82 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 15 83 8. Normative References . . . . . . . . . . . . . . . . . . . . 16 84 9. Informative References . . . . . . . . . . . . . . . . . . . 16 85 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 17 86 Appendix B. Document History . . . . . . . . . . . . . . . . . . 17 87 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 18 89 1. Introduction 91 A large portion of today's development stacks, practices and tools 92 for the web target the user agent itself as execution environment, 93 leveraging local resources to offer a rich, responsive user 94 experience that rivals native applications. 96 An important aspect of apps running in the user agent is their 97 reliance on HTTP APIs, served from the app's own backend component or 98 from third party providers on disparate domains. Whenever those API 99 are secured according to the OAuth2 Bearer Token Usage [RFC6750], the 100 user agent app needs to obtain suitable access tokens: however, the 101 task of implementing an OAuth2 [RFC6749] client executing in a user 102 agent is complicated by security challenges and restrictions inherent 103 in the browser platform. The original OAuth2 [RFC6749] provided 104 guidance dedicated to user agent apps in section 4.2, via the 105 implicit grant. The approach proved to suffer from too many 106 challenges, however, leading subsequent documents (such as the OAuth2 107 security BCP [I-D.ietf-oauth-security-topics] and OAuth 2.1 108 [I-D.ietf-oauth-v2-1]) to recommend a more secure approach based on 109 the authorization code grant with PKCE [RFC7636], and relying on 110 additional security measures such as refresh token rotation and 111 sender constraint. 113 Even the new guidance doesn't entirely eliminate some of the inherent 114 risks and complications of implementing an OAuth2 client in a user 115 agent. For example, both access tokens and refresh tokens end up in 116 the user agent, where they are vulnerable to many important attacks; 117 and in general, implementing a full fledged OAuth2 client requires 118 many moving parts (connecting to the appropriate authorization server 119 endpoints, managing communications, handling complex error 120 situations, etc) that can be alleviated but cannot be completely made 121 transparent to the frontend developer by the use of SDKs. 123 In the attempt to avoid those limitations, developers are 124 increasingly pursuing approaches where their backend components (when 125 available) play a more active role. For example, there are many 126 solutions where the backend takes care of obtaining tokens from the 127 authorization server, using classic confidential client grants, and 128 provides a facade for every API the frontend needs to invoke: in that 129 way, the frontend can simply call the API via facade, securing 130 communications with its backend using mainstream methods such as any 131 cookie based web sign on technology. In some literature the 132 aforementioned pattern, where both token acquisition and API 133 invocation is delegated to a backend, is identified by the term BFF - 134 backend for frontend. Other sources use the term BFF to describe any 135 topology where at least some functionality traditionally implemented 136 by the frontent is delegated to the backend. For the sake of 137 clarity, in this document we will use Full BFF to refer to the 138 approach where both token acquisition and API invocation are handled 139 by the backend, and BFF for approaches where the frontend retain the 140 responsibility to implement some functionality (as it is the case for 141 the pattern described in this specification). 143 Although the Full BFF approach offers better security, by virtue of 144 keep all tokens out of the user agent, it is not always viable. 145 Depending on the number of users and chattiness of the application, 146 routing every API call thru the backend can be expensive in terms of 147 performance, latency, and service tier of the hosting platform in 148 use; the solution might rely on user agents connecting to API in the 149 same region; the developmnt and hosting stack might not offer a 150 viable product or technology implementing the pattern. For and other 151 reasons, it is increasingly common practice to use a simpler 152 solution: rely on the backend component for obtaining tokens from the 153 authorization server, and sending back to the frontend the resulting 154 access tokens for direct frontend to API communication. As long as 155 the mechanism used for transmitting tokens from the backend to the 156 frontend is secure, the approach is viable: however leaving the 157 details of its implementation to every application and stack 158 developer results in the impossibility to have frontend and backend 159 development stacks to interoperate out of the box. Furthermore, 160 there are a number of security considerations that, if disregarded in 161 the implementation of the pattern, might lead to elevation of 162 privilege attacks and other challenges. 164 This documents provides detailed guidance on how to implement the 165 pattern in which a frontend component can delegate token acquisition 166 to its backend component. By offering precise guidance on details 167 such as endpoints and messages format for each operation, this 168 specification will allow developers to create and consume off-the- 169 shelf components that will easily interoperate and allow mixing and 170 matching different frontend and backend SDKs, making it possible to 171 author single page apps consuming APIs on arbitrary domains without 172 having to cope with the complexity normally associated to a frontend- 173 only approach. The OAuth2 for Browser-Based Apps BCP [BrowserBCP] 174 hints at both Full BFF and the approach described here, but doesn't 175 provide detailed guidance - this specification doesn't replace the 176 BCP, it just providers more details to facilitate interoperable and 177 well designed implementations. It's important to stress that the 178 approach here described should be considered only when a Full BFF 179 approach is not viable. Whenever it is possible for a solution to 180 keep tokens out of a user agent, a Full BFF approach should be 181 preferred. 183 Given that the pattern described here does not provide any artifact 184 that the frontend can use to obtain session information such as user 185 attributes, something traditional approaches to user agent apps 186 development do afford, this document also provides a mechanism for 187 the frontend to obtain session information from the backend. 189 1.1. Topology and Roles 191 This document describes how a single page application featuring a 192 backend can obtain tokens from an OAuth2 authorization server to 193 access a resource server. For what the protocol flow is concerned, 194 the topology can be broken down into four roles: 196 Frontend: This represents the application code executing in the user 197 agent, controlling presentation and invoking one or more resource 198 servers. 200 Backend: The backed represents code executing on a server, in 201 particular on the same domain from where the frontend code has 202 been served. Backend and frontend are both under the control of 203 the same developer. 205 Resource Server: This represents a classic OAuth2 resource server as 206 described in Section 1.1 of OAuth2 [RFC6749], exposing the API the 207 frontend needs to invoke. See Section 6 for more details applying 208 to notable cases. 210 Authorization Server: This represents a classic OAuth2 authorization 211 server as described in Section 1.1 of OAuth2 [RFC6749], handling 212 authorization for the API the frontend needs to invoke. This 213 document does not introduce any changes in the standard 214 authorization server behavior, however see Section 6 for some 215 security considerations that might influence the policies of 216 individual servers. 218 1.2. Protocol Flow 220 This section provides a high level description of the way in which 221 the frontend can obtain and use access tokens with the help of its 222 backend. As a prerequisite for the flow described below, the backend 223 MUST have established a secure session with the user agent, so that 224 all requests from that user agent toward the backend occur over HTTPS 225 and carry a valid session artifact (such as a cookie) that the 226 backend can validate. This document does not mandate any specific 227 mechanism to establish and maintain that session. In other words: 228 the user must have signed in the backend, using whatever web sign on 229 mechanism the developer chooses. For example, the user might have 230 signed in the backend using OpenID Connect [OIDC], resulting in a 231 session cookie bound to the backend application domain that will be 232 included in every future requests from the user agent. The choice of 233 web sign on technology is completely arbitrary, with the only 234 requirement of resulting in an authenticated session. 236 A second prerequisite establishes that the backend must obtain the 237 access tokens that will be requested by the frontend later on, and or 238 whatever mechanism will allow the backend to renew access tokens (or 239 obtain new ones) in non-interactive fashion. For example, the 240 backend might perform an OAuth2 authorization code flow after sign in 241 to obtain access tokens and refresh tokens; or might have performed 242 an OpenID Connect hybrid flow, satisfying both the sign in and access 243 token acquisition requirements in a single step. Once the backend 244 obtains the tokens, it should persist them in preparation to hand 245 them over to the frontend when requested to do so, following the flow 246 described below. 248 [[ TODO SVG maybe someday... ]] 250 +---------------+ 251 | | 252 | Authorization | 253 | Server | 254 | | 255 +---------------+ 256 ^ | 257 | 258 | 259 (B) Token | 260 request | (C) Token 261 | response 262 | 263 | v 264 +-------------+ +---------------+ 265 | | | | 266 | |---(A) bff-token request-->| | 267 | Frontend | | Backend | 268 | |<--(D) bff-token response--| | 269 | | | | 270 +-------------+ +---------------+ 271 ^ | 272 | | 273 | | 274 | | +---------------+ 275 | | | | 276 | ----(E) Protected resource request---->| Resource | 277 | | Server | 278 ------(F) Protected resource response-------| | 279 | | 280 +---------------+ 282 Figure 1: An abstract diagram of the flow followed to obtain an 283 access token and access a protected resource 285 * (A) The frontend presents to the backend a request for an access 286 token for a given resource server 288 * (B) If the backend does not already have a suitable access token 289 obtained in previous flows and cached, it requests to the 290 authorization server a new access token with the required 291 characteristics, using any artifacts previousy obtained (eg 292 refresh token) and grants that will allow the authorization server 293 to issue the requested token without requiring user interaction. 295 * (C) The authorization server returns the requested token and any 296 additional information according to the grant used (eg validity, 297 actual scopes granted, etc) 299 * (D) The backend returns the requested access token to the frontend 301 * (E) The frontend presents the access token to the resource server 303 * (F) the resource server validates the incoming token and returns 304 the protected resource 306 2. Conventions and Definitions 308 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 309 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 310 "OPTIONAL" in this document are to be interpreted as described in BCP 311 14 [RFC2119] [RFC8174] when, and only when, they appear in all 312 capitals, as shown here. 314 3. Endpoints 316 This specification introduces "bff-token" and "bff-sessioninfo", two 317 specialized endpoints that the backend exposes to support the 318 frontend in acquiring tokens and user session information. For the 319 purpose of facilitating the implementation of the pattern with 320 minimal configuration requirements, these endpoints are published at 321 a ".well-known" location according to RFC 5785 [RFC5785]. Both 322 endpoints are meant to be used by the applications' frontend, and the 323 frontend only. As such, the backend MUST verify the the call is 324 occurring in the context of a secure session (e.g., by mandating the 325 presence of a valid session cookie received via HTTPS). The content 326 returned from these two endpoints contains credentials and other 327 sensitive information so MUST also be protected against cross-origin 328 reading of the response data. Preventing successful cross-origin 329 requests in the first place is a strong protection against against 330 cross-origin reads. As such, the endpoints MUST NOT be accessible 331 via CORS and SHOULD have protections in place to prevent Cross-Site 332 Request Forgery. If a cookie is used to maintain the secure session, 333 it SHOULD be marked with "HttpOnly" [RFC6265] and "SameSite" 334 [I-D.ietf-httpbis-rfc6265bis]. Both endpoints return JSON [RFC8259] 335 so the response MUST contain a "Content-Type" header with the correct 336 "application/json" value and SHOULD also contain a "X-Content-Type- 337 Options" header with a value of "nosniff". Additional guidance 338 around preventing unauthorized reading of response data can be found 339 in [Post-Spectre-Web-Dev] where the discussion of Dynamic 340 Subresources is particularly relevant. 342 3.1. The bff-token Endpoint 344 The "bff-token" endpoint is exposed by the backend to allow the 345 frontend to request access tokens. It is exposed at the well-known 346 relative URI "/.well-known/bff-token". The "bff-token" endpoint URI 347 MUST use the "https" scheme. The backend MUST support the use of the 348 HTTP "GET" method for the "bff-token" endpoint and MAY support the 349 use of the "POST" method as well. The backend MUST ignore 350 unrecognized request parameters. See Section 4 for more details on 351 how to use the "bff-token" endpoint. 353 3.2. The bff-sessioninfo Endpoint 355 The "bff-sessioninfo" endpoint is exposed by the backend to allow the 356 frontend to obtain information about the current user, so that it can 357 be accessed my the presentation code. 358 It is exposed at the well-known relative URI "/.well-known/bff- 359 sessioninfo". The backend MUST support the use of the HTTP "GET" 360 method for the "bff-sessioninfo" endpoint. The backend MUST ignore 361 unrecognized request parameters. See Section 5 for more details on 362 how to use the "bff-sessioninfo" endpoint. 364 4. Requesting Access Tokens to the Backend 366 To obtain an access token, the frontend makes a request to the 367 backend at the "bff-token" endpoint URI. The flow includes the 368 following steps, as shown in Figure 1. 370 [[ TODO more granular error refs ]] 372 1. The frontend generates the request and sends it to the "bff- 373 token" endpoint as described in Section 4.1 (leg A in Figure 1). 375 2. The backend examines the request, validating whether it includes 376 a valid user session: if it doesn't, it rejects the request as 377 described in Section 4.3.1. 379 3. The backend extracts user information from the session, using 380 whatever mechanism it deems suitable, and verifies whether it 381 already has in storage a suitable access token satisfying the 382 request (see Section 6 for more details). If it does, it returns 383 it as described in (5). 385 4. If there is no suitable access token stored, the backend verifies 386 whether it has the necessary artifacts to request it to the 387 authorization server without requiring user interaction- for 388 example, by using a refresh token previously stored for the 389 current user. If it does, the backed contacts the authorization 390 server with a token request using the grant of choice (leg B in 391 Figure 1). In the absence of a suitable artifact required to 392 perform a request toward the authorization server, the backend 393 returns an error to the frontend as described in Section 4.3.2. 395 5. If the authorization server returns the requested token as 396 expected (leg C in Figure 1), the backend returns it to the 397 frontend, as shown in Leg D of Figure 1 and described in 398 Section 4.2. If the authorization server denies the request, the 399 backend returns an error to the frontend as described in 400 Section 4.3.3. 402 The following sections provide more details for each of the messages 403 described. 405 4.1. Access Token Request 407 The frontend requests an access token from the backend by specifying 408 the requirements the resulting token must meet. To do so, the 409 following parameters may be added to to the query component (or 410 request payload in the case of 'POST') of the "/.well-known/bff- 411 token" request URI using the "application/x-www-form-urlencoded" 412 format with a character encoding of UTF-8 as described in Appendix B 413 of [RFC6749]. 415 "resource" : The identifier of the desired resource server, as 416 defined in [RFC8707]. This parameter is OPTIONAL. 418 "scope" : The scope of the access request resulting in the desired 419 access token. This parameter follows the syntax described in 420 section 3.3 of [RFC6749]. This parameter is OPTIONAL. 422 Both parameters MAY be absent from the request. Given that the 423 frontend and the backend are components of the same application, it 424 is possible in some scenarios for the backend to determine what token 425 to return to the frontend without any specific requirement. For 426 example, the application might be consuming only one resource, with a 427 fixed set of scopes: that would make specifying that information in 428 the request from the frontend unnecessary. 430 The following is an example of request where both resource and scopes 431 are specified. 433 GET /.well-known/bff-token?scope=buy+sell 434 &resource=https%3A%2F%2Fapi.example.org%2Fstocks HTTP/1.1 435 Host: myapp.example.com 436 Cookie: super-secure-session=hVQvkyX2IOj36fqIoUQFlBeALbh 438 Note that the request does not need to specify any client attributes, 439 as those are all handled by the backend- and the presence of a pre- 440 existing session provides the context necessary for the backend to 441 select the right settings when crafting requests for the 442 authorization server. 444 4.2. Access Token Response 446 If the backend successfully obtains a suitable token, or has one 447 already cached, it returns it to the frontend with the following 448 parameters in the payload of the HTTP response using the 449 "application/json" media type as defined by [RFC8259]. 451 "access_token" : The requested access token. This parameter is 452 REQUIRED. 454 "expires_in" : The lifetime in seconds of the access token, as 455 defined in section 5.1 of [RFC6749]. This parameter is REQUIRED, 456 if the information was made available from the authorization 457 server that originally issued the access token. 459 "scope" : The scope of the access token being returned as list of 460 space-delimited, case-sensitive strings, as defined in Section 3.3 461 of [RFC6749]. If the request contained a scope parameter, and the 462 scope of resulting token is different from the requested value, 463 this parameter is REQUIRED. In all other cases, the presence of 464 scope in the response is OPTIONAL. 466 The following is an example of access token response. 468 HTTP/1.1 200 OK 469 Content-Type: application/json 470 X-Content-Type-Options: nosniff 471 Cache-Control: no-cache, no-store 472 Cross-Origin-Resource-Policy: same-origin 473 Content-Security-Policy: sandbox 474 Cross-Origin-Opener-Policy: same-origin 475 X-Frame-Options: DENY 477 { 478 "access_token":"4bWc0ESC9aCc77LTC8EjR1pCfE4WxfNg", 479 "expires_in":3596, 480 "scope":"buy sell" 481 } 483 Note that if the backend elects to cache tokens, to serve future 484 requests from the frontend without contacting the authorization 485 server if still within the useful lifetime, it must also cache 486 expiration information and scopes in accordance to the requirements 487 expressed in this section. 489 4.3. Errors 491 When the backend fails to deliver to the frontend the requested 492 token, it responds with an HTTP 400 (Bad Request) status code and 493 includes the following parameters with the response: 495 "error" : An ASCII error code identifying the circumstances of the 496 error. See the next sections for details. This parameter is 497 REQUIRED. 499 "error_description" : OPTIONAL. A human-readable message describing 500 the error for troubleshooting purposes. 502 4.3.1. No valid session found 504 All requests to the backend MUST be performed in the context of a 505 valid authenticated session, typically by presenting a session cookie 506 over a TLS channel. If the backend cannot find or validate a 507 session, it must reject the request and return a message as described 508 in Section 4.3, with an error parameter value of "invalid_session". 510 4.3.2. Backend cannot perform a request to the authorization server 512 If the backend doesn't have the necessary artifacts (e.g., a refresh 513 token for the current user and/or requested resource) to request a 514 suitable access token to the authorization server without requiring 515 user interaction, it will reject the request and return a message as 516 described in Section 4.3, with an error parameter value of 517 "backend_not_ready". 519 4.3.3. The backend request to the authorization server fails 521 If the backend request to the authorization server fails, the backend 522 will return to the frontend a message as described in Section 4.3, 523 with as error parameter value the error parameter received in the 524 authorization server response (as described by section 5.2 of 525 [RFC6749] and, if present in the authorizations server response, will 526 include the error_description parameter with the same parameter value 527 as received by the authorization server. [[ TODO wow this sentence is 528 ugly. ]] 530 5. Requesting Session Information from the Backend 532 Application developers will often need to obtain information about 533 the current session (such as user attributes, session expiration, 534 etc) to display it to the end user, drive application behavior and 535 any other operation it would perform if the frontend would be in 536 charge of obtaining tokens directly. In the topology described in 537 this specification, most of the user experience is driven by the 538 frontend: however, the session information is inaccessible to the 539 user agent, as it is either kept in artifacts that the user agent 540 cannot inspect (opaque sessions cookies) or on the backend side. The 541 "/.well-known/bff-sessioninfo" endpoint is meant to restore the 542 developer's ability to access the session information they need, 543 without compromising the security of the solution. At any time, the 544 frontend can leverage the current secure session to send to the "bff- 545 sessioninfo" endpoint a request, and receive the needed session 546 information. The following sections provide details on request and 547 response messages. 549 5.1. Session Information Request 551 The frontend sends a request for session information via an HTTP GET, 552 using the "https" scheme in the context of a secure session. The 553 request has no parameters. The following is an example of session 554 information request. 556 GET /.well-known/bff-sessioninfo HTTP/1.1 557 Host: myapp.example.com 558 Cookie: super-secure-session=hVQvkyX2IOj36fqIoUQFlBeALbh 560 5.2. Session Information Response 562 If the request is executed in the context of a secure session, the 563 backend returns a JSON object containing any information it deems 564 appropriate to share with the frontend about the content of the 565 session. For example, if the session was established via OpenID 566 Connect [OIDC] the response might contain the session and user 567 attribute claims as defined in sections 2 and 5.1 of [OIDC]. The 568 following is a non-normative example of such a session information 569 response. 571 HTTP/1.1 200 OK 572 Content-Type: application/json 573 X-Content-Type-Options: nosniff 574 Cache-Control: no-cache, no-store 576 { 577 "iss": "https://as.example.com", 578 "sub": "24400320", 579 "exp": 1311281970, 580 "auth_time": 1311280969, 581 "preferred_username": "johnny", 582 "email_verified: "johnny@foo.com", 583 "given_name": "Jonathan", 584 "family_name" : "Swift" 585 } 587 It is worth noting that the backend isn't bound to any specific rule 588 and is free to return any information it deems necessary in this 589 message in the context of the application (frontend and backend) own 590 requirements. 592 5.3. Error 594 In case the frontend sends a request to bff-sessioninfo in the 595 absence of a valid secure session, the backend will return an error 596 as described in Section 4.3.2. For any other error situation, the 597 backend is free to determine what to signal to the frontend. [[ TODO 598 seems a bit weak... maybe a generic error? ]] 600 6. Security Considerations 602 The simplicity of the described pattern notwithstanding, there are a 603 number of important considerations that frontend, backend and SDK 604 implementers should keep in mind while implementing this approach. 606 6.1. Frontend should not persist access tokens in local storage 608 Access tokens SHOULD NOT be saved in local storage: they SHOULD be 609 kept in memory, and retrieved anew when necessary from the backend 610 following Section 4. 612 6.2. Mismatch between security characteristics of token requestor and 613 API caller 615 Some authorization servers might express in their access tokens 616 whether the client obtaining it authenticated itself, or it behaved 617 as a public client. Resource servers might rely on that information 618 to infer the nature and security characteristics of the application 619 presenting the access token to them, and use that to drive 620 authorization decisions (e.g., only allow certain operations if the 621 caller is a confidential client). The pattern described here obtains 622 an access token through the backend, a confidential client, but the 623 access token is ultimately used by code executing in a far less 624 secure environment. Resource servers knowing that their clients will 625 use this pattern SHOULD refrain from using the client authentication 626 type as a factor in authorization decision, or, whenever possible, 627 should use whatever extensions the authorization server of choice 628 offers to signal that the requested access tokens will not be used by 629 a confidential client. As there are no standards to express in an 630 access token the nature of the client authentication used in 631 obtaining the token itself, this document does not provide a specific 632 mechanism to influence the authorization server and leaves the task, 633 in the rare cases it might be necessary, to individual 634 implementations. 636 6.3. Mismatch between scopes in a request vs cached tokens 638 The backend will likely cache token responses from the authorization 639 server, so that the backend can promptly serve equivalent requests 640 from the frontend without further roundtrips toward the authorization 641 server. That is a powerful optimization, but it presents scopes 642 elevation risks if applied indiscriminately. If the token cached by 643 the authorization server features a superset of the scopes requested 644 by the frontend, the backend SHOULD NOT return it to the frontend and 645 perform a new request with the smaller scopes set to the 646 authorization server. 648 6.4. Resource server colocated with the backend 650 If the only API invoked by the frontend happens to be colocated with 651 the backend, the frontend doesn't need to obtain access tokens to it: 652 it can simply use the same secure session leveraged to protect 653 requests to the token endpoints described here. The "bff-token" 654 isn't necessary in that scenario, although "bff-sessioninfo" retains 655 its usefulness to surface session and user information to the user 656 agent code. Also note that the presence of the "bff-token" endpoint 657 makes it possible to easily accommodate possible future evolutions 658 where the frontend needs to invoke APIs protected by resource servers 659 hosted elsewhere, without engendering changes in the security 660 property of the application. Developers choosing to expose API 662 7. IANA Considerations 664 This specification requests registration of the following two well- 665 known URIs in the IANA "Well-Known URIs" registry [IANA.well-known] 666 established by [RFC5785]. 668 The bff-token Endpoint 670 * URI suffix: bff-token 672 * Change Controller: IESG 674 * Specification Document: Section 3.1 [[ of this specification ]] 676 * Related information: (none) 678 The bff-sessioninfo Endpoint 680 * URI suffix: bff-sessioninfo 682 * Change Controller: IESG 684 * Specification Document: Section 3.2 [[ of this specification ]] 686 * Related information: (none) 688 # Miscellaneous 690 [[ TODO Should we say something about: Requests could be more 691 complicated than just scopes (think RAR) and the frontend might need 692 to tell more than scopes to the backend. In that case, just add 693 custom params and stir. ]] 695 [[ TODO We mentioned another thing, but I can't remember now. ]] 697 8. Normative References 699 [RFC5785] Nottingham, M. and E. Hammer-Lahav, "Defining Well-Known 700 Uniform Resource Identifiers (URIs)", RFC 5785, 701 DOI 10.17487/RFC5785, April 2010, 702 . 704 [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", 705 RFC 6749, DOI 10.17487/RFC6749, October 2012, 706 . 708 [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 709 Interchange Format", STD 90, RFC 8259, 710 DOI 10.17487/RFC8259, December 2017, 711 . 713 [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization 714 Framework: Bearer Token Usage", RFC 6750, 715 DOI 10.17487/RFC6750, October 2012, 716 . 718 9. Informative References 720 [BrowserBCP] 721 Parecki, A. and D. Waite, "OAuth 2.0 for Browser-Based 722 Apps", 5 April 2021, . 725 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 726 Requirement Levels", BCP 14, RFC 2119, 727 DOI 10.17487/RFC2119, March 1997, 728 . 730 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 731 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 732 May 2017, . 734 [RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265, 735 DOI 10.17487/RFC6265, April 2011, 736 . 738 [RFC8707] Campbell, B., Bradley, J., and H. Tschofenig, "Resource 739 Indicators for OAuth 2.0", RFC 8707, DOI 10.17487/RFC8707, 740 February 2020, . 742 [I-D.ietf-oauth-security-topics] 743 Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, 744 "OAuth 2.0 Security Best Current Practice", Work in 745 Progress, Internet-Draft, draft-ietf-oauth-security- 746 topics-16, 5 October 2020, . 749 [OIDC] Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and 750 C. Mortimore, "OpenID Connect Core 1.0 incorporating 751 errata set 1", 8 November 2014, 752 . 754 [I-D.ietf-httpbis-rfc6265bis] 755 West, M. and J. Wilander, "Cookies: HTTP State Management 756 Mechanism", Work in Progress, Internet-Draft, draft-ietf- 757 httpbis-rfc6265bis-07, 7 December 2020, 758 . 761 [I-D.ietf-oauth-v2-1] 762 Hardt, D., Parecki, A., and T. Lodderstedt, "The OAuth 2.1 763 Authorization Framework", Work in Progress, Internet- 764 Draft, draft-ietf-oauth-v2-1-00, 30 July 2020, 765 . 767 [RFC7636] Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key 768 for Code Exchange by OAuth Public Clients", RFC 7636, 769 DOI 10.17487/RFC7636, September 2015, 770 . 772 [Post-Spectre-Web-Dev] 773 West, M., "Post-Spectre Web Development (work in 774 progress)", 16 March 2021, . 777 [IANA.well-known] 778 IANA, "Well-Known URIs", 779 . 781 Appendix A. Acknowledgements 783 I wanted to thank the Academy, the viewers at home, etc.. 785 Appendix B. Document History 787 [[ To be removed from the final specification ]] 789 -01 791 * Added some protections/discussions around CSRF and cross-site 792 reading of sensitive data. 794 -00 796 * Literally willed into existence by a long haired gentleman from 797 the Seattle area 799 Authors' Addresses 801 Vittorio Bertocci 802 auth0.com 804 Email: vittorio@auth0.com 806 Brian Campbell 807 Ping Identity 809 Email: bcampbell@pingidentity.com