Internet-Draft | Native OAuth App2App | August 2025 |
Zehavi | Expires 10 February 2026 | [Page] |
This document describes a protocol allowing a Client App to obtain an OAuth grant from an Authorization Server's Native App using the [App2App] pattern, providing native app navigation user-experience (no web browser used), despite both apps belonging to different trust domains.¶
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.¶
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/.¶
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 February 2026.¶
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.¶
This document describes a protocol enabling native (Browser-less) app navigation of an [App2App] OAuth grant across different Trust Domains.¶
When Clients and Authorization Servers are located on different Trust Domains, authorization requests traverse across domains using federation, involving Authorization Servers acting as clients of Downstream Authorization Servers.¶
Such federation setups create trust networks, for example in Academia and in the business world across corporations.¶
However in [App2App] scenarios the web browser must serve as user-agent, because federating Authorization Servers url's are not claimed by any native app.¶
The use of web browsers in App2App flows degrades the user experience somewhat.¶
This document specifies:¶
A new Authorization Server endpoint and corresponding metadata property REQUIRED to support the browser-less App2App flow.¶
A new native authorization request parameter, specifying the deep link of Client App.¶
A new error code value.¶
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.¶
In addition to the terms defined in referenced specifications, this document uses the following terms:¶
In this document, "OAuth" refers to OAuth 2.0, [RFC6749] in the authorization code flow.¶
An Authorization Server federating to other trust domains by acting as an OAuth Client of Downstream Authorization Servers.¶
A Native app OAuth client of Authorization Server. In accordance with "OAuth 2.0 for Native Apps" [RFC8252], client's redirect_uri is claimed by the app.¶
An Authorization Server downstream of another Authorization Server. It may be an OAuth Broker or the User-Interacting Authorization Server.¶
An Authorization Server which interacts with end-user. The interaction may be interim navigation (e.g: user input is required to guide where to redirect), or performs user authentication and request authorization.¶
Native App of User-Interacting Authorization Server.¶
A url claimed by a native application.¶
(1) Client App presents an authorization request to Authorization Server's native_authorization_endpoint, including a native_callback_uri.¶
(2) Authorization Server returns either:¶
(3) Client App:¶
Calls native authorization request urls it obtains, so long as such responses are obtained, until a deep link url to User-Interacting App is obtained.¶
Handles requests for end-user input by prompting end-user and providing their input to Authorization Server.¶
Handles deep links, by invoking the app claiming the url, if present on the device.¶
(4) Once a deep link claimed on the device is obtained, Client App natively invokes User-Interacting App.¶
(5) User-Interacting App authenticates end-user and authorizes the request.¶
(6) User-Interacting App returns to Client App by natively invoking native_callback_uri and provides as a parameter the url-encoded redirect_uri with its response parameters.¶
(7) Client App invokes the redirect_uri it obtained.¶
(8) Client App calls any subsequent uris obtained until its own redirect_uri is obtained.¶
(9) Client App exchanges code for tokens and the flow is complete.¶
Client App is natively invoked by User-Interacting Authorization Server App.¶
If it is invoked with an error (and optional error_description) parmeter, or no parameter at all, it MUST terminate the flow. It MUST ignore any unknown parameters.¶
If invoked with a url-encoded redirect_uri as parameter, the Client App MUST validate redirect_uri, and any url subsequently obtained, using the Allowlist it previously generated, and MUST terminate the flow if any url is not found in the Allowlist.¶
Client App SHALL invoke redirect_uri, and any validated subsequent urls received using HTTP GET.¶
Authorization Servers processing Native App2App MUST respond to redirect_uri invocations:¶
According to the REST API guidelines specified in Section 3.3.¶
Returning a JSON body instructing the next url to call.¶
Example:¶
HTTP/1.1 200 OK Content-Type: application/json { "action": "call", "url": "redirect_uri of an OAuth Client, including response parameters", }¶
Client App MUST handle any other response (2xx with other content-types / 3xx / 4xx / 5xx) as a failure and terminate the flow.¶
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.¶
App SHALL invoke Android [android.method.intent] method with FLAG_ACTIVITY_REQUIRE_NON_BROWSER, which throws ActivityNotFoundException if no matching app is found.¶
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.¶
The Native App2App flow described in this document MAY fail when:¶
An error response is obtained.¶
Required User-Interacting App is not installed on end-user's device.¶
Client App MAY recover by launching a new (non-native) authorization request on a web browser, in accordance with "OAuth 2.0 for Native Apps" [RFC8252].¶
Note - Failure because User-Interacting App is not installed on end-user's device, might succeed in future, if the missing app has been installed. Client App MAY choose if and when to retry the Native App2App flow after such a failure.¶
[RFC8252] Security Considerations advises against using embedded user agents. The main concern is preventing theft through keystroke recording of end-user's credentials such as usernames and passwords.¶
This risk does not apply to this draft as Client App acts as User Agent only for the purpose of flow redirection, and does not interact with end-user's credentials in any way.¶
The mechanism for providing routing instructions MUST NOT be used to request end-user to provide any authentication credentials.¶
Client App SHALL construct an Allowlist of DNS domains it traverses while processing the request, used to enforce all urls it later traverses during response processing. This mitigates open redirection attacks as urls not in this Allowlist SHALL 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 be managed as a single-use object, destructed after each protocol flow ends.¶
It is RECOMMENDED Client App allows only one OAuth request processing at a time.¶
It is RECOMMENDED that all apps in this specification shall use https-scheme deep links (Android App Links / iOS universal links). Apps SHOULD implement the most specific package identifiers mitigating deep link hijacking by malicious apps.¶
Since no native app claims the urls of redirecting Authorization Servers (OAuth Brokers), mobile Operating Systems default to using the system browser as the User Agent.¶
Using a web browser may degrade the user experience in several ways:¶
Some browser's support for deep links is limited by design, or by the settings used.¶
Browsers may prompt end-user for consent before opening apps claiming deep links, introducing additional friction.¶
Browsers are noticeable by end-users, rendering the UX less smooth.¶
Client app developers don't control which browser the User-Interacting App uses to provide its response to redirect_uri. Opinionated choices pose a risk that different browsers will use, making necessary cookies used to bind session identifiers to the user agent (nonce, state or PKCE verifier) unavailable, which may break the flow.¶
After flow completion, "orphan" browser tabs may remain. They do not directly impact the flow, but can be regarded as unnecessary "clutter".¶
[OpenID.Native-SSO] also offers a native SSO flow across apps. However, it is limited to apps:¶
[OAuth.First-Party] also deals with native apps, but it MUST only be used by first-party applications, which is when the authorization server and application are controlled by the same entity, which is not true in the case described in this document.¶
While this document also discusses a mechanism for Authorization Servers to guide Client App in obtaining user's input to guide routing the request across trust domains, the [OAuth.First-Party] required high degree of trust between the authorization server and the client is not fulfilled.¶
This document has no IANA actions.¶
The authors would like to thank the following individuals who contributed ideas, feedback, and wording that shaped and formed the final specification: George Fletcher, Arndt Schwenkschuster, Henrik Kroll, Grese Hyseni. As well as the attendees of the OAuth Security Workshop 2025 session in which this topic was discussed for their ideas and feedback.¶
[[ To be removed from the final specification ]]¶
-latest * Replaced Authorization Details Type with new parameter * native_authorization_endpoint as REST API - no cookies or HTTP 30x responses¶
-05 * removed error native_callback_uri_not_claimed * Added Routing Instructions Response * Added native_authorization_endpoint and matching AS profile * Added Authorization Details Type as container for native_callback_uri¶
-04¶
Phrased the challenge in Trust Domain terminology¶
Discussed interim Authorization Server interacting the end-user, which is not the User-Authenticating Authorization Server¶
Moved Cookies topic to Protocol Flow¶
Mentioned that Authorization Servers redirecting not through HTTP 30x force the use of a browser¶
Discussed Embedded user agents security consideration¶
-03¶
-02¶
-01¶
-00¶
initial working group version (previously draft-zehavi-oauth-app2app-browserless)¶