<?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-newton-regext-rdap-simple-redaction-00" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true">

<front>
<title abbrev="simple-redaction">RDAP Simple Redaction</title><seriesInfo value="draft-newton-regext-rdap-simple-redaction-00" stream="IETF" status="standard" name="Internet-Draft"></seriesInfo>
<author initials="A." surname="Newton" fullname="Andy Newton"><organization>ICANN</organization><address><postal><street></street>
</postal><email>andy@hxr.us</email>
</address></author><date/>
<area>Applications and Real-Time Area (ART)</area>
<workgroup>Registration Protocols Extensions (regext)</workgroup>

<abstract>
<t>This document defines a simple redaction extension for the Registration Data Access Protocol
(RDAP).</t>
</abstract>

</front>

<middle>

<section anchor="background"><name>Background</name>
<t>This document defines &quot;simple redaction&quot;, an extension for redacting information from Registration
Data Access Protocol (RDAP) response. Simple redaction only defines redaction in JSON strings of RDAP responses. This narrowed
scope meets the purposes of known redaction policies, such as the
<eref target="https://www.icann.org/resources/pages/registration-data-policy-2024-02-21-en">ICANN Registration Data Policy</eref>,
where redaction is applied against &quot;personal data&quot; which is only found in JSON strings in the
RDAP specification (<xref target="RFC9083"></xref>). The only place in RDAP where booleans or integers are used in the
base specification of <xref target="RFC9083"></xref> are in the DNSSEC portion of the domain object class, and there
is unlikely to be policy for redaction of such information as it also visible in the public DNS.</t>
<t>This specification does not require the removal of JSON values or components that
would otherwise make the resulting JSON invalid according to <xref target="RFC9083"></xref> nor syntactically invalid according
to <xref target="RFC9083"></xref> or <xref target="RFC7095"></xref>. Therefore, the resulting responses are syntactically valid but semantically
redacted.</t>
<t>Finally, this specification has the benefit that if an RDAP client does not recognize this extension
and simply passes the redaction signals onto the user, in some contexts the user may still understand that the
information is redacted.</t>
<t>The following is an example of an RDAP response using simple redaction:</t>

<artwork><![CDATA[{
  "rdapConformance" : [ "Rdap_level_0", “simpleRedaction” ],
  "objectClassName" : "entity",
  "handle":"////REDACTED_HANDLE////",
  "vcardArray":[
    "vcard",
    [
      ["version", {}, "text", "4.0"],
      ["fn", {}, "text", "////REDACTED_FULL_NAME////"],
      ["email",
        { "type":"work" },
        "text", "redacted_email@redacted.invalid"
      ]
    ]
  ],
  “simpleRedaction”: [
    { “key”: “////REDACTED_HANDLE////” },
    { “key”: “////REDACTED_FULL_NAME////” },
    { “key”: “redacted_email@redacted.invalid” }
  ]
}

]]>
</artwork>
</section>

<section anchor="redaction_keys"><name>Redaction Keys</name>
<t>Simple redaction allows a server to define a set of keys, each used to signify when data in a string
has been redacted. Clients use these keys to identify the information being redacted.</t>

<section anchor="unstructured_keys"><name>Unstructured Text</name>
<t>Keys signifying redaction for unstructured text, i.e. free form text, take the form of <tt>////REDACTION_KEY////</tt>.
These keys begin with four forward-slash character (&quot;////&quot;), followed by one or more of the upper and lower case characters
<tt>A</tt> through <tt>Z</tt>, <tt>0</tt> through <tt>9</tt>, hyphen (&quot;-&quot;), or under-bar (&quot;_&quot;), followed by four more forward-slash characters.</t>
<t>The following example demonstrates redaction of the full name value from a jCard (<xref target="RFC7095"></xref>) array:</t>

<artwork><![CDATA[["fn", {}, "text", "////REDACTED_FULL_NAME////"]    
]]>
</artwork>
<t>These keys may be placed in a string with other characters thus allowing for the partial redaction of a string:</t>

<artwork><![CDATA["Alice ////LAST_NAME_REDACTION////"
]]>
</artwork>
</section>

<section anchor="tel_uri_keys"><name>TEL URIs</name>
<t>Keys for use in &quot;tel&quot; URIs (<xref target="RFC3966"></xref>) follow a form similar to <xref target="unstructured_keys"></xref> but with a restricted
set of characters to conform to the &quot;tel&quot; URI syntax. These keys begin and end with four forward-slash characters,
but the set of characters allowed between the slashes is limited to <tt>0</tt> through <tt>9</tt>. For example:
<tt>////0123456789////</tt>.</t>
<t>The following is an example of a &quot;tel&quot; URI used in a jCard array:</t>

<artwork><![CDATA[["tel", {}, "uri", "tel:+////0000000////;ext=////999999////"]    
]]>
</artwork>
<t>The above is just an example, but <xref target="RFC6530"></xref>, which defines the structures in <xref target="RFC7095"></xref>, does
not require the &quot;tel&quot; property to be a URI. So this maybe written as:</t>

<artwork><![CDATA[["tel", {}, "text", "////TELEPHONE_REDACTION////"]    
]]>
</artwork>
</section>

<section anchor="email-addresses"><name>Email Addresses</name>
<t>Keys for email addresses MUST use a host part that is &quot;redacted.invalid&quot; but may use any local part
allowable in an email address. For example: <tt>redacted_email@redacted.invalid</tt>.</t>
<t>The &quot;.invalid&quot; TLD is a special-use domain defined in <xref target="RFC6761"></xref> and is unusable on the Internet.</t>
</section>

<section anchor="uris-with-host-names"><name>URIs with Host Names</name>
<t>Keys used in a URI with host names, such as an HTTP URI, MUST use a host name that is &quot;redacted.invalid&quot;.
For example: <tt>https://redacted.invalid/redacted_web_page</tt>.</t>
<t>The &quot;.invalid&quot; TLD is a special-use domain defined in <xref target="RFC6761"></xref> and is unusable on the Internet.</t>
</section>
</section>

<section anchor="explicity_keying"><name>Explicit Keying</name>
<t>All redaction keys (<xref target="redaction_keys"></xref>) are explicitly specified by the server.</t>

<section anchor="simple_redaction_array"><name>The &quot;simpleRedaction&quot; Array</name>
<t>Each defined key MUST be given in the &quot;simpleRedaction&quot; array value. This array contains JSON objects.
Each JSON object has a REQUIRED JSON string named &quot;key&quot;, a JSON array named &quot;reasons&quot;, and an OPTIONAL
&quot;links&quot; array as defined by <xref target="RFC9083"></xref> (see <xref target="alternates"></xref> and <xref target="policy"></xref> on usage).
The &quot;reasons&quot; array is OPTIONAL but if present MUST NOT be empty.</t>
<t>The &quot;reasons&quot; array contains JSON objects. These objects SHOULD have a &quot;lang&quot; member as defined
by <xref target="RFC9083"></xref> and MUST have a JSON array named &quot;description&quot;. The &quot;description&quot; array contains
only JSON strings.</t>
<t>The following is an example:</t>

<artwork><![CDATA[“simpleRedaction”: [
  {
    “key”: “////REDACTED_FULL_NAME////”,
    “reasons” : [
      {
        “lang”: “en”,
        “description” : [
          “The full name of registrants has not been given.”,
          “This redaction is done according to policy.”
        ]
      },
      {
        “lang”: “ja”,
        “description” : [
          “登録者のフルネームは公表されていない。”,
          “この編集はポリシーに従って行われます。”
        ]
      }
    ],
    "links": [
      {
        "value": "https://example.com/value",
        "rel": "about",
        "href": "https://example.com/some-policy.html",
        "type": "text/html"
      }
    ]
  }
]
]]>
</artwork>
<t>A key MAY be used more than once in an RDAP object, but it MUST only appear once in the &quot;simpleRedaction&quot; array
of objects. A client MUST NOT consider any key not found to be the &quot;simpleRedaction&quot; array of objects as a valid
redaction (i.e. do not signal to the user that the information has been redacted).</t>
<t>The &quot;simpleRedaction&quot; JSON value MUST only be in the top-most object of the RDAP response.</t>
</section>

<section anchor="alternates"><name>Alternates</name>
<t>The &quot;simpleRedaction&quot; array described in <xref target="simple_redaction_array"></xref> allows each key to be accompanied by
an array of links, as defined by <xref target="RFC9083"></xref>. Usage of the links may be used to signal an alternate
usage in cases where the alternate can be expressed as a URI. To do this, servers MUST use the &quot;alternate&quot;
link relation and clients SHOULD signal to users that the &quot;href&quot; value is available for alternate usage.</t>
<t>The following example demonstrates the signaling on a web-based contact form to be used instead of email.</t>

<artwork><![CDATA[{
  "rdapConformance" : [ "Rdap_level_0", “simpleRedaction” ],
  "objectClassName" : "entity",
  "handle":"foo",
  "vcardArray":[
    "vcard",
    [
      ["version", {}, "text", "4.0"],
      ["fn", {}, "text", "Bob Allison"],
      ["email",
        { "type":"work" },
        "text", "redacted_email@redacted.invalid"
      ]
    ]
  ],
  “simpleRedaction”: [
    { 
      “key”: “redacted_email@redacted.invalid”,
      "links": [
        {
          "value": "https://example.com/value",
          "rel": "alternate",
          "href": "https://example.com/contact-form",
          "type": "text/html"
        }
      ]
    }
  ]
}
]]>
</artwork>
<t>This example demonstrates signaling that an alternate email address is to be used.</t>

<artwork><![CDATA[{
  "rdapConformance" : [ "Rdap_level_0", “simpleRedaction” ],
  "objectClassName" : "entity",
  "handle":"foo",
  "vcardArray":[
    "vcard",
    [
      ["version", {}, "text", "4.0"],
      ["fn", {}, "text", "Bob Allison"],
      ["email",
        { "type":"work" },
        "text", "redacted_email@redacted.invalid"
      ]
    ]
  ],
  “simpleRedaction”: [
    { 
      “key”: “redacted_email@redacted.invalid”,
      "links": [
        {
          "value": "https://example.com/value",
          "rel": "alternate",
          "href": "mailto:proxy-service@example.com"
        }
      ]
    }
  ]
}
]]>
</artwork>
<t>Clients should consider, when presenting information to a user,
that an alternate use may differ from the form in the RDAP response. For example,
the RDAP response may contain an email address but the alternate usage is a web page.</t>
</section>

<section anchor="policy"><name>Redaction Policy</name>
<t>The &quot;links&quot; array described in <xref target="simple_redaction_array"></xref> may also be used to link to a web page
describing the redaction policy. When the array is to be used for this purpose, the &quot;about&quot; relationship
MUST be used. The following is an example.</t>

<artwork><![CDATA[{
  "rdapConformance" : [ "Rdap_level_0", “simpleRedaction” ],
  "objectClassName" : "entity",
  "handle":"foo",
  "vcardArray":[
    "vcard",
    [
      ["version", {}, "text", "4.0"],
      ["fn", {}, "text", "Bob Allison"],
      ["email",
        { "type":"work" },
        "text", "redacted_email@redacted.invalid"
      ]
    ]
  ],
  “simpleRedaction”: [
    { 
      “key”: “redacted_email@redacted.invalid”,
      "links": [
        {
          "value": "https://example.com/value",
          "rel": "about",
          "href": "https://example.com/some-policy.html",
          "type": "text/html"
        }
      ]
    }
  ]
}
]]>
</artwork>
</section>

<section anchor="keying-strategies"><name>Keying Strategies</name>

<section anchor="unclean-data"><name>Unclean Data</name>
<t>While it seems odd that some users would be allowed to give an email address with a host of
&quot;redacted.invalid&quot; or a string that begins and ends with four forward-slashes to an Internet
registration authority, some registries must deal with such data for various reasons.</t>
<t>One strategy servers may use would be to append a set of random characters to each key. For example,
if a registered resource was given as &quot;////I-fooled-you////&quot; then the server could thwart this
by appending the random characters &quot;1234-NO-YOU-DID-NOT&quot; to make the key &quot;////I-fooled-you_1234-NO-YOU-DID-NOT////&quot;.</t>
</section>

<section anchor="handles"><name>Handles</name>
<t>For servers operating under policies in which the &quot;handle&quot;, as defined by <xref target="RFC9083"></xref> must be
redacted, it would be beneficial to some clients to create unique redaction keys for each handle.
While clients SHOULD use &quot;self&quot; links, as described in <xref target="RFC9083"></xref>, to differentiate between
between objects returned in a response, in the absence of &quot;self&quot; links they often use the &quot;handle&quot;.
Therefore, servers SHOULD create a unique redaction key for each handle that is redacted.</t>
</section>
</section>
</section>

<section anchor="examples"><name>Examples</name>

<section anchor="unstructured-addresses"><name>Unstructured Addresses</name>
<t><xref target="RFC7095"></xref> allows for the representation of unstructured postal addresses. The following is a simple
example of an RDAP response with simple redactions where the postal address is given as
unstructured.</t>

<artwork><![CDATA[{
  "rdapConformance" : [ "Rdap_level_0", “simpleRedaction” ],
  "objectClassName" : "entity",
  "handle":"foo",
  "vcardArray":[
    "vcard",
    [
      ["version", {}, "text", "4.0"],
      ["fn", {}, "text", "Bob"],
      ["adr",
        {

          "type":"home",
          "label":"////REDACTED_STREET////\nVancouver\nBC\n////REDACTED_POSTAL_CODE////\n"
        },
        "text",
        [
          "", "", "", "", "", "", ""
        ]
      ],
    ]
  ],
  “simpleRedaction”: [
    { “key”: “////REDACTED_STREET////” },
    { “key”: “////REDACTED_POSTAL_CODE////” },
  ]
}
]]>
</artwork>
</section>

<section anchor="structured-addresses"><name>Structured Addresses</name>
<t><xref target="RFC7095"></xref> allows for the representation of structured postal addresses. The following is a simple
example of an RDAP response with simple redactions where the postal address is given as
structured.</t>

<artwork><![CDATA[{
  "rdapConformance" : [ "Rdap_level_0", “simpleRedaction” ],
  "objectClassName" : "entity",
  "handle":"foo",
  "vcardArray":[
    "vcard",
    [
      ["version", {}, "text", "4.0"],
      ["fn", {}, "text", "Bob"],
      ["adr",
        { "type":"work" },
        "text",
        [
          "",
          "////REDACTED_STREET////",
          "////REDACTED_STREET////",
          "Quebec",
          "QC",
          "////REDACTED_POSTAL_CODE////",
          "Canada"
        ]
      ]
    ]
  ],
  “simpleRedaction”: [
    { “key”: “////REDACTED_STREET////” },
    { “key”: “////REDACTED_POSTAL_CODE////” },
  ]
}
]]>
</artwork>
</section>

<section anchor="a-complete-example"><name>A Complete Example</name>
<t>The following is an example an RDAP response to a domain lookup in which the redactions
specified in
<eref target="https://www.icann.org/resources/pages/registration-data-policy-2024-02-21-en">ICANN Registration Data Policy</eref>,
have been applied.</t>

<artwork><![CDATA[{
  "rdapConformance": [
    "rdap_level_0", "simpleRedaction"
  ],
  "objectClassName": "domain",
  "handle": "////REGISTRY_DOMAIN_ID_REDACTION////",
  "ldhName": "example.com",
  "secureDNS": {
    "delegationSigned": false
  },
  "notices": [
    {
      "title": "Terms of Use",
      "description": [
        "Service subject to Terms of Use."
      ],
      "links": [
        {
          "rel": "self",
          "href": "https://www.example.com/terms-of-use",
          "type": "text/html",
          "value": "https://www.example.com/terms-of-use"
        }
      ]
    }
  ],
  "nameservers": [
    {
      "objectClassName": "nameserver",
      "ldhName": "ns1.example.com"
    },
    {
      "objectClassName": "nameserver",
      "ldhName": "ns2.example.com"
    }
  ],
  "entities": [
    {
      "objectClassName": "entity",
      "handle": "123",
      "roles": [
        "registrar"
      ],
      "publicIds": [
        {
          "type": "IANA Registrar ID",
          "identifier": "1"
        }
      ],
      "vcardArray": [
        "vcard",
        [
          [
            "version",
            {},
            "text",
            "4.0"
          ],
          [
            "fn",
            {},
            "text",
            "Example Registrar Inc."
          ],
          [
            "adr",
            {},
            "text",
            [
              "",
              "Suite 100",
              "123 Example Dr.",
              "Dulles",
              "VA",
              "20166-6503",
              "US"
            ]
          ],
          [
            "email",
            {},
            "text",
            "contact@organization.example"
          ],
          [
            "tel",
            {
              "type": "voice"
            },
            "uri",
            "tel:+1.7035555555;ext=1234"
          ],
          [
            "tel",
            {
              "type": "fax"
            },
            "uri",
            "tel:+1.7035555556"
          ]
        ]
      ],
      "entities": [
        {
          "objectClassName": "entity",
          "roles": [
            "abuse"
          ],
          "vcardArray": [
            "vcard",
            [
              [
                "version",
                {},
                "text",
                "4.0"
              ],
              [
                "fn",
                {},
                "text",
                "Abuse Contact"
              ],
              [
                "email",
                {},
                "text",
                "abuse@organization.example"
              ],
              [
                "tel",
                {
                  "type": "voice"
                },
                "uri",
                "tel:+1.7035555555;ext=1234"
              ]
            ]
          ]
        }
      ]
    },
    {
      "objectClassName": "entity",
      "handle": "////REGISTRY_REGISTRANT_ID_REDACTION////",
      "roles": [
        "registrant"
      ],
      "vcardArray": [
        "vcard",
        [
          [
            "version",
            {},
            "text",
            "4.0"
          ],
          [
            "fn",
            {},
            "text",
            "////REGISTRANT_NAME_REDACTION////"
          ],
          [
            "org",
            {},
            "text",
            "////REGISTRANT_ORG_REDACTION////"
          ],
          [
            "adr",
            {},
            "text",
            [
              "",
              "////REGISTRANT_STREET_REDACTION////",
              "////REGISTRANT_STREET_REDACTION////",
              "Quebec",
              "////REGISTRANT_CITY_REDACTION////",
              "////REGISTRANT_POSTAL_CODE_REDACTION////",
              "Canada"
            ]
          ],
          [
            "email",
            {},
            "text",
            "registrant-email-redaction@redacted.invalid"
          ],
          [
            "tel",
            {
              "type": "voice"
            },
            "uri",
            "tel:+////0000000000////;ext=////1111111111////"
          ],
          [
            "tel",
            {
              "type": "fax"
            },
            "uri",
            "tel:+////2222222222////"
          ]
        ]
      ]
    },
    {
      "objectClassName": "entity",
      "handle": "////REGISTRY_TECH_ID_REDACTION////",
      "roles": [
        "technical"
      ],
      "vcardArray": [
        "vcard",
        [
          [
            "version",
            {},
            "text",
            "4.0"
          ],
          [
            "fn",
            {},
            "text",
            "////TECH_NAME_REDACTION////"
          ],
          [
            "org",
            {},
            "text",
            "Example Inc."
          ],
          [
            "adr",
            {},
            "text",
            [
              "",
              "Suite 1234",
              "4321 Rue Somewhere",
              "Quebec",
              "QC",
              "G1V 2M2",
              "Canada"
            ]
          ],
          [
            "email",
            {},
            "text",
            "technical-email-redaction@redacted.invalid"
          ],
          [
            "tel",
            {
              "type": "voice"
            },
            "uri",
            "tel:+////3333333333////;ext=321"
          ],
          [
            "tel",
            {
              "type": "fax"
            },
            "uri",
            "tel:+1-555-555-4321"
          ]
        ]
      ]
    }
  ],
  "events": [
    {
      "eventAction": "registration",
      "eventDate": "1997-06-03T00:00:00Z"
    },
    {
      "eventAction": "last changed",
      "eventDate": "2020-05-28T01:35:00Z"
    },
    {
      "eventAction": "expiration",
      "eventDate": "2021-06-03T04:00:00Z"
    }
  ],
  "status": [
    "server delete prohibited",
    "server update prohibited",
    "server transfer prohibited",
    "client transfer prohibited"
  ],
  “simpleRedaction”: [
    { “key”: “////REGISTRY_DOMAIN_ID_REDACTION////” },
    { “key”: “////REGISTRY_REGISTRANT_ID_REDACTION////” },
    { “key”: “////REGISTRANT_NAME_REDACTION////” },
    { “key”: “////REGISTRANT_STREET_REDACTION////” },
    { “key”: “////REGISTRANT_POSTAL_CODE_REDACTION////” },
    { “key”: “////0000000000////” },
    { “key”: “////1111111111////” },
    { “key”: “////REGISTRY_TECH_ID_REDACTION////” },
    { “key”: “////TECH_NAME_REDACTION////” },
    { “key”: “////1111111111////” },
    { “key”: “////2222222222////” },
    { “key”: “registrant-email-redaction@redacted.invalid” },
    { “key”: “tech-email-redaction@redacted.invalid” },
    { “key”: “////REGISTRANT_ORG_REDACTION////” },
    { “key”: “////REGISTRANT_CITY_REDACTION////” }
  ]
}  
]]>
</artwork>
</section>
</section>

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

<section anchor="iana-considerations"><name>IANA Considerations</name>
<t>TBD: registration of &quot;simpleRedaction&quot;.</t>
</section>

</middle>

<back>
<references><name>References</name>
<references><name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3966.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6761.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9083.xml"/>
</references>
<references><name>Informative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6530.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7095.xml"/>
</references>
</references>

</back>

</rfc>
