<?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-jscontact-profile-00" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true" tocDepth="4">

<front>
<title abbrev="JSContact Profile for RPP">JSContact Profile for RESTful Provisioning Protocol (RPP)</title><seriesInfo value="draft-wullink-rpp-jscontact-profile-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="6"></date>
<area>Internet</area>
<workgroup>Network Working Group</workgroup>

<abstract>
<t>This document defines a JSContact usage profile, conforming to the rules described in <xref target="I-D.ietf-calext-jscontact-profiles"></xref>, for the RESTful Provisioning Protocol (RPP). The JSContact Profile for RPP specifies how the JSContact format defined in <xref target="RFC9982"></xref> can be used as a standardized representation of contact information within RPP operations, enabling interoperability and consistency across RPP implementations that manage contact data.</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t>JSContact <xref target="RFC9982"></xref> is a flexible, JSON-based format for representing contact
information. Its flexibility allows the same data to be expressed in multiple
valid ways, which can hinder interoperability in a provisioning context where
data must be stored and interpreted consistently.</t>
<t>This document defines a JSContact usage profile for the RESTful Provisioning
Protocol (RPP), restricting the set of JSContact constructs that RPP clients and
servers are required to support when provisioning contact information.</t>

<section anchor="relationship-to-the-rdap-jscontact-profile"><name>Relationship to the RDAP JSContact Profile</name>
<t>The Registration Data Access Protocol (RDAP) <xref target="RFC9083"></xref> provides read-only
access to registration data managed by RPP. Both protocols use JSContact for
contact representation, but with profiles suited to their respective roles.</t>
<t>The RDAP JSContact profile <xref target="I-D.ietf-regext-rdap-jscontact"></xref> defines the
constructs used when serving registration data to read-only consumers. The RPP
profile defined in this document is a superset: all JSContact constructs
permitted by the RDAP profile are also permitted in RPP.</t>
<t>The converse does not hold. RPP supports additional JSContact constructs
required for provisioning that have no meaningful equivalent in a read-only
The RDAP JSContact profile <xref target="I-D.ietf-regext-rdap-jscontact"></xref> defines the constructs used when serving registration data to read-only consumers. The RPP profile, defined in this document, is a subset of these constructs. All JSContact constructs permitted by the RPP profile can be used for RDAP.</t>
<t>The converse does not hold. RDAP supports additional JSContact constructs that are useful in the read-only context of RDAP responses but that may hinder interoperability. These constructs are not present in RPP requests and responses.</t>
</section>
</section>

<section anchor="terminology"><name>Terminology</name>
<t>In this document, the following terminology is used.</t>
<t>RESTful Provisioning Protocol or RPP - The protocol described in this document.</t>
<t>URL - A Uniform Resource Locator as defined in <xref target="RFC3986"></xref>.</t>
<t>RPP client - An HTTP user agent performing an RPP request.</t>
<t>RPP server - An HTTP server responsible for processing requests and returning results in any supported media type.</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>
</section>

<section anchor="using-jscontact-in-rpp"><name>Using JSContact in RPP</name>

<section anchor="jscontact-profile-for-rpp"><name>JSContact Profile for RPP</name>
<t>Since JSContact is a generalized representation of contact data, many of its
capabilities are not optimized for interoperable use in RPP payloads. This
document therefore defines a usage profile for JSContact that simplifies
implementation for both RPP clients and RPP servers.</t>
<t>The JSContact profile for RPP is compliant with the rules described in
<xref target="I-D.ietf-calext-jscontact-profiles"></xref>. The profile properties are formally
listed in <xref target="profile-properties"></xref>. All types mentioned in this section refer to
the JSContact specification <xref target="RFC9982"></xref>.</t>

<section anchor="version"><name>Version</name>
<t>The Card &quot;version&quot; member value MUST be &quot;2.0&quot;.</t>
</section>

<section anchor="kind"><name>Kind</name>
<t>The Card &quot;kind&quot; member value MUST be &quot;individual&quot; (default) or &quot;org&quot; to
represent an individual or an organization, respectively.</t>
</section>

<section anchor="language"><name>Language</name>
<t>The Card &quot;language&quot; member SHOULD be set when localizations are specified
(i.e., when the &quot;localizations&quot; member is present and non-null).</t>
</section>

<section anchor="name"><name>Name</name>
<t>The Card &quot;name&quot; member MUST include only the &quot;full&quot; member and MUST NOT include the &quot;components&quot; member.</t>
</section>

<section anchor="organizations"><name>Organizations</name>
<t>The Organization type MUST include only the &quot;org&quot; member.</t>
</section>

<section anchor="addresses"><name>Addresses</name>
<t>The Address type MUST only use the &quot;components&quot; member.</t>
<t>The AddressComponent MUST include only the &quot;kind&quot; and &quot;value&quot; members. The &quot;kind&quot; member value MUST only use &quot;name&quot;, &quot;locality&quot;, &quot;region&quot;, or &quot;postcode&quot;.</t>
<t>When both an internationalized and a localized version of an address are used, the localized version MUST be placed in the <tt>localizations</tt> map keyed by an appropriate <xref target="BCP47"></xref> language tag.</t>
</section>

<section anchor="emails"><name>Emails</name>
<t>The EmailAddress type MUST include only the &quot;address&quot; member.</t>
</section>

<section anchor="phones"><name>Phones</name>
<t>The Phone type MUST include the &quot;number&quot; member and MAY include the &quot;features&quot;
member. When the &quot;features&quot; member is present, its values MUST be &quot;voice&quot; or
&quot;fax&quot;. When the &quot;features&quot; member is absent, the phone number is assumed to be
a voice number.</t>
</section>

<section anchor="links"><name>Links</name>
<t>The Link type MUST include the &quot;uri&quot; member and MAY include the &quot;kind&quot; member.
When the &quot;kind&quot; member is present, its value MUST be &quot;contact&quot;.</t>
</section>

<section anchor="map-keys"><name>Map Keys</name>
<t>A JSContact map key MUST comply with the Id type definition in <xref target="RFC9553"></xref>. RPP implementations MUST use the following predefined keys:</t>

<ul spacing="compact">
<li>&quot;org&quot; in the &quot;organizations&quot; map for a single preferred organization.</li>
<li>&quot;addr&quot; in the &quot;addresses&quot; map for a single preferred postal address.</li>
<li>&quot;email&quot; in the &quot;emails&quot; map for the preferred email address.
</li>
<li>&quot;voice&quot; in the &quot;phones&quot; map for the preferred voice number.
</li>
<li>&quot;fax&quot; in the &quot;phones&quot; map for the preferred fax number.
</li>
<li>&quot;url&quot; in the &quot;links&quot; map for a preferred contact URL; the &quot;kind&quot; member of
the Link object MUST NOT be set.</li>
<li>&quot;contact-uri&quot; in the &quot;links&quot; map for a contact URI; the &quot;kind&quot; member of
the Link object MUST be set to &quot;contact&quot;.</li>
</ul>
<t>When internationalized and localized versions of an organization, postal address, or email exist, the internationalized version MUST be included under
the predefined map key, while the localized version MUST be placed in the &quot;localizations&quot; map as described in <xref target="localizations"></xref>.</t>
</section>

<section anchor="localizations"><name>Localizations</name>
<t>If present, localized variants of name, organization, postal address, and email MUST be added to the &quot;localizations&quot; map. RPP implementations MUST
expand all localizations, meaning a nested PatchObject key of the form &quot;{key1}/{key2}/.../{keyN}&quot; MUST NOT be used.</t>
<t>The number of provided localizations MUST NOT exceed the number of languages supported by the RPP server. The language of each localization MUST be indicated by a <xref target="BCP47"></xref> language tag as the key in the &quot;localizations&quot; map.</t>
<t>The following example of a Card includes a localized version of the postal address:</t>
<figure><name>Example of handling localizations in JSContact
</name>
<sourcecode type="json"><![CDATA[{
  "@type": "Card",
  "version": "2.0",
  "language": "en",
  "name": {
    "full": "Joe User"
  },
  "organizations": {
    "org": { "name": "Example Org" }
  },
  "addresses": {
    "addr": {
      "components": [
        { "kind": "name",     "value": "Main Street 1" },
        { "kind": "locality", "value": "Ludwigshafen am Rhein" },
        { "kind": "region",   "value": "Rhineland-Palatinate" },
        { "kind": "postcode", "value": "67067" }
      ],
      "countryCode": "DE"
    }
  },
  "localizations": {
    "de": {
      "addresses": {
        "addr": {
          "components": [
            { "kind": "name",     "value": "Hauptstraße 1" },
            { "kind": "locality", "value": "Ludwigshafen am Rhein" },
            { "kind": "region",   "value": "Rheinland-Pfalz" },
            { "kind": "postcode", "value": "67067" }
          ],
          "countryCode": "DE"
        }
      }
    }
  }
}
]]>
</sourcecode>
</figure>
</section>

<section anchor="profile-properties"><name>Profile Properties</name>
<t>The properties of the JSContact profile for RPP registered in the JSContact
Profile registry as described in <xref target="jscontact-profile-registry"></xref> are:</t>
<t>| Property    | Context          | Restricted  | Restricted Enum                          |</t>
<table>
<thead>
<tr>
<th align="left"></th>
<th align="left"></th>
<th align="left">Attributes</th>
<th align="left">Values</th>
</tr>
</thead>

<tbody>
<tr>
<td align="left">language</td>
<td align="left">Card</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">kind</td>
<td align="left">Card</td>
<td align="left"></td>
<td align="left">individual, org</td>
</tr>

<tr>
<td align="left">name</td>
<td align="left">Card</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">full</td>
<td align="left">Name</td>
<td align="left">mandatory</td>
<td align="left"></td>
</tr>

<tr>
<td align="left">organizations</td>
<td align="left">Card</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">name</td>
<td align="left">Organization</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">addresses</td>
<td align="left">Card</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">full</td>
<td align="left">Address</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">countryCode</td>
<td align="left">Address</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">components</td>
<td align="left">Address</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">kind</td>
<td align="left">AddressComponent</td>
<td align="left"></td>
<td align="left">name, locality, region, postcode</td>
</tr>

<tr>
<td align="left">value</td>
<td align="left">AddressComponent</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">emails</td>
<td align="left">Card</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">address</td>
<td align="left">EmailAddress</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">phones</td>
<td align="left">Card</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">features</td>
<td align="left">Phone</td>
<td align="left"></td>
<td align="left">voice, fax</td>
</tr>

<tr>
<td align="left">number</td>
<td align="left">Phone</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">links</td>
<td align="left">Card</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">kind</td>
<td align="left">Link</td>
<td align="left"></td>
<td align="left">contact</td>
</tr>

<tr>
<td align="left">uri</td>
<td align="left">Link</td>
<td align="left"></td>
<td align="left"></td>
</tr>

<tr>
<td align="left">localizations</td>
<td align="left">Card</td>
<td align="left"></td>
<td align="left">yes</td>
</tr>
</tbody>
</table><t>Client validation MUST return an error if any JSContact properties other than those listed above are present.</t>
</section>
</section>
</section>

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

<section anchor="jscontact-profile-registry"><name>JSContact Profile Registry</name>
<t>IANA is requested to register the following entry in the &quot;JSContact Profile&quot; registry [I-D.ietf-calext-jscontact-profiles]:</t>
<t>Name: rpp
Profile Version: 1.0
Reference: This document</t>
<t>TODO</t>
</section>
</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>

</middle>

<back>
<references><name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml9/reference.BCP.47.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-calext-jscontact-profiles.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-regext-rdap-jscontact.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.3986.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9083.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9553.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9982.xml"/>
</references>

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

</back>

</rfc>
