Web Authorization Protocol Y. Zehavi Internet-Draft H. Kroll Intended status: Standards Track G. Hyseni Expires: 10 November 2025 Raiffeisen Bank International 9 May 2025 OAuth 2.0 App2App Browserless Flow draft-zehavi-oauth-app2app-browserless-01 Abstract This document describes a protocol enabling native apps from different app publishers, using the App2App pattern to act as OAuth Client And Authorization Server, native browser-less user navigation. The native experience is also retained when the Client uses any number of brokers to federate across trust networks, while retaining highest levels of security. About This Document This note is to be removed before publishing as an RFC. The latest revision of this draft can be found at https://yaron- zehavi.github.io/oauth-app2app-browserless/draft-zehavi-oauth- app2app-browserless.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-zehavi-oauth- app2app-browserless/. Discussion of this document takes place on the Web Authorization Protocol Working Group mailing list (mailto:oauth@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/oauth/. Subscribe at https://www.ietf.org/mailman/listinfo/oauth/. Source for this draft and an issue tracker can be found at https://github.com/yaron-zehavi/oauth-app2app-browserless. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Zehavi, et al. Expires 10 November 2025 [Page 1] Internet-Draft Native OAuth App2App May 2025 Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 10 November 2025. Copyright Notice Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1. Difference from OpenID.Native-SSO . . . . . . . . . . . . 3 1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 3 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 4 3. Challenge of App2App with Brokers . . . . . . . . . . . . . . 4 3.1. App2App with brokers requires a web browser . . . . . . . 4 3.2. Impact of using a web browser . . . . . . . . . . . . . . 5 4. App2Web . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5. Browser-less App2App with Brokers . . . . . . . . . . . . . . 6 5.1. Flow Diagram . . . . . . . . . . . . . . . . . . . . . . 6 5.2. Protocol Flow . . . . . . . . . . . . . . . . . . . . . . 8 5.2.1. Client App calls Primary Broker . . . . . . . . . . . 8 5.2.2. Primary Broker returns authorization request to Downstream Authorization Server . . . . . . . . . . . 8 5.2.3. Client App traverses Brokers with request . . . . . . 8 5.2.4. Processing by User-Interacting Authorization Server: . . . . . . . . . . . . . . . . . . . . . . . 9 5.2.5. Client App traverses Brokers in reverse order . . . . 10 5.2.6. Client App obtains response . . . . . . . . . . . . . 11 6. Detecting Presence of Native Apps Owning Urls . . . . . . . . 11 6.1. Android . . . . . . . . . . . . . . . . . . . . . . . . . 11 6.2. iOS . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 7. Security Considerations . . . . . . . . . . . . . . . . . . . 11 7.1. OAuth request forgery and manipulation . . . . . . . . . 11 7.2. Secure Native application communication . . . . . . . . . 11 Zehavi, et al. Expires 10 November 2025 [Page 2] Internet-Draft Native OAuth App2App May 2025 7.3. Deep link hijacking . . . . . . . . . . . . . . . . . . . 12 7.4. Open redirection . . . . . . . . . . . . . . . . . . . . 12 7.5. Authorization code theft and injection . . . . . . . . . 12 7.6. Handling of Cookies . . . . . . . . . . . . . . . . . . . 12 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 12 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 12 9.1. Normative References . . . . . . . . . . . . . . . . . . 12 9.2. Informative References . . . . . . . . . . . . . . . . . 13 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 14 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 14 1. Introduction This document, OAuth 2.0 App2App Browserless Flow (Native App2App), discusses the [App2App] pattern where two applications act as OAuth Client and Authorization Server respectively, to natively authenticate and authorize an end-user. It addresses the challenges introduced when a web browser is involved in OAuth flows through one or more Brokering Authorization Servers, which are needed because Client App is not an OAuth client of the User-Interacting Authorization Server. Since no app owns OAuth Brokers' urls, App2App flows involving brokers require using a web browser, which degrades the user experience. This document presents a protocol enabling native App2App *browser- less* navigation, through any number of brokers, without compromising on any security property. 1.1. Difference from [OpenID.Native-SSO] [OpenID.Native-SSO] also offers a native SSO flow across applications without requiring the browser. However, it is dealing with the specific sub-case when both apps are published by the same issuer and leverage this fact to share information. 1.2. Terminology In addition to the terms defined in referenced specifications, this document uses the following terms: "OAuth": In this document, "OAuth" refers to OAuth 2.0, [RFC6749] and [RFC6750] as well as [OpenID], both in their *authorization code flow*. "PKCE": Proof Key for Code Exchange (PKCE) [RFC7636], a mechanism to Zehavi, et al. Expires 10 November 2025 [Page 3] Internet-Draft Native OAuth App2App May 2025 prevent various attacks on OAuth authorization codes. "OAuth Broker": A component acting as an Authorization Server for its clients, as well as an OAuth Client towards Downstream Authorization Servers. Brokers are used to facilitate a trust relationship when there is no direct relation between an OAuth Client and the final Authorization Server where end-user authenticates and authorizes. Brokers are an established pattern for establishing trust in federation use cases, such as in Academia and in the business world across corporations. Brokers may be replaced in the future with dynamic trust establishment leveraging [OpenID.Federation]. "Client App": Native app implementing [RFC8252] as OAuth client of Primary Broker, and whose redirect_uri is claimed as a deep link. "Primary Broker": An OAuth Broker serving as Authorization Server of Client App. And also an OAuth client of a Downstream Authorization Server. Primary Broker performs additional handling for App2App use-case, covered in Section 5.2. "Downstream Authorization Server": An Authorization Server which may be a _Secondary Broker_ or a _User-Interacting Authorization Server_. "Secondary Broker": A Broker redirecting the flow, which does not perform user authentication and authorization. "User-Interacting Authorization Server": The Authorization Server which interacts with end-user to perform authentication and authorization. May or may not offer App2App via a native app claiming it's urls as deep links. Such app may or may not be installed on end-user's device. 2. Conventions and Definitions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. 3. Challenge of App2App with Brokers 3.1. App2App with brokers requires a web browser Zehavi, et al. Expires 10 November 2025 [Page 4] Internet-Draft Native OAuth App2App May 2025 +------------------------------------------------------------------------------------+ | | | +--------------+ | | | | Mobile Browser | | | Client App | +--------------------------------------------------------+ | | | | | | | | +--------------+ | +---------+ +--------+ +-----------------+ | | | | | | | | | | | | | | +---------->| Primary |------>| |------>| User- | | | | Authorization | | Broker | Auth. | | Auth. | Authenticating | | | | Request | +---------+ Req. +--------+ Req. | Authorization | | | | | Secondary | Server | | | | +--------------+ | Brokers +-----------------+ | | | | | | | | | | | User- | +--------------------------------------------|-----------+ | | |Authenticating| | | | | App |<-------------------------------------------------+ | | +--------------+ Deep Link | +------------------------------------------------------------------------------------+ Mobile Device Figure 1: App2App with brokers and browser Since OAuth Brokers reside on web domains which no native app claims as Deep Links, OAuth requests to Brokers and responses to Broker's redirect_uri will be handled by a web browser. 3.2. Impact of using a web browser Using a web browser downgrades the user experience in several ways. The browser may be noticed by end-user as it is loading urls and redirecting to native apps. The browser may prompt end-user for consent before opening deep links, introducing additional friction. App developers have limited control as to which browser will be opened on the return redirect to the Broker, so any cookies used to bind session identifiers (nonce, state or PKCE verifier) to the user agent may be lost, causing the flow to break. Finally, the browser may be left after the flow ends with "orphan" browser tabs used for redirection. While these do not impact the process directly, they can be seen as clutter which degrades the overall UX's cleanliness. 4. App2Web Zehavi, et al. Expires 10 November 2025 [Page 5] Internet-Draft Native OAuth App2App May 2025 +--------------------------------------------------------------------------------+ | | | +-----------+ | | | | | | | Client | Mobile Browser | | | App | +--------------------------------------------------------------+ | | | | | | | | +-----------+ | +---------+ +----------+ +--------------------+ | | | | | | | | | | | | | | +------>| Primary |------>|Secondary |------>| User- | | | | Authorization| | Broker | Auth. | Brokers | Auth. | Authenticating | | | | Request | +---------+ Req. +----------+ Req. | Authorization | | | | | | Server | | | | | +-+----------------+-+ | | | | | User- | | | | | | Authenticating | | | | | | Web UI | | | | | +----------------+ | | | +--------------------------------------------------------------+ | +--------------------------------------------------------------------------------+ Mobile Device Figure 2: App2Web with brokers When the user's device does not have an app owning the User- Authenticating Authorization Server's urls as deep links, the flow requires the help of a browser. This is the case when the User-Authenticating Authorization Server offers no native app, or when such an app exists but is not installed on the end-user's device. This is similar to the flow described in [RFC8252], and referred to in [App2App] as *App2Web*. 5. Browser-less App2App with Brokers 5.1. Flow Diagram Zehavi, et al. Expires 10 November 2025 [Page 6] Internet-Draft Native OAuth App2App May 2025 +----------------------------------------------+ | (8) +-----------+ | | +---------------->| | | | | | | | | +--------------+ (1) | Primary | | | | Client |------------->| Broker | | | | App |<-------------| | | | | | (2) +-----------+ | | +--------------+ | | ^ | ^ ^ | | | | | | (3) +-----------+ | | | | | +---------------->| | | | | | +------------------>| Secondary | | | | | (7) | Brokers | | | | | | | | |(6)| |(4) +-----------+ | | | v | | +----------------+ | | | User- | | | | Authenticating | (5) | | | App | | | +----------------+ | +----------------------------------------------+ Mobile Device Figure 3: Browser-less App2App with Brokers * (1) Client App uses HTTP to call Primary Broker's authorization endpoint with an authorization request including _app2app_ scope. * (2) Primary Broker prepares authorization request for Downstream Authorization Server including scope app2app:_client_app_deep_link_ * (3) Client App loops through Brokers, natively calling their authorization endpoint over HTTP using previously obtained authorization request urls, and processing their HTTP 3xx redirect directives, until a deep link owned by an app on the device is reached. * (4) Client App natively invokes User-Authenticating App via its deep link. * (5) User-Authenticating App authenticates user and authorizes the request. It identifies app2app mode and uses client_app_deep_link to override the request's redirect_uri. Zehavi, et al. Expires 10 November 2025 [Page 7] Internet-Draft Native OAuth App2App May 2025 * (6) User-Authenticating App natively invokes Client App using client_app_deep_link, handing it redirect_uri response. * (7) Client App loops through Brokers, starting from the redirect_uri it received from User-Authenticating App. It natively calls them using HTTP traversing through their redirect directives, until Primary Broker redirects to Client App's own deep link. * (8) Client App exchanges code for tokens. 5.2. Protocol Flow 5.2.1. Client App calls Primary Broker Client App calls Primary Broker's authorization_endpoint to initiate an authorization code flow, it SHALL indicate App2App flow using the dedicated scope app2app. Client App's redirect_uri SHALL be claimed as a deep link and will be referred to as _client_app_deep_link_. 5.2.2. Primary Broker returns authorization request to Downstream Authorization Server * Primary Broker SHALL validate Client's request and prepare an authorization request to Downstream Authorization Server's authorization_endpoint. * Primary Broker SHALL provide _client_app_deep_link_ to Downstream Authorization Server as a suffix to the dedicated scope app2app. The combined scope is: app2app:*client_app_deep_link*. * Primary Broker SHALL respond with HTTP 302 with the authorization request url towards Downstream Authorization Server in the Location header. 5.2.3. Client App traverses Brokers with request Client App SHALL use OS mechanisms to detect if the authorization request URL it received is handled by an app installed on the device. If so, Client App SHALL natively invoke the app claiming the url to process the authorization request. This achieves native navigation across applications. If an app handling the authorization request URL is not found, Client App SHALL natively call the authorization request URL using HTTP GET and processe the response: Zehavi, et al. Expires 10 November 2025 [Page 8] Internet-Draft Native OAuth App2App May 2025 * If the response is successful (HTTP Code 2xx), it is assumed to be the User-Interacting Authorization Server. This means the Client App "over-stepped" and MUST downgrade to App2Web. * If the response is a redirect instruction (HTTP Code 3xx + Location header), a Secondary Broker was reached and Client App SHALL repeat the logic previously described: - Check if an app owns the obtained url, and if so natively invoke it. - Otherwise natively call the obtained url and analyze the response. * Handle error response (HTTP 4xx / 5xx) for example by displaying the error. As the Client App traverses through Brokers, it SHALL maintain a list of all the domains it traverses, which serves later as the Allowlist when traversing the response. 5.2.3.1. Secondary Brokers Secondary Brokers engaged in the journey MUST retain structured scope app2app:*client_app_deep_link* in downstream authorization requests they create. 5.2.3.2. Downgrade to App2Web If Client App reaches a User-Interacting Authorization Server with no app handling its urls, it may be impossible to relaunch the last authorization request URL on the browser as it might have included a single use request_uri which by now has been used and is therefore invalid. In such a case the Client App MUST start over, generating a new authorization request without App2App indication, which is then launched on the browser. The remaining flow follows [RFC8252] and is therefore not further elaborated in this document. 5.2.4. Processing by User-Interacting Authorization Server: The User-Interacting Authorization Server SHALL handle the authorization request using its native app: * Native app authenticates end user and authorizes the request. Zehavi, et al. Expires 10 November 2025 [Page 9] Internet-Draft Native OAuth App2App May 2025 * The _client_app_deep_link_ provided in the strcutured scope, SHALL override the request's original redirect_uri: - User-Interacting Authorization Server's native app SHALL validate that an app owning _client_app_deep_link_ is on the device - If so it SHALL natively invoke it, handing it the redirect url with its response parameters - If such an app does not exist it is an error and the flow SHALL terminate * To establish trust towards client_app_deep_link, User-Interacting Authorization Server MAY use mechanisms outside the scope of this document, or OpenID Federation: - SHALL strip url path from _client_app_deep_link_ (retaining the domain). - SHALL add url path /.well-known/openid-federation and perform trust chain resolution. - SHALL inspect Client's metadata for redirect_uri's and validate _client_app_deep_link_ is included. 5.2.5. Client App traverses Brokers in reverse order Client App is natively invoked by User-Interacting Authorization Server App, with the request's redirect_uri. Client App MUST validate this url, and any url subsequently obtained through a 3xx redirect instruction from the brokers it traverses, against the Allowlist generated for this flow, and MUST fail if any url is not included in the Allowlist. Client App SHALL invoke the url it received using HTTP GET: * If the response is a redirect instruction (HTTP Code 3xx + Location header), Client App SHALL repeat the logic and proceed to call obtained urls until reaching its own redirect_uri (_client_app_deep_link_). * SHALL handle any other HTTP code (2xx / 4xx / 5xx) as a failure. Zehavi, et al. Expires 10 November 2025 [Page 10] Internet-Draft Native OAuth App2App May 2025 5.2.6. Client App obtains response Once Client App's own redirect_uri is returned in a redirect 3xx directive, the traversal is complete. Client App SHALL proceed according to OAuth to exchange code for tokens, or handle error responses. 6. Detecting Presence of Native Apps Owning Urls Native Apps on iOS and Android MAY use OS SDK's to detect if an app owns a url. The general method is the same - App calls an SDK to open the url as deep link and handles an exception thrown if no matching app is found. 6.1. Android App SHALL invoke Android [android.method.intent] method with FLAG_ACTIVITY_REQUIRE_NON_BROWSER, which throws ActivityNotFoundException if no matching app is found. 6.2. iOS App SHALL invoke iOS [iOS.method.openUrl] method with options [iOS.option.universalLinksOnly] which ensures URLs must be universal links and have an app configured to open them. Otherwise the method returns false in completion.success 7. Security Considerations 7.1. OAuth request forgery and manipulation It is RECOMMENDED Client App acts as a confidential OAuth client. 7.2. Secure Native application communication If Client App uses a Backend it is RECOMMENDED to communicate with it securely: * Use TLS in up to date versions and ciphers. * Use DNSSEC. * Perform certificate pinning. Zehavi, et al. Expires 10 November 2025 [Page 11] Internet-Draft Native OAuth App2App May 2025 7.3. Deep link hijacking It is RECOMMENDED that all apps in this specification shall protect their deep links using Android universal links / iOS App Links including the most specific package identifiers to prevent deep link hijacking by malicious apps. 7.4. Open redirection Client App SHALL construct an Allowlist of domains it traverses through while processing the request, used to enforce all urls it later traverses through during response processing. This mitigates open redirection attacks as urls outside of this Allowlist will be rejected. In addition Client App MUST ignore any invocation for response processing which is not in the context of a request it initiated. It is RECOMMENDED the Allowlist is managed as a single-use object and destructed after each protocol flow ends. It is RECOMMENDED Client App allows only one OAuth request processing at a time. 7.5. Authorization code theft and injection It is RECOMMENDED that PKCE is used and that the code_verifier is tied to the Client App instance. 7.6. Handling of Cookies It can be assumed that Authorization Servers will use Cookies to bind security elements (state, nonce, PKCE) to the user agent, and will break if these cookies are later missing. Therefore, Client App MUST handle Cookies as a web browser would: * SHALL store cookies it obtains on HTTP responses. * SHALL send cookies on subsequent HTTP requests to servers that returned cookies. 8. IANA Considerations This document has no IANA actions. 9. References 9.1. Normative References Zehavi, et al. Expires 10 November 2025 [Page 12] Internet-Draft Native OAuth App2App May 2025 [OpenID] Sakimura, N., Bradley, J., Jones, M. B., de Medeiros, B., and C. Mortimore, "OpenID Connect Core 1.0", November 2014, . [OpenID.Federation] Hedberg, Ed, R., Jones, M. B., Solberg, A. A., Bradley, J., De Marco, G., and V. Dzhuvinov, "OpenID Federation 1.0", March 2025, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, October 2012, . [RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization Framework: Bearer Token Usage", RFC 6750, DOI 10.17487/RFC6750, October 2012, . [RFC7636] Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key for Code Exchange by OAuth Public Clients", RFC 7636, DOI 10.17487/RFC7636, September 2015, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8252] Denniss, W. and J. Bradley, "OAuth 2.0 for Native Apps", BCP 212, RFC 8252, DOI 10.17487/RFC8252, October 2017, . [RFC9126] Lodderstedt, T., Campbell, B., Sakimura, N., Tonge, D., and F. Skokan, "OAuth 2.0 Pushed Authorization Requests", RFC 9126, DOI 10.17487/RFC9126, September 2021, . 9.2. Informative References Zehavi, et al. Expires 10 November 2025 [Page 13] Internet-Draft Native OAuth App2App May 2025 [android.method.intent] "Android Intent Method", n.d., . [App2App] Heenan, J., "Guest Blog: Implementing App-to-App Authorisation in OAuth2/OpenID Connect", October 2019, . [iOS.method.openUrl] "iOS open(_:options:completionHandler:) Method", n.d., . [iOS.option.universalLinksOnly] "iOS method property universalLinksOnly", n.d., . [OpenID.Native-SSO] Fletcher, G., "OpenID Connect Native SSO for Mobile Apps", November 2022, . Acknowledgments The authors would like to thank the attendees of the OAuth Security Workshop 2025 session in which this was discussed, as well as the following individuals who contributed ideas, feedback, and wording that shaped and formed the final specification: Authors' Addresses Yaron Zehavi Raiffeisen Bank International Email: yaron.zehavi@rbinternational.com Henrik Kroll Raiffeisen Bank International Email: henrik.kroll@rbinternational.com Grese Hyseni Raiffeisen Bank International Email: grese.hyseni@rbinternational.com Zehavi, et al. Expires 10 November 2025 [Page 14]