<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-wullink-rpp-oauth2-transfer-00" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true" tocDepth="4">

<front>
<title abbrev="Secure Object Transfer for RPP">Secure Object Transfer for RESTful Provisioning Protocol (RPP)</title><seriesInfo value="draft-wullink-rpp-oauth2-transfer-00" stream="IETF" status="standard" name="Internet-Draft"></seriesInfo>
<author initials="M." surname="Wullink" fullname="Maarten Wullink"><organization>SIDN Labs</organization><address><postal><street></street>
</postal><email>maarten.wullink@sidn.nl</email>
<uri>https://sidn.nl/</uri>
</address></author><author initials="P." surname="Kowalik" fullname="Pawel Kowalik"><organization>DENIC</organization><address><postal><street></street>
</postal><email>pawel.kowalik@denic.de</email>
<uri>https://denic.de/</uri>
</address></author><date year="2026" month="July" day="7"></date>
<area>Internet</area>
<workgroup>Network Working Group</workgroup>

<abstract>
<t>This document describes how OAuth 2.0 <xref target="RFC6749"></xref> can be used to secure object transfers in RESTful Provisioning Protocol (RPP) <xref target="I-D.ietf-rpp-core"></xref>. It extends the RPP OAuth 2.0 authorization model defined in <xref target="I-D.wullink-rpp-oauth2"></xref> with mechanisms specific to federated object transfers.</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t><strong>NOTE:</strong> This is an early draft of how object transfer could work in RPP. It is included to illustrate the transfer flow and to facilitate discussion of the flow details and applicable security mechanisms. This document is expected to be significantly revised and updated as the transfer flow and security mechanisms are further developed and refined.</t>
<t>This document extends the core functionality of RPP with a secure mechanism for transferring objects between registrars. It is based on the OAuth 2.0 federation model, where the registry acts as a central trust anchor and the losing registrar's authorization server (AS) issues tokens that the registry can validate locally to authorize transfers. This provides a secure, scalable, and user-friendly mechanism for authorizing transfers without exposing sensitive information in transfer requests or responses. It also prevents the use of opaque transfer tokens and their inherent security risks, such as token leakage or replay attacks.</t>
<t>This document introduces new data objects, scopes and claims specific to the transfer flow. It defines two complementary transfer mechanisms: an interactive flow based on OAuth 2.0 federation for secure transfers with explicit registrant consent, and a fallback flow using opaque transfer tokens for transfers where interactive consent is not possible. The document also defines the trust model and security properties of the transfer mechanism.</t>
</section>

<section anchor="terminology"><name>Terminology</name>
<t>In this document the following terminology is used.</t>
<t>RPP server - An HTTP server responsible for processing requests and returning results in any supported media type.</t>
<t>JWT - JSON Web Token as defined in <xref target="RFC7519"></xref>.</t>
</section>

<section anchor="conventions-used-in-this-document"><name>Conventions Used in This Document</name>
<t>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;,&quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in <xref target="RFC2119"></xref>.</t>
<t>In examples, indentation and white space are provided only to illustrate element relationships and are not REQUIRED features of the protocol.</t>
<t>All example requests assume an RPP server using HTTP version 2 is listening on the standard HTTPS port on host rpp.example. An authorization token has been provided by an out-of-band process and MUST be used by the client to authenticate each request.</t>
</section>

<section anchor="object-transfer-details"><name>Object Transfer Details</name>
<t>In RPP, Object Transfer Details as described in <xref target="I-D.wullink-rpp-oauth2"></xref> are used for interactive federated object transfers to convey the specific domain name or contact handle being transferred. The gaining registrar includes an <tt>authorization_details</tt> object of type <tt>rpp_transfer</tt> in the authorization request to the losing registrar's AS. The registrant then sees exactly which object they are consenting to transfer. The AS MUST echo the <tt>authorization_details</tt> object back as a claim in the issued access token, giving the registry verifiable, tamper-proof evidence of what was authorized and for which object.</t>
<t>The <tt>type</tt> field MUST be set to <tt>rpp_transfer</tt>. Table <xref target="tbl-rar"></xref> lists the RAR fields defined for RPP.</t>
<table anchor="tbl-rar"><name>RPP Transfer Authorization, RAR <tt>authorization_details</tt> object (Primary Method, <xref target="RFC9396"></xref>)</name>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th>Requirement</th>
<th>Description</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>type</tt></td>
<td>String</td>
<td>REQUIRED</td>
<td>MUST be <tt>transfer</tt>.</td>
</tr>

<tr>
<td><tt>object_type</tt></td>
<td>String</td>
<td>REQUIRED</td>
<td>The RPP object type being transferred. MUST be one of <tt>domain</tt> or <tt>contact</tt>.</td>
</tr>

<tr>
<td><tt>object_identifier</tt></td>
<td>String</td>
<td>REQUIRED</td>
<td>The unique identifier of the specific object to be transferred (e.g., <tt>foo.example</tt> or <tt>CID-12345</tt>).</td>
</tr>
</tbody>
</table><t>Example RAR <tt>authorization_details</tt> value for a domain transfer:</t>

<sourcecode type="json"><![CDATA[[{
  "type": "transfer",
  "object_type": "domain",
  "object_identifier": "foo.example"
}]
]]>
</sourcecode>
<t>The losing registrar's AS MUST echo the <tt>authorization_details</tt> back as a claim in the issued JWT. The registry MUST validate the <tt>authorization_details</tt> claim in the token and MUST verify that <tt>object_type</tt> and <tt>object_identifier</tt> match the object being transferred.</t>
<t>When the losing registrar's AS does not support RAR (<xref target="RFC9396"></xref>), the specific object being transferred MUST be conveyed via the <tt>rpp_op_type</tt>, <tt>rpp_object_type</tt> and <tt>rpp_object_identifier</tt> claims rather than encoded in the <tt>authorization_details</tt> claim. The <tt>rpp_op_type</tt> claim MUST be set to <tt>transfer</tt>. The <tt>rpp_object_type</tt> claim MUST be set to the RPP object type being transferred (e.g., <tt>domain</tt> or <tt>contact</tt>). The <tt>rpp_object_identifier</tt> claim MUST be set to the fully qualified name or handle of the specific object being transferred (e.g., <tt>foo.example</tt> or <tt>CID-12345</tt>). The registry MUST validate that these claim values match the object being transferred.</t>
</section>

<section anchor="scopes"><name>Scopes</name>
<t>RPP OAuth 2.0 scopes are defined in <xref target="I-D.wullink-rpp-oauth2"></xref>. This document does not define new scopes; the existing <tt>transfer</tt> access level scope (e.g., <tt>domain:transfer</tt>) defined in <xref target="I-D.wullink-rpp-oauth2"></xref> MUST be used for transfer operations.</t>
</section>

<section anchor="claims"><name>Claims</name>
<t>In addition to the standard <xref target="RFC9068"></xref> claims, table <xref target="tbl-rpp-claims"></xref> lists the RPP-specific claims that are defined to enable fine-grained authorization decisions. Required claims MUST be present in every RPP access token. Optional claims SHOULD be included when applicable to the deployment or request context.</t>
<table anchor="tbl-rpp-claims"><name>RPP Specific Access Token Claims</name>
<thead>
<tr>
<th>Claim</th>
<th>Requirement</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>rpp_transfer_authinfo</tt></td>
<td>OPTIONAL</td>
<td>String</td>
<td>The transfer authorization information used in Fallback flow object transfer. When present, the value MUST be equivalent to the value that would otherwise be sent in the <tt>RPP-Authorization</tt> header <xref target="I-D.ietf-rpp-core"></xref>, using the same <tt>&lt;method&gt; &lt;authorization information&gt;</tt> format. The RPP server MUST treat this claim as equivalent to the <tt>RPP-Authorization</tt> header; if both are present in the same request, the claim value MUST take precedence. This claim MUST only be present in access tokens used for transfer operations.</td>
</tr>
</tbody>
</table></section>

<section anchor="data-objects"><name>Data Objects</name>
<t>The RPP Data Object Catalog is extended to include each registrar's AS metadata.</t>

<ul spacing="compact">
<li>Auth Server Metadata Object: This describes an <tt>authorization_server</tt> object for each registrar that operates its own AS. This object contains the necessary metadata for the gaining registrar to interact with the losing registrar's AS, including the authorization endpoint URI and JWKS URI or public key material.</li>
</ul>
</section>

<section anchor="trust-model"><name>Trust Model</name>
<t>The Secure Transfer depends on the OAuth 2.0 federation model, where the registry acts as the central trust anchor, operating as a hub-and-spoke topology. Registrars establish a trust relationship with the registry during accreditation; they do not need to establish direct trust relationships with each other. This allows any two registrars to participate in a Secure Transfer without any prior bilateral arrangement.</t>
<t><strong>Registry as trust anchor.</strong> As part of registrar onboarding, each registrar that operates its own AS (i.e., maintains registrant accounts) MUST register its AS metadata with the registry. This includes at minimum:</t>

<ul spacing="compact">
<li>The AS's authorization endpoint URI, used by the gaining registrar to construct the redirect.</li>
<li>The AS's JWKS endpoint URI or the public key material itself, used by the registry to validate tokens issued by that AS.</li>
</ul>
<t>The registry stores this metadata as part of the registrar's profile and makes it available via the discovery mechanism.</t>
<t><strong>Token validation without bilateral trust.</strong> When the registry receives a transfer request carrying a JWT issued by the losing registrar's AS, it validates the token locally using the losing registrar's public key that was registered at onboarding. No runtime call to the losing registrar or its AS is required. The registry already trusts that public key because it was registered through the accreditation process.</t>
<t><strong>Gaining registrar.</strong> The gaining registrar only needs to trust the registry. It obtains the losing registrar's AS URI from the registry's discovery endpoint, redirects the registrant's browser there, and exchanges the resulting authorization code for a token. It does not need to pre-configure or authenticate the losing registrar. The browser redirect and back-channel token exchange are both secured by standard HTTPS and do not require a federated identity relationship between the two registrars.</t>
<t><strong>Security properties.</strong> This model provides the following guarantees:</t>

<ul spacing="compact">
<li>No need for pre-established bilateral trust between registrars. Any two registrars can participate in a secure transfer as long as they both trust the registry.</li>
<li>The traditional transfer token is replaced with a signed JWT access token that the registry can validate locally, eliminating the risks of token leakage or replay attacks.</li>
<li>A rogue registrar cannot forge a transfer token that the registry will accept, because only the legitimate losing registrar's public key (registered at onboarding) can produce a valid signature.</li>
<li>The gaining registrar cannot forge registrant consent, because the token is issued by the losing registrar's AS, not the gaining registrar.</li>
<li>The registry controls the set of trusted ASs by controlling which registrar IdP metadata it accepts at onboarding.</li>
<li>Registrars need no knowledge of each other beyond what the registry exposes via the discovery endpoint.</li>
</ul>
</section>

<section anchor="object-transfer-flows"><name>Object Transfer Flows</name>
<t>The server MAY support a secure object transfer mechanism based on OAuth 2.0 federation for secure object transfer between registrars, the gaining registrar can obtain an access token from the losing registrar's AS to authorize the transfer request. This provides a secure mechanism for transferring objects without exposing sensitive information in the transfer request or response messages. This also prevents the use of opaque transfer tokens and their inherent security risks, such as token leakage or replay attacks.
If any of the parties in the transfer flow does not support the secure transfer mechanism based on OAuth 2.0 federation, then the transfer MUST fall back to the Fallback flow transfer mechanism using opaque transfer tokens, using the <tt>RPP-Authorization</tt> header to include the transfer token in the transfer request messages.</t>
<t>The two transfer mechanisms cover complementary scenarios:</t>

<ul>
<li><t><strong>Interactive flow (OAuth 2.0 federated):</strong> The current registrant has an account at the losing registrar and actively initiates or approves the transfer themselves — for example, a registrant migrating their own domain to a new registrar. The registrant authenticates at the losing registrar's AS and grants explicit, object-scoped consent.</t>
</li>
<li><t><strong>Fallback flow (authinfo):</strong> The losing registrar has not registered an AS URI with the registry, or the domain has been sold and the new owner has no account at the losing registrar. In this case interactive consent at the losing registrar is not possible. The seller (the previous owner, who does have an account at the losing registrar) obtains a transfer authorization code (authinfo) out-of-band and passes it to the buyer. The buyer provides the authinfo to the gaining registrar, which includes it in the transfer request via the <tt>RPP-Authorization</tt> header or the <tt>rpp_transfer_authinfo</tt> JWT claim. The registry validates the authinfo and executes the transfer without requiring the new owner to have any account at the losing registrar.</t>
</li>
</ul>
<t><strong>Flow selection is not at the discretion of the gaining registrar.</strong> The gaining registrar MUST use whichever flow the losing registrar's capabilities dictate, as determined by registry discovery. Specifically:</t>

<ul spacing="compact">
<li>If the registry's discovery endpoint returns an AS URI for the losing registrar, the gaining registrar MUST use the interactive OAuth 2.0 federated flow. Fallback flow MUST NOT be used as a substitute, even if it would be simpler to implement. The only exception is if the new owner is a different party than the previous owner (e.g., the domain was sold), in which case the gaining registrar MUST use Fallback flow because the new owner cannot authenticate to the losing registrar's AS to give consent.</li>
<li>If the registry's discovery endpoint returns no AS URI for the losing registrar, the gaining registrar MUST use Fallback flow.</li>
</ul>
<t>The registry MUST enforce this: if a Fallback flow transfer request (i.e., a request carrying an <tt>RPP-Authorization</tt> header or <tt>rpp_transfer_authinfo</tt> claim) is received for an object whose losing registrar has a registered AS URI, the registry MUST reject the request with an appropriate error response. This prevents downgrade attacks and ensures that registrars cannot bypass the stronger OAuth 2.0 flow for operational convenience once they have declared support for it.</t>
<t><strong>Token single-use enforcement.</strong> Access tokens issued by the losing registrar's AS for use in the interactive federated transfer flow MUST be single-use. The registry MUST reject any transfer request that presents a token that has already been used to authorize a transfer, even if the token has not yet expired. The losing registrar's AS MUST issue tokens with the intent of single use, and SHOULD include a unique <tt>jti</tt> (JWT ID) claim in each token to facilitate replay detection. The registry MUST maintain a short-lived cache of observed <tt>jti</tt> values and MUST reject any token whose <tt>jti</tt> has already been seen.</t>
<t>If the registry cannot enforce single-use semantics (e.g., due to lack of shared state in a distributed deployment), the token lifetime MUST be set as short as operationally feasible, on the order of a few seconds, to minimize the window of opportunity for replay attacks. Token lifetimes for interactive transfer tokens MUST NOT exceed 60 seconds.</t>
<t>For the secure transfer mechanism based on OAuth 2.0 federation, the RPP server requires an established trust relationship with the AS of the losing registrar. The server MUST support the necessary mechanisms for validating tokens issued by the losing registrar's AS.
This requires the server to support the JWT profile for OAuth 2.0 Access Tokens <xref target="RFC9068"></xref> and to support the necessary mechanisms for validating tokens issued by external ASs. The client MUST include a valid access token in the Authorization header of the transfer request, and the server MUST validate the token and the associated permissions before allowing the transfer to proceed. The server MUST also implement appropriate error handling for cases where the token is invalid, expired, or does not have the necessary permissions for the requested transfer operation. Registrars implementing secure transfer mechanisms based on OAuth 2.0 federation MUST support the federated identity provider function.</t>

<section anchor="interactive-flow"><name>Interactive Flow</name>
<t>The interactive flow uses the OAuth 2.0 Authorization Code grant <xref target="RFC6749" sectionFormat="bare" section="Section 4.1"></xref> to obtain explicit, object-specific registrant consent directly from the losing registrar's AS. Before redirecting the registrant, the gaining registrar MUST first query the RPP authorization server metadata endpoint to resolve the losing registrar's AS authorization URI. If no AS URI is available for the losing registrar, the gaining registrar MUST fall back to the Fallback flow described in <xref target="fallback-flow"></xref>.</t>
<t>The authorization request MUST convey the specific object being transferred so that the losing registrar's AS can present the registrant with an accurate consent screen. The <strong>primary method</strong> is Rich Authorization Requests (RAR) <xref target="RFC9396"></xref> as described in <xref target="object-transfer-details"></xref>. When the losing registrar's AS does not support RAR, the <strong>fallback method</strong> is to include the object identifier in the <tt>rpp_object_id</tt> claim.</t>
<t>The following diagram illustrates a successful interactive OAuth 2.0 federated secure object transfer, where both gaining and losing registrars support RAR and the registrant authenticates to the losing registrar to approve the transfer:</t>
<figure><name>OAuth 2.0 Federated Secure Object Transfer - Interactive Flow
</name>
<sourcecode type="ascii"><![CDATA[  Client          Gaining         Registry        Losing
(Registrant)    Registrar                        Registrar

     |               |               |               |
     | 1. Initiate   |               |               |
     |  transfer of  |               |               |
     |  foo.example  |               |               |
     +-------------->|               |               |
     |               |               |               |
     |               | 2. Lookup     |               |
     |               |  losing reg   |               |
     |               |  AS URI       |               |
     |               +-------------->|               |
     |               |               |               |
     |               | 3. Return     |               |
     |               |  losing reg   |               |
     |               |  AS URI       |               |
     |               |<--------------|               |
     |               |               |               |
     | 4. Redirect   |               |               |
     |  to Losing Reg|               |               |
     |  AS (RAR:     |               |               |
     |  authz_details|               |               |
     |  type=rpp_    |               |               |
     |  transfer,    |               |               |
     |  id=          |               |               |
         foo.example)|               |               |
     |               |               |               |
     |<--------------|               |               |
     |               |               |               |
     | 5. Auth &     |               |               |
     |  approve      |               |               |
     |  transfer at  |               |               |
     |  Losing Reg   |               |               |
     |  AS           |               |               |
     +---------------------------------------------->|
     |               |               |               |
     | 6. Auth code  |               |               |
     |  + redirect to|               |               |
     |  Gaining Reg  |               |               |
     |  callback URI |               |               |
     |<----------------------------------------------|
     |               |               |               |
     | 7. Follow     |               |               |
     |  redirect     |               |               |
     |  (auth code   |               |               |
     |  delivered)   |               |               |
     +-------------->|               |               |
     |               |               |               |
     |               | 8. Exchange   |               |
     |               |  auth code for|               |
     |               |  access token |               |
     |               +------------------------------>|
     |               |               |               |
     |               | 9. JWT token  |               |
     |               |  (authz_      |               |
     |               |  details=     |               |
     |               |  {type:rpp_   |               |
     |               |  transfer,    |               |
     |               |  id=          |               |
     |               |  foo.example) |               |
     |               |               |               |
     |               |<------------------------------|
     |               |               |               |
     |               | 10. Transfer  |               |
     |               |  request +    |               |
     |               |  Bearer token |               |
     |               +-------------->|               |
     |               |               |               |
     |               |               | 11. Local JWT |
     |               |               |  validation   |
     |               |               |  (losing reg  |
     |               |               |  AS pubkey,   |
     |               |               |  verify scope)|
     |               |               |               |
     |               |               | 12. Execute   |
     |               |               |  transfer &   |
     |               |               |  notify Losing|
     |               |               |  Registrar    |
     |               |               +-------------->|
     |               |               |               |
     |               | 13. Transfer  |               |
     |               |   successful  |               |
     |               |<--------------|               |
     |               |               |               |
     |  14. Transfer |               |               |
     |   confirmed   |               |               |
     |<--------------|               |               |
     |               |               |               |
]]>
</sourcecode>
</figure>
<t>The steps in the diagram are as follows:</t>

<ol spacing="compact">
<li>The client initiates a transfer request to the gaining registrar, specifying the object to transfer (e.g., <tt>foo.example</tt>).</li>
<li>The gaining registrar queries the registry's registrar discovery endpoint to look up the losing registrar's AS authorization URI. The losing registrar is identified from the current sponsoring registrar data on the domain.</li>
<li>The registry returns the losing registrar's AS authorization URI. If no URI is registered, the gaining registrar MUST fall back to the Fallback flow.</li>
<li>The gaining registrar redirects the client's browser to the losing registrar's AS. The authorization request MUST include an <tt>authorization_details</tt> parameter of type <tt>rpp_transfer</tt> with <tt>object_type: &quot;domain&quot;</tt> and <tt>object_identifier: &quot;foo.example&quot;</tt>.</li>
<li>The client authenticates at the losing registrar's AS and explicitly approves the transfer scope, providing direct, verifiable consent to release the specific object.</li>
<li>The losing registrar's AS issues an authorization code and redirects the client's browser back to the gaining registrar's registered callback URI.</li>
<li>The client's browser follows the redirect, delivering the authorization code to the gaining registrar's callback endpoint.</li>
<li>The gaining registrar exchanges the authorization code for an access token at the losing registrar's AS token endpoint.</li>
<li>The losing registrar's AS validates the code and issues a signed JWT access token (<xref target="RFC9068"></xref>). When RAR was used, the token MUST contain an <tt>authorization_details</tt> claim echoing the <tt>rpp_transfer</tt> object.</li>
<li>The gaining registrar submits the transfer request to the registry, including the JWT as a Bearer token in the <tt>Authorization</tt> header.</li>
<li>The registry validates the JWT locally using the losing registrar's AS public key (obtained via OAuth 2.0 AS Metadata <xref target="RFC8414"></xref>). No live call to the losing registrar is required. The registry MUST verify the transfer authorization using the appropriate method: if the token contains an <tt>authorization_details</tt> claim (RAR), the registry MUST verify that the <tt>type</tt> is <tt>rpp_transfer</tt> and that <tt>object_identifier</tt> matches the object being transferred.</li>
<li>The registry executes the transfer and notifies the losing registrar.</li>
<li>The registry returns a successful transfer response to the gaining registrar.</li>
<li>The gaining registrar confirms the completed transfer to the client.</li>
</ol>
</section>

<section anchor="fallback-flow"><name>Fallback Flow</name>
<t>The Fallback flow uses opaque transfer authorization tokens to authorize object transfers between registrars. The gaining registrar obtains the transfer authorization token out-of-band from the losing registrar (e.g., via the registrant or a prior registrar-to-registrar agreement) and includes it in the transfer request. No OAuth 2.0 federation or end-user interaction is required. The registry validates the opaque token against the losing registrar's records to authorize the transfer.</t>
<t>The transfer authorization token MUST be conveyed using the <tt>rpp_transfer_authinfo</tt> claim embedded in a JWT access token.</t>
<t>The following diagram illustrates the machine-to-machine Fallback flow for a secure object transfer:</t>
<figure><name>Fallback Object Transfer - Machine to Machine flow
</name>
<sourcecode type="ascii"><![CDATA[  Client          Gaining         Registry        Losing
(Registrant)    Registrar                        Registrar
     |               |               |               |
     |   1. Initiate |               |               |
     |    transfer   |               |               |
     |   (authz token|               |               |
     |    provided   |               |               |
     |    out-of-band|               |               |
     |    by losing  |               |               |
     |    registrar) |               |               |
     +-------------->|               |               |
     |               |               |               |
     |               | 2. Transfer   |               |
     |               |  request      |               |
     |               |  (RPP-Authori-|               |
     |               |   zation:     |               |
     |               |   <token>)    |               |
     |               +-------------->|               |
     |               |               |               |
     |               |               | 3. Validate   |
     |               |               |  authz token  |
     |               |               |               |
     |               |               | 4. Execute    |
     |               |               |  transfer &   |
     |               |               |  notify Losing|
     |               |               |  Registrar    |
     |               |               +-------------->|
     |               |               |               |
     |               | 5. Transfer   |               |
     |               |   successful  |               |
     |               |<--------------|               |
     |               |               |               |
     |  6. Transfer  |               |               |
     |   confirmed   |               |               |
     |<--------------|               |               |
     |               |               |               |
]]>
</sourcecode>
</figure>
<t>The steps in the diagram are as follows:</t>

<ol spacing="compact">
<li>The client initiates a transfer request to the gaining registrar, providing the transfer authorization token that was obtained out-of-band from the losing registrar (e.g., via the registrant or a prior registrar-to-registrar agreement).</li>
<li>The gaining registrar submits the transfer request to the registry, including the opaque authorization token in the <tt>RPP-Authorization</tt> header.</li>
<li>The registry validates the authorization token against the losing registrar's records.</li>
<li>The registry executes the transfer and notifies the losing registrar.</li>
<li>The registry returns a successful transfer response to the gaining registrar.</li>
<li>The gaining registrar confirms the completed transfer to the client.</li>
</ol>
</section>
</section>

<section anchor="iana-considerations"><name>IANA Considerations</name>
<t>TODO</t>
</section>

<section anchor="internationalization-considerations"><name>Internationalization Considerations</name>
<t>TODO</t>
</section>

<section anchor="security-considerations"><name>Security Considerations</name>
<t>TODO</t>
</section>

<section anchor="change-history"><name>Change History</name>

<section anchor="version-00"><name>Version 00</name>

<ul spacing="compact">
<li>Created initial draft with core concepts and flows.</li>
</ul>
</section>
</section>

</middle>

<back>
<references><name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-rpp-core.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.wullink-rpp-oauth2.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6749.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7519.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8414.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9068.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9396.xml"/>
</references>

<section anchor="acknowledgements" numbered="false"><name>Acknowledgements</name>
<t>TODO</t>
</section>

</back>

</rfc>
