Internet-Draft OAuth Public September 2026
Jenkins & Bucksch Expires 20 March 2027 [Page]
Workgroup:
Mail Maintenance
Internet-Draft:
draft-ietf-mailmaint-oauth-public-06
Published:
Intended Status:
Informational
Expires:
Authors:
N.M. Jenkins, Ed.
Fastmail
B. Bucksch
Beonex

OAuth Profile for Open Public Clients

Abstract

This document specifies a profile of the OAuth authorization protocol to allow for interoperability between native clients and servers using open protocols, such as JMAP, IMAP, SMTP, POP, CalDAV, and CardDAV. The profile is restricted to native clients, that is, applications installed and run on the end user's device. It deliberately does not support web-based clients, which cannot complete the flow as specified.

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/.

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 20 March 2027.

Table of Contents

1. Introduction

This document pulls together several existing standards and uses them to specify a specific OAuth profile, allowing interoperable modern authentication for native clients of open protocols, such as JMAP, IMAP, SMTP, POP, CalDAV, and CardDAV. For these protocols, there are many servers and many clients with no pre-existing relationship, that need to be able to connect. At the moment, the only interoperable way to do so is with a basic username and password, which has many deficiencies from a security standpoint.

1.1. Applicability to Native Clients Only

This profile applies only to native clients: applications that are installed and executed on the end user's device, as described in [RFC8252]. Web-based clients, that is, clients that run in a web browser or on a web server, are out of scope for this document.

This restriction is deliberate. The profile allows any client to register with any server without a pre-existing relationship (see Section 3.3), and there is no way for the server to verify any of the information supplied during that registration. For a native client, this does not introduce a new risk: a malicious application that the user has already installed and run could spoof the user's browser to phish their credentials, or install malware in unsandboxed environments, so allowing it to complete an OAuth flow makes the user no worse off. Indeed, it is more secure, as the alternative is a legitimate client storing the user's password.

Just navigating to a web page, however, is a different security scenario. Allowing arbitrary web-based clients to seamlessly register and obtain authorization would make it substantially easier for phishing sites to gain access to a user's account, by sending the user through a legitimate OAuth flow at the real authorization server and then receiving the resulting tokens.

The profile therefore enforces this restriction by limiting the redirect URIs that may be registered to loopback addresses and private-use URI schemes, which can only be received by software running on the user's device. See Section 3.3 for the specific requirements and Section 4 for further discussion.

1.2. Presumptions

This profile presumes a deployment has a set of one or more resource server endpoints (e.g., for JMAP/IMAP/SMTP/POP/CardDAV/CalDAV), and a common authorization server issuer identifier for all of them. For example, a deployment might have a JMAP session endpoint https://api.example.com/jmap/session, an IMAP endpoint imap.example.com, and an issuer identifier https://auth.example.com/acmeinc.

1.3. Getting the Authorization Server Issuer Identifier

The endpoints may be discovered via an autoconfiguration mechanism, such as [I-D.ietf-mailmaint-pacc], or via manual user input. Autoconfiguration may also include the issuer identifier. To allow OAuth configuration for manual input or when the issuer identifier is not included in the autoconfiguration data, HTTP endpoints that support this profile MUST support Protected Resource Metadata [RFC9728], accessible via the oauth-protected-resource well-known path, as specified in Section 3 of [RFC9728]. The authorization_servers property MUST be present in the resource metadata. Servers SHOULD list exactly one issuer identifier, that of the authorization server to be used with this profile; if more than one is listed, the client instance MUST use the first. HTTP requests made without valid authentication to the resource endpoints MUST indicate the protected resource metadata URL in the resource_metadata parameter of the WWW-Authenticate HTTP response header field, as described in Section 5.1 of [RFC9728].

A client instance that needs the issuer identifier for an HTTP endpoint SHOULD obtain the metadata URL by making a request to the endpoint without credentials and reading the resource_metadata parameter from the WWW-Authenticate header field of the response. This works for endpoints whose own path is a well-known path, such as https://caldav.example.com/.well-known/caldav, and for endpoints that redirect during service discovery, as is common for CalDAV and CardDAV: the client instance follows the redirects as it normally would and reads the header field from the final response. If the header field is absent, the client instance MAY instead construct the metadata URL from the endpoint URL as described in Section 3.1 of [RFC9728]. The client instance MUST NOT follow HTTP redirects when fetching the metadata document itself.

In either case, the client instance MUST validate the metadata as required by Section 3.3 of [RFC9728]: the resource property MUST be identical to the URL of the request that returned the WWW-Authenticate header field, or, for a constructed URL, to the endpoint URL into which the well-known path was inserted. If it is not, the metadata MUST NOT be used. This check ensures that a redirect or a misconfigured server cannot cause the client instance to use metadata that describes some other resource.

Protected Resource Metadata is only available for HTTP-based endpoints. For IMAP, POP, and SMTP, the equivalent in-protocol mechanism is the openid-configuration field of the OAUTHBEARER failed-authentication response (Section 3.2.2 of [RFC7628]). Servers offering these protocols under this profile MUST include this field in every failed OAUTHBEARER response, with the URL of the authorization server metadata document (in either of the forms described in Section 3.2). A client instance that has not obtained the issuer identifier from autoconfiguration or the user MAY discover it by connecting to the endpoint over TLS, attempting OAUTHBEARER authentication with a syntactically valid but deliberately invalid token, and reading this field from the response. The client instance MUST then fetch the document at that URL (without following redirects, as in Section 3.2), take its issuer property as the issuer identifier, and proceed as described in that section from the issuer identifier alone, discarding the document it fetched. This ensures the metadata used is subject to every check in this document, regardless of the URL from which the field pointed. As with autoconfiguration data and protected resource metadata, the URL is supplied by a server that may itself be counterfeit, and the protections of Section 3.6 apply.

2. Notational Conventions

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. The Open Public Client OAuth Profile

3.1. Overview

OAuth 2 [RFC6749] can be used in many different ways. This document specifies one particular set of options to ensure interoperability and security. Servers may implement more options, but MUST support the flow as described in this document for interoperability with clients. Similarly, clients may choose to support additional flows but there is no guarantee that this will be interoperable.

The general flow works like this:

  1. The OAuth 2.0 Authorization Server Metadata [RFC8414] is fetched.
  2. The client instance registers with the authorization server to get a client id using the OAuth 2.0 Dynamic Client Registration Protocol [RFC7591].
  3. The client instance authorizes using the Authorization Code Grant flow (Section 4.1 of [RFC6749]) with PKCE [RFC7636] and Issuer Identification [RFC9207]. The client instance also includes Resource Indicators [RFC8707] in the authorization request. Server support for Resource Indicators is RECOMMENDED but not required: an authorization server that does not support them ignores the unrecognised parameters (as required by Section 3.1 of [RFC6749]) and the flow proceeds without them; the client instance then relies on the rules in Section 3.6 to decide which resource servers it may send access tokens to. The consequences of this are discussed in Section 3.4, Section 3.6, and Section 4.
  4. The client instance gets an access token and refresh token, as per Section 5 of [RFC6749].

The access token can now be used as a Bearer token to authenticate requests to the application servers as per [RFC6750] for HTTP requests, or [RFC7628] for SASL authentication. When it expires, a new one can be requested using the refresh token as per Section 6 of [RFC6749].

The rest of this document describes in detail each of the above steps.

3.2. Fetching the Authorization Server Metadata

The authorization server issuer identifier MUST be an HTTPS URL with no userinfo, query, or fragment component. If a path is present, it MUST NOT contain . or .. segments, and MUST NOT use percent-encoding for unreserved characters (as defined in Section 2.3 of [RFC3986]). If the issuer identifier does not conform to these requirements, the flow MUST be aborted. Note that https://auth.example.com and https://auth.example.com/ are both permitted, but they are distinct issuer identifiers: clients do not normalize one to the other, and the issuer metadata property (see below) must match exactly whichever form was used. The authorization server metadata MUST first be fetched as specified in Section 3 of [RFC8414] by constructing a URL that places /.well-known/oauth-authorization-server after the host and before any path. For example, for an issuer identifier of https://auth.example.com/acmeinc, the authorization server metadata would be fetched from https://auth.example.com/.well-known/oauth-authorization-server/acmeinc.

If this request does not result in a successful response (a 200 OK HTTP status code with an "application/json" content type), the client MUST also try the OpenID Connect Discovery [OpenID.Discovery] metadata path. This is constructed by appending /.well-known/openid-configuration to the issuer identifier after stripping any trailing slash. For example, for an issuer identifier of https://auth.example.com/acmeinc, this would be https://auth.example.com/acmeinc/.well-known/openid-configuration. This fallback is necessary for compatibility with existing deployments that only serve metadata at the OpenID Connect path. See Section 4 for a discussion of the security implications of this fallback.

A successful response is indicated by a 200 OK HTTP status code. The response MUST have an "application/json" content type. If neither metadata path results in a successful response, the flow MUST be aborted. Clients MUST NOT follow HTTP redirects when fetching the metadata; a redirect MUST be treated the same as an error response.

The authorization server metadata is a JSON document with properties as specified in [RFC8414]. It MUST include the following properties:

issuer

The authorization server's issuer identifier. This MUST be identical to the issuer identifier from which this metadata URL was derived — not the URL from which it was fetched. For example, if the issuer identifier is https://auth.example.com/acmeinc, the issuer property MUST be https://auth.example.com/acmeinc, regardless of whether the metadata was fetched from https://auth.example.com/.well-known/oauth-authorization-server/acmeinc or https://auth.example.com/acmeinc/.well-known/openid-configuration. If not, the flow MUST be aborted.

This MUST be verified again during the authorization flow (see Section 3.4, or [RFC9207] for more details), to protect against mix-up attacks.

registration_endpoint

The URL the client instance will use to register, to get a client id it needs for authorization (see Section 3.3).

authorization_endpoint

The URL the client instance will use to start the authorization process (see Section 3.4) once it has registered.

token_endpoint

The URL the client instance will use to get refresh and access tokens after successful authorization (see Section 3.5).

scopes_supported

An array of supported scopes on the server (see Section 3.9).

response_types_supported

A list of response types supported in the OAuth authorization flow. This is an array of strings that MUST include "code".

grant_types_supported

A list of the OAuth 2.0 grant type values that this authorization server supports. This is an array of strings that MUST include "authorization_code" and "refresh_token".

token_endpoint_auth_methods_supported

This is an array of strings that MUST include "none".

code_challenge_methods_supported

An array of strings listing Proof Key for Code Exchange (PKCE) [RFC7636] code challenge methods supported by this authorization server. This MUST include "S256".

authorization_response_iss_parameter_supported

This MUST have the boolean value true.

Servers MUST include the following property if any resource server accessed via this profile does not share the registrable domain of the issuer identifier (see Section 3.6), or if they require Resource Indicators [RFC8707] (that is, they will not issue a usable access token unless the authorization request includes resource parameters). All other servers that support Resource Indicators SHOULD include it:

protected_resources

A JSON array of strings, as defined in Section 4 of [RFC9728], listing all of the resource indicator values that may be used with this authorization server for resources accessed via this profile. Clients use this list to determine the resource values to send in the authorization request (see Section 3.4). For HTTP-based protocols, each entry is an https URL with no query or fragment part that identifies a resource server, or a path within one, for example https://api.example.com or https://caldav.example.com/dav. Entries are matched against resource URLs as described in Section 3.4. For non-HTTP protocols, each entry is a hostname with no scheme or port, for example imap.example.com. Section 4 of [RFC9728] defines the entries of this array as resource identifiers, which Section 1.2 of [RFC9728] restricts to https URLs; this profile deviates from that restriction for non-HTTP protocols, for the reasons given in Section 3.4.

[RFC9728] permits an authorization server to omit some of its protected resources from this list. This profile is stricter: if the property is present, it MUST be complete with respect to the resource endpoints that may be accessed using this profile, since a client can only send resource indicators for endpoints that it can match against the list.

The metadata MAY include other properties, or other values for multi-valued properties, however clients are not required to understand or use any of them for interoperability.

It is RECOMMENDED servers support DPoP ([RFC9449]) to allow sender-constrained refresh and access tokens for HTTP-based protocols. Servers that support DPoP MUST include the following property:

dpop_signing_alg_values_supported
A JSON array containing a list of the JWS alg values (from the [IANA.JOSE.ALGS] registry) supported by the authorization server for DPoP proof JWTs, as defined in [RFC9449], Section 5.1.

Also of possible interest to client/server implementers following this document:

revocation_endpoint
The URL the client instance can use to revoke their tokens, as per [RFC7009].
revocation_endpoint_auth_methods_supported
If a revocation_endpoint is included, this property MUST be included, and is an array of strings that MUST include "none".

Clients MUST verify the required properties are present and conform to the requirements of this document. Clients MUST also verify that the registration_endpoint, authorization_endpoint, token_endpoint, and, if present, revocation_endpoint are URLs with the https scheme, as the client instance will send authorization codes and refresh tokens to them; if any is not, the client MUST abort the flow. If the required properties are not present or do not conform, the server is not using OAuth in conformance with this document and no compatibility may be presumed. It is RECOMMENDED clients abort the flow in such a case.

3.3. Dynamic Client Registration

The client registration endpoint MUST accept registration requests that carry no initial access token or other form of authentication (open registration, see Section 3 of [RFC7591]), since a client instance following this profile has no pre-existing relationship with the server.

To register, the client instance sends an HTTP POST to the client registration endpoint (as found in the metadata) with a content type of "application/json", and a body consisting of a JSON document with the following properties:

redirect_uris

An array of URIs the client instance may use to receive back information at the end of the authorization flow. Each URI MUST satisfy all of these conditions:

  • The URI MUST start with one of the following:

    • http://127.0.0.1/
    • http://[::1]/
    • A private-use scheme in reverse domain notation, e.g., com.example:/. Such a scheme MUST have at least one dot in it.
  • The URI MUST NOT include two consecutive dots (e.g., /../).
  • The URI MUST NOT include a fragment part (#).

The URI may include a path and query parameters.

Claimed "https" scheme redirect URIs (Section 7.2 of [RFC8252]) are deliberately not permitted, even though they are otherwise the most secure option for native clients. An authorization server cannot distinguish a claimed https URI from an ordinary web URL, so permitting them would permit web-based clients to complete the flow. See Section 1.1 and Section 4.

token_endpoint_auth_method
This MUST be "none".
grant_types
This is an array of strings that MUST include "authorization_code" and "refresh_token".
response_types
This is an array of strings that MUST include "code".
scope

A string containing a space-separated list of scope values the client may request access for. (Note! This is not a JSON array.)

For compatibility with servers implementing OpenID Connect [OpenID.Core], if the server advertised the offline_access scope in the "scopes_supported" property of the authorization server metadata, the client instance MUST also register for this scope.

client_name
The name of the client software to be presented to the end-user during authorization.
client_uri
A URL for a web page providing information about the client software. This MUST use HTTPS.
logo_uri
A URL for a logo to display for this client software. This SHOULD be square, and in a PNG or SVG image format. This MUST use HTTPS.
tos_uri
A URL that points to a human-readable terms of service or license document for the client software. This MUST use HTTPS.
policy_uri
A URL that points to a human-readable privacy policy document for the client software. This MUST use HTTPS.
software_id
A unique identifier string (e.g., a Universally Unique Identifier (UUID)) assigned by the client developer or software publisher, used by registration endpoints to identify the client software doing the dynamic registration. Unlike "client_id", which is issued by the authorization server and may vary between instances, the "software_id" SHOULD remain the same for all instances of the client software. The "software_id" SHOULD remain the same across multiple updates or versions of the same piece of software. The value of this field is not intended to be human readable and is usually opaque to the client and authorization server.
software_version
A version identifier string for the client software identified by "software_id". The value of the "software_version" SHOULD change on any update to the client software identified by the same "software_id". The value of this field is intended to be compared using string equality matching and no other comparison semantics are defined by this specification.

If the server indicated in its metadata that it supports DPoP [RFC9449] and the client instance is intending to authenticate all requests using DPoP, the client instance SHOULD also include the following property:

dpop_bound_access_tokens
true

If set, the server MUST require every token request for the issued client id to include a DPoP proof, and MUST issue only DPoP-bound access tokens, as specified in Section 5.2 of [RFC9449]. DPoP is only defined for HTTP, so a client instance that uses non-HTTP protocols such as IMAP, POP, or SMTP MUST NOT set this property. See Section 3.8 for how such a client instance can still make use of DPoP.

The server will check that all required properties are present and have valid values. Any unknown properties supplied by the client instance MUST just be ignored. The authorization server MAY replace any of the client's requested metadata values submitted during the registration and substitute them with suitable values.

The client instance MUST use the values returned in the registration response (see below) in preference to those it requested, in particular for the redirect_uris, scope, and dpop_bound_access_tokens properties. If the returned redirect_uris or scope omit a value the client instance requires, it MUST abort the flow and inform the user. If the server has omitted dpop_bound_access_tokens or returned it as false, for example because it returns a static client id to all requests, the client instance MUST NOT assume that access tokens will be DPoP-bound and MUST check the token_type of each token response (see Section 3.8).

If there is an exact match for all properties except for software_version, an existing registration may be returned. Otherwise, servers SHOULD create a new registration and client id.

There is no way to verify the authenticity of the information supplied by the client, however the general case of accurate information is still useful to the server, for example to be able to contact client authors to help debug issues if aberrant behaviour is observed. Servers MAY choose to ignore all of the information instead and just return a static client id to all requests.

The redirect URI restrictions MUST be enforced: a registration request containing a redirect URI that does not satisfy them MUST be rejected with an invalid_redirect_uri error (Section 3.2.2 of [RFC7591]). These ensure the OAuth flow can only be completed by native clients — not web clients — as discussed in Section 1.1. Since a malicious native client could present the user with a custom browser to phish credentials anyway, the lack of verification of client registration details does not provide additional danger beyond existing threats. Allowing seamless dynamic registration for web-based clients, however, unfortunately makes it much easier for a phishing site to gain access to an account, by sending the user through the OAuth flow.

If successful, the server responds with an HTTP 201 Created status code and a body of type "application/json", with the content being a JSON object containing all the properties submitted during registration (with their values as set by the server, if overwritten), plus the following property:

client_id
The OAuth 2.0 client identifier string, used in the authorization flow (see Section 3.4).

Clients following this profile are public clients (see Section 2.1 of [RFC6749]): they register with a token_endpoint_auth_method of "none" and do not authenticate to the token endpoint, instead proving possession of the authorization code using PKCE. The server MUST NOT issue a client secret in the registration response, so the client_secret and client_secret_expires_at properties defined in Section 3.2.1 of [RFC7591] MUST NOT be present. A native client cannot keep a secret confidential, so a secret would offer no security benefit, and a client that expected to use one would not be interoperable with servers that correctly omit it. If a server nonetheless returns a client_secret, the client instance MUST ignore it and continue as a public client.

If the registration fails, the server will respond with an HTTP 400 status code and a JSON body as described in [RFC7591], section 3.2.2.

3.4. Authorization

Clients construct an authorization request URL by taking the authorization_endpoint from the authorization server metadata and adding the following additional query parameters:

client_id
The client id as returned in the registration.
redirect_uri

One of the redirect URIs registered by the client instance. This MUST be identical to the registered URI, with one exception: if the registered URI has the prefix "http://127.0.0.1/" or "http://[::1]/", the URI sent MAY differ from it by the addition of a port number, and the authorization server MUST accept any port (see Section 7.3 of [RFC8252]). This is necessary because the client instance cannot know in advance which port it will be able to listen on.

For example, if http://127.0.0.1/redirect was registered, then the client instance could send http://127.0.0.1:49152/redirect as the redirect_uri for authorization.

response_type
This MUST be "code".
scope

A space delimited set of scopes the client instance would like access to. This MUST be a subset of the scopes registered for this client id.

For compatibility with servers implementing OpenID Connect [OpenID.Core], if the server advertised the offline_access scope in the "scopes_supported" property of the authorization server metadata, the client instance MUST also request this scope. Section 11 of [OpenID.Core] further requires the prompt parameter to have the value consent when offline_access is requested, unless other conditions permitting offline access are in place, and some deployments will not issue a refresh token without it. A client instance requesting offline_access SHOULD therefore also include a prompt parameter with the value consent (see Section 3.1.2.1 of [OpenID.Core]).

code_challenge

A PKCE code challenge as per [RFC7636], using SHA 256. To generate a challenge, first generate a code_verifier: a high-entropy cryptographic random string using the unreserved characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" from Section 2.3 of [RFC3986], with a minimum length of 43 characters and a maximum length of 128 characters.

The code_challenge is then BASE64URL-ENCODE(SHA256(ASCII(code_verifier))).

code_challenge_method
This MUST be "S256".
resource

A Resource Indicator [RFC8707] for a resource endpoint (as obtained from autoconfiguration or user input) that the client instance wishes to access after successful authorization. The client instance MUST include a resource parameter for each endpoint it intends to use, so if it wishes to use multiple protocols it will include multiple resource query parameters. If two endpoints result in the same value, the value MUST only be included once.

The value for each endpoint is determined as follows. First, the client instance determines the endpoint's resource URL:

  • For HTTP-based protocols, such as JMAP, CalDAV, and CardDAV, this is the endpoint URL, for example https://api.example.com/jmap/session or https://caldav.example.com/.well-known/caldav.
  • For non-HTTP protocols, such as IMAP, POP, and SMTP, this is the hostname of the server with no scheme or port, for example imap.example.com.

Then, if the authorization server metadata includes the protected_resources property (see Section 3.2), the client instance MUST use as the resource value the entry in that array that matches the resource URL. An entry matches an HTTP resource URL if all of the following hold:

  • The schemes are identical.
  • The hosts are identical when compared case-insensitively, after conversion of any internationalized host names to A-labels [RFC5890].
  • The ports are identical, after applying the default port for the scheme wherever a port is not given explicitly.
  • The path of the entry, with any trailing "/" removed, is either identical to the path of the resource URL or is followed in the path of the resource URL by a "/". That is, the entry's path is a prefix of the resource URL's path at a segment boundary.

Any query or fragment part of the resource URL is disregarded for matching. An entry matches a non-HTTP resource host name if the two are identical when compared case-insensitively, again after conversion to A-labels. If more than one entry matches, the client instance MUST use the one with the longest path.

For example, if the client instance wishes to connect to https://caldav.example.com/.well-known/caldav and the metadata lists ["https://caldav.example.com", "https://carddav.example.com"], the resource value is https://caldav.example.com. An entry of https://api.example.com does not match https://api.example.com.attacker.net/jmap/session, https://api.example.com:8443/jmap/session, or https://api.example.com@attacker.net/, and an entry of https://example.com/dav does not match https://example.com/davenport. Matching MUST be performed on the parsed components of the URL and not by comparing strings, as a plain prefix comparison would accept each of these counterfeit URLs.

If no entry matches, the endpoint is not a protected resource of this authorization server: the client instance MUST NOT include a resource parameter for it, and MUST NOT send access tokens obtained from this authorization server to it (see Section 3.6). If the client instance cannot function without that endpoint, it MUST abort the flow and inform the user.

If the metadata does not include the protected_resources property, the client instance MUST use the resource URL itself as the resource value. In this case the client instance MUST also apply the registrable domain rule in Section 3.6 before sending access tokens to the endpoint.

Note that in this case the resource value names a specific endpoint URL, while Section 3.6 permits the client instance to send the resulting access token to any host within the registrable domain of the issuer identifier, for example one reached by following an HTTP redirect during CalDAV or CardDAV service discovery. An authorization server that supports Resource Indicators and issues audience-restricted access tokens (see Section 4.10.2 of [RFC9700]) may therefore issue a token that the redirect target rejects, even though the client instance has behaved correctly. Servers that support Resource Indicators SHOULD avoid this by publishing protected_resources, so that the client instance sends a value that covers every host the token may legitimately be presented to; failing that, they MUST ensure a token issued for an endpoint URL is accepted by any resource server to which that endpoint redirects the client.

Note that Section 2 of [RFC8707] requires the resource value to be an absolute URI, and Section 4 of [RFC9728] likewise requires entries of protected_resources to be https URLs. This profile deviates from both requirements for non-HTTP protocols, where the value is a bare hostname. Endpoints for these protocols are not naturally identified by a URI, and the hostname is what the client instance MUST present in the host attribute of the OAUTHBEARER SASL exchange [RFC7628] (see Section 3.7). Servers implementing this profile MUST accept a bare hostname as a resource value for such endpoints.

Server support for Resource Indicators is RECOMMENDED; servers that do not support them will ignore these parameters and the flow will still succeed. Servers that do support Resource Indicators MUST verify that all requested resource values are permitted locations to send access tokens to (i.e., they are the real resource endpoints associated with this authorization server, or entries in the server's protected_resources list), and MUST reject the request with an invalid_target error, as defined in Section 2 of [RFC8707], if any are not.

state
An opaque value used by the client instance to verify that an authorization response is due to a request that the client instance initiated. The authorization server will include this value when redirecting the user-agent back to the client instance. Client instances MUST generate a state with a unique, unguessable random string when initiating an authorization request.
login_hint (optional)
The username the user originally asked to log in with, as defined in Section 3.1.2.1 of [OpenID.Core]. The server can prefill this in a login form. Note, the user may choose to log in with a different username; the client instance learns which username was actually authenticated from the username property of the token response (see Section 3.5).

After constructing the authorization request URL, the client instance MUST use platform-specific APIs to open it in an external user-agent. It MUST NOT use an embedded user-agent (such as a web view) within the application, as required by Section 8.12 of [RFC8252]. Typically, the external user-agent used is the default browser, that is, the application configured for handling "http" and "https" scheme URIs on the system. See Section 6 of [RFC8252] for a discussion of best practices and alternatives, such as in-app browser tabs, which are external user-agents that render within the application while retaining the security properties of the browser. The client instance MUST use a user-agent that supports session cookies, JavaScript, and the Web Authentication API [WebAuthn], so that authorization servers can rely on these being available.

Embedded user-agents are prohibited because they undermine much of the security benefit of this profile. An embedded user-agent is under the control of the client application, which can therefore observe and modify everything the user enters, including their password and any second factor, and the user has no way to verify which site they are actually entering their credentials into. An external user-agent, by contrast, shares the user's existing authentication state and credential stores with the rest of the system. This allows single sign-on, password managers, and origin-bound authenticators such as passkeys [WebAuthn] to work, and allows the browser's built-in phishing protections to apply. Users are also better able to recognise and reason about a login page shown in their familiar browser than one shown inside an arbitrary application.

This restriction is a requirement on clients and is not reliably enforceable by the authorization server, as an embedded user-agent may be indistinguishable from an external one. Servers MAY use heuristics (for example, the User-Agent header field) to detect and refuse authorization from known embedded user-agents, as suggested in Section 8.12 of [RFC8252], but the security of this profile does not depend on them doing so. As discussed in Section 4, a malicious native application could already present the user with a fake browser, so this profile does not attempt to defend against a malicious client; the requirement ensures that well-behaved clients provide the security properties users expect.

The authorization server MUST verify that all of the parameters defined above are present and conform to the restrictions in this document. A request in which any parameter is included more than once MUST be rejected, with the exception of the resource parameter, which may be repeated as described above.

The client instance MAY include additional request parameters defined by other OAuth extensions, for example the prompt or ui_locales parameters defined by OpenID Connect Core [OpenID.Core]. This does not permit alternative or additional values for the parameters defined above; in particular, it does not relax the redirect_uri matching rules, and a request whose defined parameters do not conform MUST be rejected regardless of any other parameters present. The authorization server MUST ignore any request parameter it does not recognise, as required by Section 3.1 of [RFC6749], and clients MUST NOT depend on such parameters being understood for interoperability. Ignoring unrecognised parameters is safe because they cannot affect the processing of the parameters defined by this document, and it allows this profile to coexist with other OAuth extensions that both the client and server happen to support.

If verified, the authorization server will authenticate the user and ask them if they wish to grant authorization to the client.

If the request fails due to a missing, invalid, or mismatching redirection URI, or if the client identifier is missing or invalid, the authorization server SHOULD inform the user of the error and MUST NOT automatically redirect the user-agent to the invalid redirection URI. If the authorization request fails for any other reason, the client instance will receive an error response via the redirect_uri. This MUST include an error query parameter with an appropriate error code, as defined in Section 4.1.2.1 of [RFC6749]. The error response also includes the state parameter and, as required by Section 2 of [RFC9207], the iss parameter. The client instance MUST verify both as described below before acting on the error, and MUST ignore an error response whose state does not match a request it has outstanding.

If authorization is successful, the client instance will receive a response via the redirect_uri, which will include the following query parameters:

code
The authorization code. This may be exchanged for the refresh token. This code MUST expire, and MUST remain valid for at least 10 minutes from authorization. It MUST NOT be used again once the client instance has successfully exchanged it for a refresh token. Doing so may cause the server to detect it as stolen and revoke all associated tokens.
state
The value of the state parameter that was passed in with the initial request.
iss
The issuer identifier of the authorization server.

The client instance MUST verify all of the following:

  • The "iss" returned is identical to the "issuer" property in the authorization server metadata. This is critical for protecting against various mix-up attacks should a malicious OAuth metadata object be fetched, as discussed in the security considerations.
  • The state returned matches exactly the state it sent, to verify that this request was indeed initiated by the client and not an attacker.

If any verification fails, the client instance MUST abort the flow and not send the authorization code anywhere. It MUST inform the user of what went wrong and what they can do next. For a loopback redirect URI, this is done by returning an HTML page in response to the redirect request; for a private-use scheme URI the client instance is invoked directly and displays the message itself.

3.5. Obtaining a Refresh Token

Following authorization, the client instance will obtain initial refresh and access tokens by making a POST request to the token_endpoint URL. The following parameters MUST be present, using the "application/x-www-form-urlencoded" format with a character encoding of UTF-8 in the HTTP request entity-body:

client_id
The client id as returned in the registration.
redirect_uri
The redirect_uri parameter sent with the authorization request from which the code was obtained.
grant_type
This MUST be "authorization_code".
code
The code returned via the redirect back from authorization.
code_verifier

The code_verifier generated for the authorization (the random string generated in the authorization step, as per [RFC7636]).

The server MUST reject a request that omits this parameter, or whose value does not verify against the code_challenge sent with the authorization request, as specified in Section 4.6 of [RFC7636]. An authorization code issued to a client registered under this profile MUST NOT be exchangeable without it: PKCE is the only protection against an authorization code intercepted via a loopback or private-use scheme redirect.

resource (optional)
One or more Resource Indicators, as described in Section 2.2 of [RFC8707], restricting the access token to a subset of the resources that were authorized. Each value MUST be one of the resource values sent in the authorization request. If omitted, the access token is issued for all of the authorized resources. See Section 3.8 for when a client instance needs to use this.

The client instance MAY include additional parameters defined by other OAuth extensions. The server MUST ignore any parameter it does not recognise, as required by Section 3.2 of [RFC6749], and clients MUST NOT depend on such parameters being understood for interoperability. If using DPoP, the client instance MUST also set a DPoP header in accordance with Section 5 of [RFC9449]. A client instance using DPoP MUST support the authorization server-provided nonce (Section 8 of [RFC9449]) and resource server-provided nonce (Section 9 of [RFC9449]) mechanisms, retrying a request that fails with a use_dpop_nonce error using the nonce supplied, as servers MAY require a nonce in every proof.

The server will verify the parameters and if successful, return a 200 OK response with a content type of application/json. The body will be a JSON object with the following properties:

access_token
A bearer token used to authenticate API requests. This will be valid for a fixed, limited time.
token_type
The type of the access token. This MUST be "Bearer", or "DPoP" if the client is using DPoP ([RFC9449]). The value is case insensitive (Section 5.1 of [RFC6749]), and clients MUST compare it accordingly; servers commonly return "bearer".
expires_in
The lifetime in seconds of the access token. For example, the value 3600 denotes that the access token will expire in one hour from the time the response was generated. Servers MUST include this property in every token response (it is only RECOMMENDED in Section 5.1 of [RFC6749]), as clients rely on it to obtain a new access token before the current one expires (see Section 3.10).
scope

The space delimited set of scopes that this access token may use. Servers MUST include this property in every token response, even where it is identical to the set of scopes requested (in which case it is OPTIONAL in Section 5.1 of [RFC6749]).

Note, this MAY be different to the set of scopes requested. Servers MAY allow users to choose to authorize only a subset of the requested scopes. Clients MUST check the set of scopes granted is sufficient for its needs.

refresh_token
The refresh token to use next time the client instance needs to get a new access token. Servers MUST include this property in the response to an authorization code grant; a client instance following this profile cannot function without it. For its presence in the response to a refresh token grant, see Section 3.10.
username

The username of the account that was authenticated and granted this authorization, in the form the user would enter it to log in to this deployment (typically the user's email address). Servers MUST include this property in every token response, and the value MUST be the same in every token response issued under the same authorization.

The user may have started the flow by giving the client instance one username (which the client instance may have passed as the login_hint, see Section 3.4) and then authenticated at the authorization server as a different user. Without this property the client instance has no interoperable way to discover this, and may label the account, or associate the tokens with a local account, incorrectly. The client instance MUST use this value, rather than the username originally supplied by the user, as the identity of the account the tokens belong to. If it differs from the username the user supplied, the client instance SHOULD make this visible to the user.

OpenID Connect [OpenID.Core] can convey the authenticated user's identity in an ID Token, but this profile does not require OpenID Connect support, and the sub claim it guarantees is an opaque identifier rather than a username the user would recognise. This document therefore registers "token response" as an additional usage location for the existing username parameter (see Section 5.2).

If the request fails, the server MUST return an error response as described in Section 5.2 of [RFC6749]: a 400 Bad Request status code (or 401 Unauthorized for an invalid_client error) with a content type of application/json, and a JSON object body with the properties defined there. A client id that is no longer valid (see Section 3.12) is reported with the invalid_client error code. An authorization code or refresh token that is invalid, expired, or revoked is reported with the invalid_grant error code.

3.6. Permitted Resource Servers

An access token obtained from an authorization server MUST only be sent to a resource server that the client instance has determined to be associated with that authorization server, as described in this section. This protects against a counterfeit resource server that has been named in autoconfiguration data or protected resource metadata under the attacker's control (see Section 4.9.1 of [RFC9700] and Section 4).

The client instance MUST make this determination for every host to which it sends an access token. This includes any host reached by following an HTTP redirect, such as those commonly used in CalDAV and CardDAV service discovery: the determination is made against the URL actually being requested, not only the endpoint URL the client instance started from. A client instance MUST NOT send an access token to a host for which the determination fails. If the client instance cannot function without that resource server, it MUST abort and inform the user.

The determination is made in one of two ways, depending on whether the authorization server metadata includes the protected_resources property (see Section 3.2):

  • If the property is present, a resource server is permitted if and only if an entry in the list matches the request URL (for HTTP-based protocols) or the host name (for non-HTTP protocols), using the matching rules given for the resource parameter in Section 3.4.
  • If the property is absent, a resource server is permitted if and only if its host name has the same registrable domain as the host of the authorization server issuer identifier. For HTTP-based protocols the host name is the host component of the request URL; for non-HTTP protocols it is the host name the client instance connects to.

The registrable domain of a host name is its public suffix plus the DNS label immediately preceding that suffix, where the public suffix is determined using the Public Suffix List [PSL]. For example, the registrable domain of imap.example.com is example.com, and the registrable domain of auth.example.co.uk is example.co.uk. Host names MUST be compared case-insensitively, and internationalized host names MUST be converted to A-labels [RFC5890] before comparison. A host that is an IP address literal, or that has no registrable domain (for example, a single-label host name, or a host name that is itself a public suffix), is never permitted under this rule.

The registrable domain rule allows deployments that host their authorization server and resource servers within a single domain, for example auth.example.com and imap.example.com, to be secure without further configuration. Deployments whose resource servers are not all within the registrable domain of the issuer identifier, including providers that use a separate identity provider domain and multi-tenant authorization servers whose issuer identifier includes a path component, MUST publish protected_resources (see Section 3.2), as clients following this profile will otherwise refuse to use their resource servers.

3.7. Using the Access Token

The client instance is now authenticated. It can connect to the resource servers permitted under Section 3.6 with the Bearer scheme [RFC6750]. For HTTP-based protocols, this means setting an Authorization header with the value Bearer {access_token} (where {access_token} is replaced with the value of the access_token). If using DPoP, the client instance MUST also set a DPoP header in accordance with Section 7 of [RFC9449].

For protocols that use SASL authentication, such as IMAP, POP, and SMTP, the access token is used in accordance with the OAUTHBEARER mechanism defined in [RFC7628]. Servers MUST NOT require the username associated with the resource (the "authzid") be included in the GS2 header. The client instance MUST include the host attribute in its initial client response (Section 3.1 of [RFC7628]), set to the host name it connected to, and SHOULD include the port attribute. [RFC7628] makes these attributes optional for bearer tokens; this profile requires host because it is the value the client instance used as the Resource Indicator for the endpoint (see Section 3.4), which allows a server to check that the access token was issued for the host it is being presented to.

3.8. DPoP and Non-HTTP Protocols

DPoP [RFC9449] is only defined for HTTP. The proof JWT (Section 4.2 of [RFC9449]) is bound to the HTTP method and URI of the request it protects and is carried in an HTTP header field, and the OAUTHBEARER SASL mechanism [RFC7628] has no means of carrying such a proof. A DPoP-bound access token therefore cannot be used to authenticate to an IMAP, POP, or SMTP server. Sender-constraining access tokens for SASL-based protocols would require a new SASL mechanism, or an extension to OAUTHBEARER, together with a means for the resource server to verify the proof. That is out of scope for this document.

A client instance that uses only HTTP-based protocols and wishes to use DPoP SHOULD register with dpop_bound_access_tokens set to true (see Section 3.3), include a DPoP proof in every token request, and use the resulting DPoP-bound access tokens as described in Section 7 of [RFC9449].

A client instance that uses non-HTTP protocols, whether exclusively or alongside HTTP-based protocols, has two choices. The simplest is not to use DPoP at all, in which case all tokens are bearer tokens. Alternatively, it MAY use DPoP for the token endpoint and for HTTP-based resources while still obtaining bearer tokens for non-HTTP resources, as follows:

  • The client instance MUST NOT set dpop_bound_access_tokens to true when registering, as the server would then be required to issue only DPoP-bound access tokens.
  • The client instance includes a DPoP proof in every token request. As required by Section 5 of [RFC9449], the server binds the refresh token to the client instance's key, so the refresh token is sender-constrained even though some of the access tokens obtained with it are not.
  • The client instance obtains separate access tokens for HTTP and non-HTTP resources by including resource parameters in the token request (see Section 3.5 and Section 3.10): one request listing only its HTTP-based resources, and a second listing only its non-HTTP resources (that is, hostnames, see Section 3.4). The initial token request exchanging the authorization code can be made for either set, and the other set is then obtained by a refresh request.
  • When a token request includes a valid DPoP proof and every resource parameter is a hostname for a non-HTTP resource, a server that supports both DPoP and Resource Indicators MUST issue an access token that is not bound to the DPoP key, with a token_type of "Bearer". For any other token request that includes a DPoP proof, the server issues a DPoP-bound access token with a token_type of "DPoP", as normal. Servers that support DPoP SHOULD therefore also support Resource Indicators, so that client instances using non-HTTP protocols are not prevented from using DPoP.
  • The client instance MUST check the token_type of each response and use the token accordingly: a "DPoP" token with the DPoP authentication scheme for HTTP requests, and a "Bearer" token with the Bearer scheme or OAUTHBEARER. If the client instance receives a "DPoP" token in response to a request that listed only non-HTTP resources, the server does not support this arrangement (for example, because it does not support Resource Indicators and ignored the parameters). The client instance MUST NOT attempt to use that token with a non-HTTP server, and MUST obtain a new authorization without using DPoP if it is to continue.

A client instance can avoid the last failure case in most deployments by only attempting this arrangement when the authorization server metadata includes protected_resources, which indicates the server acts on Resource Indicators.

3.9. Scopes

To work interoperably, clients and servers must use a common set of scopes for access. This document creates a new IANA registry for such scopes (see Section 5.1), and registers scopes to cover IMAP, SMTP, POP, CardDAV, CalDAV, and JMAP.

Registration of a scope in that registry does not by itself impose any requirement on OAuth implementations in general (see Section 5.1). This profile, however, does require support: a server implementing this profile MUST support each of the scopes registered by this document (Section 5.1.5) whose definition covers a protocol or type of data that the server offers. For example, a server that offers IMAP and SMTP MUST support urn:ietf:params:oauth:scope:mail, and a server that offers CalDAV MUST support urn:ietf:params:oauth:scope:calendars. Supporting a scope means advertising it in the scopes_supported metadata property, accepting it in registration and authorization requests, and granting the access described in its registration when it is authorized.

Servers MAY additionally support other scopes, for example finer-grained or vendor-specific scopes, but clients following this profile can only rely on the registered scopes being available.

3.10. Getting a New Access Token

Clients SHOULD keep using an access token they have been issued until it expires. The client instance knows when this will happen from the expires_in property returned with the token, and, while it has an active need for the token (for example, open connections it expects to re-establish), SHOULD proactively obtain a new access token shortly before the current one expires, rather than waiting for a request to fail. A client instance with no such need SHOULD NOT refresh merely to keep a token current. This is particularly important for stateful protocols such as IMAP and SMTP, where the token is needed at connection time and a round trip to the token endpoint would otherwise delay every reconnection. Clients MUST nonetheless be prepared for an access token to be rejected at any time (for HTTP-based protocols, with a 401 response), as the server may invalidate it early, and MUST handle this by obtaining a new one.

When the access token expires, the client instance MUST get a new one by making another POST request to the authorization server token endpoint. The following parameters MUST be present, using the "application/x-www-form-urlencoded" format with a character encoding of UTF-8 in the HTTP request entity-body:

client_id
The client id as returned in the registration.
grant_type
This MUST be "refresh_token".
refresh_token
The refresh token returned last time the client instance obtained a new access token.
resource (optional)
One or more Resource Indicators restricting the access token to a subset of the authorized resources, with the same semantics as in Section 3.5.

The success and failures responses are identical to those documented in "Obtaining a refresh token" (Section 3.5).

Because clients following this profile are public clients, the server MUST protect against refresh token replay using one of the two methods required by Section 4.14.2 of [RFC9700]. If the refresh token is sender-constrained, because the client instance presented a DPoP proof when it was issued and the server bound it to the client instance's key (Section 5 of [RFC9449]), the server MAY omit the refresh_token property from the response or return the same refresh token, in which case the client instance continues to use the refresh token it holds. Otherwise, the server MUST return a new refresh token in the response (refresh token rotation). In either case, the client instance MUST replace its previous refresh token with the one returned if one is returned and it differs, and MUST persist the new refresh token before making any use of the access token returned alongside it.

When the server issues a new refresh token, it MUST NOT invalidate the previous refresh token immediately. Instead, the previous refresh token MUST remain valid until the server first sees either the new refresh token or the new access token issued in the same response being used. The response may not reach the client instance: the connection may drop, or the client may crash before it can persist the new token. In either case the client instance will legitimately retry with the refresh token it still holds, and the flow must succeed. A request presenting the previous refresh token during this window MUST be answered with the same new refresh token that was issued in the original response, together with either the same access token (with expires_in adjusted for the time elapsed) or a freshly issued one. The server MUST NOT issue a further new refresh token in response to the previous one. If it did, an attacker who had obtained a copy of the previous refresh token and used it during the window would obtain a refresh token chain of their own, independent of the client instance's, and the detection described below would never catch it. Returning the same new refresh token instead means the attacker and the legitimate client instance hold the same token, and the next rotation reveals the duplicate. Once the new refresh token or the new access token has been used, however, the server knows the client instance received the response, so any subsequent use of the previous refresh token can only come from a copy that has been leaked or stolen. Note that an authorization server may not observe access token use at all, for example when access tokens are self-contained and validated locally by the resource server, or are presented to a separate IMAP or SMTP server. Use of the new refresh token is therefore the trigger that every server can rely upon; use of the new access token allows a server that does observe it to close the window sooner. At that point the server MUST treat the previous refresh token as invalid, and SHOULD revoke the entire authorization, including the current refresh token and all associated access tokens, as a protection against leaked refresh tokens.

This deviates from Section 4.14.2 of [RFC9700], which invalidates the previous refresh token as soon as the new one is issued. The deviation is limited to the window between issuance and the client instance's first use of the new tokens, during which the previous token can obtain nothing beyond what the response already granted, and is necessary to allow a client instance that did not receive the response to recover without user interaction.

The client instance MUST ensure that only one token request is in flight at a time for a given refresh token, for example by serialising refresh operations across all connections that share the authorization. Concurrent refreshes would otherwise race, with one of them presenting a refresh token that has just been superseded.

If a user has multiple devices with the same client software installed, each instance of the client MUST obtain separate authorization. A refresh token MUST NOT be shared between devices.

3.11. Token Expiry Times

Access tokens MUST have a lifetime of at least 10 minutes, and SHOULD have a lifetime of at least 1 hour.

The hard minimum exists so that a client instance can rely on an access token it has just obtained surviving a single operation, especially in the face of poor network conditions where it may have to retry several times before it can connect to the resource server. It also bounds the rate at which a client instance must contact the token endpoint, making the client more efficient with its network usage.

The recommended lifetime of one hour further reduces load on the token endpoint and, more importantly, loosens the coupling between the authorization server and the resource servers: with hour-long tokens a brief outage of the authorization server, or a period on a network where it is unreachable, is invisible to the user. The trade-off is that a longer lifetime extends the window during which a leaked bearer token can be misused. Servers that consider this window too long are encouraged to support DPoP ([RFC9449]), which prevents a stolen access token from being used by anyone other than the client instance it was issued to, rather than to shorten the lifetime below one hour.

Refresh tokens SHOULD NOT expire, unless the user explicitly revokes the token or it has been unused for a considerable period of time (at least 30 days).

For stateful connection-based protocols such as SMTP and IMAP the access token is only presented on first connection. Expiry of the access token SHOULD NOT affect current IMAP/SMTP etc. sessions that have already authenticated. However, should the server choose to force reauthorization it MUST do so by unilaterally closing the connection, as there is no way to reauthenticate an existing session in these protocols and all clients have to be able to handle reconnection in the case of dropped connections.

When the server revokes a refresh token (for example, because the user has revoked the client's authorization, or because the token has been detected as leaked), it MUST close any existing stateful connections that were authenticated using access tokens issued under that refresh token.

A client instance cannot detect that its refresh token has been revoked until it next attempts to use it. Once a client instance does detect revocation (by receiving an invalid_grant error from the token endpoint, or an invalid_client error indicating that the client id is no longer valid, see Section 3.12), it MUST discard the refresh token and any associated access tokens, MUST close any stateful connections it still has open that were authenticated with them, and MUST obtain new authorization before reconnecting (see Section 3.12).

3.12. Client Id Validity

The client id MUST remain valid for as long as there is a valid refresh token associated with that client id.

To ensure a good user experience, the client id assigned upon dynamic registration SHOULD be valid for use in the authorization flow (Section 3.4) for at least one hour after issuance.

Clients MUST associate a client id with each refresh token it has. If the refresh token is invalidated and the client instance has to reauthenticate, it MUST submit the dynamic client registration (Section 3.3) again and use the client id returned, which MAY be different than the previous client id. A client instance that receives an invalid_client error from the token endpoint MUST likewise treat the client id as no longer valid and re-register before obtaining new authorization.

Servers that wish to store client registration information MUST be careful of resource exhaustion attacks. A RECOMMENDED approach is to:

  • Normalize and securely hash the submitted registration data.
  • Check if this hash already exists in the database, and if so return the existing client id issued for this registration.
  • Otherwise, keep the registration in temporary storage and only insert it into the database upon successful authorization. Creating a new client id in the temporary storage can be rate limited, for example by IP.
  • Remove any client registrations from the database whenever there are no valid refresh tokens associated with that client id.

4. Security Considerations

This profile mandates best practices for OAuth with native clients, as defined in [RFC8252]. A thorough discussion of the security considerations generally applicable to OAuth is out of scope for this document, but can be found in [RFC6819] and in the OAuth 2.0 Security Best Current Practice [RFC9700] (BCP 240), as well as the security considerations (Section 10) of [RFC6749].

Implementers are encouraged to read all of the above documents for a more thorough consideration of the specific threats and mitigations with OAuth.

The choices made for this profile are intended to mitigate as far as possible the inherent risks that come from allowing arbitrary clients to talk to arbitrary servers.

The key restriction of this profile is that the redirect_uri MUST be something only a native client can access. If the user has downloaded and run a malicious native app, it could already undetectably spoof the user's browser to phish them, or in unsandboxed environments install malware, so supporting the OAuth flow from an unknown client is not increasing risks. Indeed, it is more secure than the current alternative, which is legitimate clients storing the user's password. This is also why claimed "https" scheme redirect URIs (Section 7.2 of [RFC8252]) are excluded: although they are the most secure redirect option on platforms that support them, an authorization server has no way to tell one from an ordinary web URL, and permitting them would permit web-based clients.

Access tokens, refresh tokens, and authorization codes are bearer credentials: anyone who obtains one can use it. Clients MUST only send them over connections secured with TLS, and MUST verify the server's certificate as described in [RFC9525]. This applies to the token endpoint, to HTTP-based resource servers as required by Section 5.3 of [RFC6750], and to protocols using SASL: for IMAP, POP, and SMTP, the client MUST negotiate TLS (either Implicit TLS or STARTTLS, see [RFC8314]) before sending the OAUTHBEARER authentication exchange. Servers MUST NOT accept access tokens over connections that are not protected by TLS. The one exception is the redirect back to a loopback redirect URI (Section 3.3), which uses the "http" scheme. This carries only the authorization code, and the connection never leaves the user's device. The code is additionally protected by PKCE, so it is useless to anyone other than the client instance that holds the corresponding code verifier.

The dynamic registration part of this document is not a security component, as there is no way to verify any of the data. The data in the registration may be shown to the user as part of the authorization flow, which may help with phishing, but as noted above the redirect_uri can only be used by a native app, which could already phish the user. However, the registration gives the server more information to detect suspicious behaviour, which can help it to detect compromised users and devices more easily.

All metadata supplied in a dynamic client registration is attacker-controlled from the authorization server's point of view. The client_name, client_uri, logo_uri, tos_uri, and policy_uri values MAY be shown to the user, but the authorization server MUST treat them as untrusted content. It MUST escape them appropriately when rendering them, and MUST NOT fetch logo_uri or any other supplied URL from the server side without the protections appropriate to fetching an untrusted URL, since such a fetch can otherwise be used to reach resources on the server's internal network. Any such URL may also point at malicious content, as discussed in Section 5 of [RFC7591]. A logo loaded by the user's browser additionally discloses the user's IP address, and the fact that an authorization is taking place, to whoever controls the URL. Because the identity of the client cannot be verified, the authorization server SHOULD make clear on the consent page that the client is unverified, SHOULD display the requested scopes in plain language, and MUST NOT present the registration metadata in a way that suggests it has been vetted. Servers that prefer not to display unverified metadata MAY show only the requested scopes and a generic description of the client.

Refresh tokens are long-lived credentials, and DPoP private keys are equivalent in value to the tokens they protect. Client instances SHOULD store both using the most secure storage the platform provides, such as an operating system keychain or keystore, with hardware-backed storage where available, and MUST NOT write them to logs or, where the platform offers protected storage, to storage accessible to other applications. Access tokens SHOULD be handled the same way, but MAY be held only in memory. When the user removes an account from the client, or the client is being uninstalled, the client instance SHOULD revoke its refresh token via the revocation_endpoint if the server advertises one, so that the server can discard the authorization rather than waiting for the token to expire through inactivity.

Both kinds of redirect URI permitted by this profile can be claimed by software other than the client instance. Another application on the device may register the same private-use URI scheme (Section 8.1 of [RFC8252]), and another process may bind the loopback port the client instance intends to use before it does (Section 8.3 of [RFC8252]). In either case the authorization code may be delivered to the wrong recipient. This profile mitigates this in two ways. The code is useless without the PKCE code verifier, which never leaves the client instance, so an intercepted code cannot be exchanged (Section 4.5.3.1 of [RFC9700]). The state parameter binds a response to a request the client instance made, so an attacker cannot inject a code of their own into the client instance's flow (Section 4.7 of [RFC9700]). Client instances MUST bind a loopback listener to the loopback interface only, MUST accept at most one authorization response per listener, and MUST close the listener once the response has been received or the flow abandoned.

The issuer is expected to be autodetected from the user's email address. A threat scenario that must be considered is the user making a small typo in the domain (especially for a common email service), and an attacker controlling this domain. In this scenario the client instance will fetch the OAuth metadata from the attacker's server, and has no way to know it is not the real server the user wishes to connect to. This leads to a number of threats:

  1. The attacker defines a malicious authorization_endpoint under their control. They attempt to phish the user's credentials with this. This is not something that can be specifically mitigated by the requirements of this document, however requiring origin-bound authentication such as passkeys [WebAuthn] for authentication will mitigate this, and most browsers have a block list of known phishing sites that can also help mitigate this.

  2. The attacker publishes their own authorization server metadata, copying the real authorization_endpoint and token_endpoint values but naming their own resource servers. This is a mix-up attack (Section 4.4 of [RFC9700]) and is protected against by the issuer identifier check. The authorization response will include an iss parameter carrying the legitimate issuer identifier, but the issuer property of the attacker's metadata must name the attacker's own domain (if it did not, the client instance would have aborted after fetching the metadata, as the property would not match the identifier from which the metadata URL was derived). The two therefore differ, and a client instance following this specification will abort the flow and not send the authorization code to the token endpoint.

  3. The attacker publishes no authorization server metadata of their own. Instead, the autoconfiguration data or protected resource metadata under their control names the real authorization server's issuer identifier alongside the attacker's own resource servers. The client instance fetches the genuine metadata, and the issuer property matches. The user authenticates and grants consent at the genuine authorization server, and the iss parameter in the authorization response matches. Every check in the flow passes, because nothing has been mixed up: the client instance then presents a valid access token to the attacker's resource server, and the attacker replays it against the real one. This is the counterfeit resource server attack described in Section 4.9.1 of [RFC9700], and the issuer identifier check offers no protection against it.

    The protection is the rule in Section 3.6: the authorization server vouches for its resource servers, either explicitly by publishing protected_resources, or implicitly through the resource servers sharing the registrable domain of the issuer identifier. In the example above, the attacker's host is under the mistyped domain while the issuer identifier is under the provider's domain, so the client instance refuses to send the token. Servers that support Resource Indicators [RFC8707] add a second, server-side layer: the client instance sends a resource value for every resource server it intends to use, and the authorization server rejects the request if any is not one of its own. Sender-constrained access tokens ([RFC9449]) further prevent a captured HTTP access token from being replayed, but offer no protection for non-HTTP protocols, so they are not a substitute for the rule above.

    The registrable domain rule has two limitations. First, it relies on the Public Suffix List [PSL], which is maintained outside the IETF and changes over time; a client instance with a stale copy may classify a host differently from an up-to-date one. Clients SHOULD keep their copy current and MUST fail closed where a host cannot be classified. Second, an attacker that controls any host within the registrable domain of the issuer identifier (for example, on a shared hosting platform or under an institution's domain) is not excluded by it. Such an attacker must also control the autoconfiguration for the domain the user entered, so the exposure is narrow, but deployments in which untrusted parties can obtain host names under the issuer's registrable domain SHOULD publish protected_resources to close it.

  4. The attacker uses the real authorization_endpoint value and the real resource servers in its metadata, but uses their own token_endpoint. The issuer identifier check described in item 2 will also protect against this.

This specification allows clients to fall back to the OpenID Connect Discovery metadata path if the RFC 8414 metadata path fails. Implementers should be aware that these two paths have different security properties when the issuer identifier contains a path component. The RFC 8414 path inserts the well-known component at the host root (e.g., https://auth.example.com/.well-known/oauth-authorization-server/acmeinc), meaning only an entity with control over the host can serve this document. The OpenID Connect Discovery path appends the well-known component to the issuer (e.g., https://auth.example.com/acmeinc/.well-known/openid-configuration), meaning any entity that controls the path can serve this document. In multi-tenant environments where different entities control different paths on the same host, the OpenID Connect Discovery fallback allows a tenant to serve their own metadata without host-level control. The issuer identifier verification remains the primary defence against mix-up attacks in all cases, but operators of shared hosts should be aware that the RFC 8414 path provides an additional layer of host-level vetting that the OpenID Connect Discovery path does not.

5. IANA Considerations

5.1. Interoperable OAuth Scopes Registry

IANA is requested to add a new registry called "Interoperable OAuth Scopes" to the "OAuth Parameters" registry group [IANA.OAuth.Parameters]. The registry records OAuth scope values that have a standardised, interoperable meaning, such that a client and a server with no pre-existing relationship can agree on the access a scope grants. Each scope provides specific access rights to protected resources, and the registry records a reference to the specification that defines those rights.

5.1.1. Applicability of Registered Scopes

Registration of a scope in this registry does not, by itself, impose any requirement on OAuth authorization servers, resource servers, or clients in general. An OAuth implementation is not required to recognise, support, or grant any scope in this registry merely because it is registered. In this respect the registry is a coordination mechanism, ensuring a given scope value has a single well-defined meaning wherever it is used, rather than a statement of what OAuth implementations must support.

Support for a registered scope is required only where a profile or other specification that references this registry mandates it. Such a specification MUST clearly identify which implementations are required to support which scopes. This document is one such profile: the scopes that servers implementing it MUST support are specified in Section 3.9. Other profiles MAY reference scopes in this registry and define their own support requirements, and the same scope MAY be required by more than one profile.

5.1.2. Scope Naming Conventions

Scope names in this registry are case sensitive. Names MUST NOT match other registered names in a case-insensitive manner unless the designated experts state that there is a compelling reason to allow an exception.

A newly defined scope registered in this registry MUST be a URN in the urn:ietf:params:oauth:scope: sub-namespace of the OAuth URN namespace [RFC6755], of the form urn:ietf:params:oauth:scope:<name>, for example urn:ietf:params:oauth:scope:mail. The <name> component SHOULD be a short, lowercase, descriptive identifier for the class of data or resources to which the scope grants access. Using this namespace guarantees the value cannot collide with scope strings defined elsewhere, and makes clear to implementers that the value has a standardised meaning. Any such URN MUST also be registered in the IANA "OAuth URI" registry [IANA.OAuth.Parameters] established by [RFC6755], referencing the same specification document(s).

An unstructured scope string, that is, one that is not a URN in the above sub-namespace, MAY be registered only where all of the following apply:

  • The scope value is already defined by an existing, publicly available and stable specification outside of the IETF's control, or is already in widespread deployment with a single well-understood meaning.
  • The purpose of the registration is to allow profiles referencing this registry to interoperate with that existing usage. Assigning a new URN for the same purpose would therefore harm interoperability rather than help it.
  • The value does not conflict with any existing registration in this registry.

Unstructured strings MUST NOT be registered for newly defined scopes. Where a specification wishes to register a scope with an unstructured name, the designated experts MUST verify that the referenced specification defines the value with the meaning given in the registration request.

5.1.3. Registration Procedure

Values are registered via Specification Required [RFC8126]. Registration requests should be sent to the oauth-ext-review@ietf.org mailing list to initiate a two-week review period. However, to allow for the allocation of values prior to publication of the final version of a specification, the designated experts may approve registration once they are satisfied that the specification will be completed and published. However, if the specification is not completed and published in a timely manner, as determined by the designated experts, the designated experts may request that IANA withdraw the registration.

Registration requests sent to the mailing list for review should use an appropriate subject (e.g., "Request to register Interoperable OAuth Scope: example").

Within the review period, the designated experts will either approve or deny the registration request, communicating this decision to the review list and IANA. Denials should include an explanation and, if applicable, suggestions as to how to make the request successful. If the designated experts are not responsive, the registration requesters should contact IANA to escalate the process.

Designated experts should apply the following criteria when reviewing proposed registrations:

  • The proposed scope must be unique, that is, it must not duplicate the functionality of an existing registration.
  • The proposed scope is likely to be generally applicable, that is, useful to multiple independent clients and servers, as opposed to being used for a single application or deployment.
  • The proposed scope name follows the naming conventions in Section 5.1.2. In particular, an unstructured (non-URN) scope name is only permitted under the conditions given there.
  • The description clearly defines the access rights granted by the scope, with reference to publicly available and stable documentation sufficient for interoperability.
  • The specification document(s) identify which implementations are required to support the scope (for example, by defining or referencing a profile that mandates it), since registration alone imposes no such requirement (see Section 5.1.1).
  • The change controller is clearly identified.

IANA must only accept registry updates from the designated experts and should direct all requests for registration to the review mailing list.

In order to enable broadly informed review of registration decisions, there should be multiple designated experts to represent the perspectives of different applications using this specification. In cases where registration may be perceived as a conflict of interest for a particular expert, that expert should defer to the judgment of the other experts.

The mailing list is used to enable public review of registration requests, which enables both designated experts and other interested parties to provide feedback on proposed registrations. Designated experts may allocate values prior to publication of the final specification. This allows authors to receive guidance from the designated experts early, so any identified issues can be fixed before the final specification is published.

5.1.4. Registration Template

Scope Name:
The OAuth scope value requested (e.g., urn:ietf:params:oauth:scope:mail). This name is case sensitive and MUST conform to Section 5.1.2.
Description:
A clear description of what access rights this scope grants to the client, with reference to publicly available and stable documentation sufficient for interoperability.
Change Controller:
For IETF Stream RFCs, list "IETF". For others, give the name of the responsible party. Other details (e.g., postal address, email address, home page URI) may also be included.
Specification Document(s):
Reference to the document or documents that specify the scope, preferably including URIs that can be used to retrieve copies of the documents. An indication of the relevant sections may also be included but is not required. The referenced document(s) MUST identify which implementations are required to support the scope (see Section 5.1.1).

5.1.5. Initial Registry Contents

Scope Name:
urn:ietf:params:oauth:scope:mail
Description:

Requests access for a client to manage the user's email. This MUST include full access via all of the following protocols that the server supports:

  • IMAP [RFC9051]
  • POP [RFC1939]
  • SMTP submission [RFC6409]
  • ManageSieve [RFC5804]
  • JMAP [RFC8620] - this scope grants the right to use all JMAP capabilities that the server supports for which urn:ietf:params:oauth:scope:mail is included in the Interoperable OAuth Scopes column of the JMAP capabilities registry.
Change Controller:
IETF
Specification Document(s):
Section 5.1.5 and Section 3.9 of this document
Scope Name:
urn:ietf:params:oauth:scope:contacts
Description:
Requests access for a client to manage the user's contacts. This MUST include full access via the CardDAV protocol [RFC6352] if the server supports it. If the server supports JMAP [RFC8620], this scope grants the right to use all JMAP capabilities that the server supports for which urn:ietf:params:oauth:scope:contacts is included in the Interoperable OAuth Scopes column of the JMAP capabilities registry.
Change Controller:
IETF
Specification Document(s):
Section 5.1.5 and Section 3.9 of this document
Scope Name:
urn:ietf:params:oauth:scope:calendars
Description:
Requests access for a client to manage the user's calendars. This MUST include full access via the CalDAV protocol [RFC4791] if the server supports it. If the server supports JMAP [RFC8620], this scope grants the right to use all JMAP capabilities that the server supports for which urn:ietf:params:oauth:scope:calendars is included in the Interoperable OAuth Scopes column of the JMAP capabilities registry.
Change Controller:
IETF
Specification Document(s):
Section 5.1.5 and Section 3.9 of this document

5.2. Update to the OAuth Parameters Registry

IANA is requested to update the registration of the username parameter in the "OAuth Parameters" registry [IANA.OAuth.Parameters] established by Section 11.2 of [RFC6749], adding "token response" to its parameter usage location and adding this document to its specification document(s). The updated registration is as follows:

Parameter name:
username
Parameter usage location:
token request, token response
Change controller:
IETF
Specification document(s):
Section 4.3.2 of [RFC6749]; Section 3.5 of this document

The use of the username parameter in a token response is defined in Section 3.5. Its use in a token request, defined by Section 4.3.2 of [RFC6749], is unchanged.

5.3. OAuth URI Registrations

This section registers the following values in the IANA "OAuth URI" registry [IANA.OAuth.Parameters] established by [RFC6755]. They are the scope values defined by this document within the urn:ietf:params:oauth:scope: sub-namespace, as required by Section 5.1.2.

URN:
urn:ietf:params:oauth:scope:mail
Common Name:
Interoperable OAuth scope granting access to the user's email
Change Controller:
IETF
Specification Document(s):
Section 5.1.5 of this document
URN:
urn:ietf:params:oauth:scope:contacts
Common Name:
Interoperable OAuth scope granting access to the user's contacts
Change Controller:
IETF
Specification Document(s):
Section 5.1.5 of this document
URN:
urn:ietf:params:oauth:scope:calendars
Common Name:
Interoperable OAuth scope granting access to the user's calendars
Change Controller:
IETF
Specification Document(s):
Section 5.1.5 of this document

5.4. Update to the JMAP Capabilities Registry

IANA is requested to update the "JMAP Capabilities" registry established in [RFC8620] to add a new column called "Interoperable OAuth Scopes". For each capability, this column shall contain a list of zero or more scopes registered in the Interoperable OAuth Scopes Registry. Authorization for any scope in the list will grant access to use that JMAP capability, if the capability is supported by the server.

Future registrations in the "JMAP Capabilities" registry SHOULD specify a value for the Interoperable OAuth Scopes column in addition to the fields established in the registration template by Section 9.4.5 of [RFC8620]. If omitted, registrations will be added with no value for this column (i.e., no interoperable scopes are available to grant access to this capability via OAuth).

5.4.1. Initial Interoperable OAuth Scopes Values for the JMAP Capabilities Registry

IANA is requested to update the existing JMAP Capabilities registrations with the following values for the Interoperable OAuth Scopes column.

Capability Name:
urn:ietf:params:jmap:core
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail, urn:ietf:params:oauth:scope:contacts, urn:ietf:params:oauth:scope:calendars
Capability Name:
urn:ietf:params:jmap:mail
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail
Capability Name:
urn:ietf:params:jmap:mdn
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail
Capability Name:
urn:ietf:params:jmap:smimeverify
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail
Capability Name:
urn:ietf:params:jmap:submission
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail
Capability Name:
urn:ietf:params:jmap:vacationresponse
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail
Capability Name:
urn:ietf:params:jmap:blob
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail, urn:ietf:params:oauth:scope:contacts, urn:ietf:params:oauth:scope:calendars
Capability Name:
urn:ietf:params:jmap:quota
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail, urn:ietf:params:oauth:scope:contacts, urn:ietf:params:oauth:scope:calendars
Capability Name:
urn:ietf:params:jmap:sieve
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail
Capability Name:
urn:ietf:params:jmap:principals
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail, urn:ietf:params:oauth:scope:contacts, urn:ietf:params:oauth:scope:calendars
Capability Name:
urn:ietf:params:jmap:principals:owner
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail, urn:ietf:params:oauth:scope:contacts, urn:ietf:params:oauth:scope:calendars
Capability Name:
urn:ietf:params:jmap:contacts
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:contacts
Capability Name:
urn:ietf:params:jmap:calendars
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:calendars
Capability Name:
urn:ietf:params:jmap:principals:availability
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:calendars
Capability Name:
urn:ietf:params:jmap:webpush-vapid
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail, urn:ietf:params:oauth:scope:contacts, urn:ietf:params:oauth:scope:calendars
Capability Name:
urn:ietf:params:jmap:websocket
Interoperable OAuth Scopes:
urn:ietf:params:oauth:scope:mail, urn:ietf:params:oauth:scope:contacts, urn:ietf:params:oauth:scope:calendars

6. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC5890]
Klensin, J., "Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework", RFC 5890, DOI 10.17487/RFC5890, , <https://www.rfc-editor.org/info/rfc5890>.
[RFC6749]
Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/info/rfc6749>.
[RFC6750]
Jones, M. and D. Hardt, "The OAuth 2.0 Authorization Framework: Bearer Token Usage", RFC 6750, DOI 10.17487/RFC6750, , <https://www.rfc-editor.org/info/rfc6750>.
[RFC6755]
Campbell, B. and H. Tschofenig, "An IETF URN Sub-Namespace for OAuth", RFC 6755, DOI 10.17487/RFC6755, , <https://www.rfc-editor.org/info/rfc6755>.
[RFC7591]
Richer, J., Ed., Jones, M., Bradley, J., Machulak, M., and P. Hunt, "OAuth 2.0 Dynamic Client Registration Protocol", RFC 7591, DOI 10.17487/RFC7591, , <https://www.rfc-editor.org/info/rfc7591>.
[RFC7628]
Mills, W., Showalter, T., and H. Tschofenig, "A Set of Simple Authentication and Security Layer (SASL) Mechanisms for OAuth", RFC 7628, DOI 10.17487/RFC7628, , <https://www.rfc-editor.org/info/rfc7628>.
[RFC7636]
Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key for Code Exchange by OAuth Public Clients", RFC 7636, DOI 10.17487/RFC7636, , <https://www.rfc-editor.org/info/rfc7636>.
[RFC8126]
Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, , <https://www.rfc-editor.org/info/rfc8126>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8252]
Denniss, W. and J. Bradley, "OAuth 2.0 for Native Apps", BCP 212, RFC 8252, DOI 10.17487/RFC8252, , <https://www.rfc-editor.org/info/rfc8252>.
[RFC8414]
Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0 Authorization Server Metadata", RFC 8414, DOI 10.17487/RFC8414, , <https://www.rfc-editor.org/info/rfc8414>.
[RFC8620]
Jenkins, N. and C. Newman, "The JSON Meta Application Protocol (JMAP)", RFC 8620, DOI 10.17487/RFC8620, , <https://www.rfc-editor.org/info/rfc8620>.
[RFC8707]
Campbell, B., Bradley, J., and H. Tschofenig, "Resource Indicators for OAuth 2.0", RFC 8707, DOI 10.17487/RFC8707, , <https://www.rfc-editor.org/info/rfc8707>.
[RFC9207]
Meyer zu Selhausen, K. and D. Fett, "OAuth 2.0 Authorization Server Issuer Identification", RFC 9207, DOI 10.17487/RFC9207, , <https://www.rfc-editor.org/info/rfc9207>.
[RFC9449]
Fett, D., Campbell, B., Bradley, J., Lodderstedt, T., Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof of Possession (DPoP)", RFC 9449, DOI 10.17487/RFC9449, , <https://www.rfc-editor.org/info/rfc9449>.
[RFC9525]
Saint-Andre, P. and R. Salz, "Service Identity in TLS", RFC 9525, DOI 10.17487/RFC9525, , <https://www.rfc-editor.org/info/rfc9525>.
[RFC9700]
Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett, "Best Current Practice for OAuth 2.0 Security", BCP 240, RFC 9700, DOI 10.17487/RFC9700, , <https://www.rfc-editor.org/info/rfc9700>.
[RFC9728]
Jones, M.B., Hunt, P., and A. Parecki, "OAuth 2.0 Protected Resource Metadata", RFC 9728, DOI 10.17487/RFC9728, , <https://www.rfc-editor.org/info/rfc9728>.
[PSL]
Mozilla Foundation, "Public Suffix List", <https://publicsuffix.org/list/>.
[WebAuthn]
Hodges, J., Ed., Jones, J.C., Ed., Jones, M.B., Ed., Kumar, A., Ed., and E. Lundberg, Ed., "Web Authentication: An API for accessing Public Key Credentials - Level 2", W3C Recommendation, , <https://www.w3.org/TR/2021/REC-webauthn-2-20210408/>.
[OpenID.Core]
Sakimura, N., Bradley, J., Jones, M.B., de Medeiros, B., and C. Mortimore, "OpenID Connect Core 1.0", , <https://openid.net/specs/openid-connect-core-1_0.html>.
[OpenID.Discovery]
Sakimura, N., Bradley, J., Jones, M.B., and E. Jay, "OpenID Connect Discovery 1.0", , <https://openid.net/specs/openid-connect-discovery-1_0.html>.

7. Informative References

[RFC1939]
Myers, J. and M. Rose, "Post Office Protocol - Version 3", STD 53, RFC 1939, DOI 10.17487/RFC1939, , <https://www.rfc-editor.org/info/rfc1939>.
[RFC4791]
Daboo, C., Desruisseaux, B., and L. Dusseault, "Calendaring Extensions to WebDAV (CalDAV)", RFC 4791, DOI 10.17487/RFC4791, , <https://www.rfc-editor.org/info/rfc4791>.
[RFC5804]
Melnikov, A., Ed. and T. Martin, "A Protocol for Remotely Managing Sieve Scripts", RFC 5804, DOI 10.17487/RFC5804, , <https://www.rfc-editor.org/info/rfc5804>.
[RFC6352]
Daboo, C., "CardDAV: vCard Extensions to Web Distributed Authoring and Versioning (WebDAV)", RFC 6352, DOI 10.17487/RFC6352, , <https://www.rfc-editor.org/info/rfc6352>.
[RFC6409]
Gellens, R. and J. Klensin, "Message Submission for Mail", STD 72, RFC 6409, DOI 10.17487/RFC6409, , <https://www.rfc-editor.org/info/rfc6409>.
[RFC6819]
Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0 Threat Model and Security Considerations", RFC 6819, DOI 10.17487/RFC6819, , <https://www.rfc-editor.org/info/rfc6819>.
[RFC7009]
Lodderstedt, T., Ed., Dronia, S., and M. Scurtescu, "OAuth 2.0 Token Revocation", RFC 7009, DOI 10.17487/RFC7009, , <https://www.rfc-editor.org/info/rfc7009>.
[RFC8314]
Moore, K. and C. Newman, "Cleartext Considered Obsolete: Use of Transport Layer Security (TLS) for Email Submission and Access", RFC 8314, DOI 10.17487/RFC8314, , <https://www.rfc-editor.org/info/rfc8314>.
[RFC9051]
Melnikov, A., Ed. and B. Leiba, Ed., "Internet Message Access Protocol (IMAP) - Version 4rev2", RFC 9051, DOI 10.17487/RFC9051, , <https://www.rfc-editor.org/info/rfc9051>.
[I-D.ietf-mailmaint-pacc]
Eggert, D., Bucksch, B., and M. Diephouse, "Automatic Configuration of Email, Calendar, and Contact Server Settings", Work in Progress, Internet-Draft, draft-ietf-mailmaint-pacc-03, , <https://datatracker.ietf.org/doc/html/draft-ietf-mailmaint-pacc-03>.
[IANA.OAuth.Parameters]
IANA, "OAuth Parameters", <https://www.iana.org/assignments/oauth-parameters>.
[IANA.JOSE.ALGS]
IANA, "JSON Web Signature and Encryption Algorithms", <https://www.iana.org/assignments/jose>.

Authors' Addresses

Neil Jenkins (editor)
Fastmail
PO Box 234, Collins St West
Melbourne VIC 8007
Australia
Ben Bucksch
Beonex