RFC 8521

Registration Data Access Protocol (RDAP) Object Tagging

๐Ÿ“… published November 2018, from ietf

๐Ÿ“ฎ RFC 8521: Registration Data Access Protocol (RDAP) Object Tagging โœจ

okay bestie, let's get into this one ๐ŸŽ€ It's a Best Current Practice (BCP 221, so it's the official "do it this way" doc, not just a suggestion ๐Ÿ’…) written by S. Hollenbeck from Verisign Labs and A. Newton from ARIN, dated November 2018. It updates RFC 7484 (that's the one about finding the right server for domain, IP, and ASN lookups ๐Ÿฆ‹). The ISSN is 2070-1721, if you ever need to look it up ๐Ÿงš


1. Introduction ๐ŸŒธ

so RDAP has a method in [RFC7484] for figuring out which authoritative server to ask when you're looking up a domain name, IP address, or Autonomous System Number (ASN) ๐Ÿ” it works because those identifiers are structured in a way that's easy for a computer to parse, and you can tie each piece to a specific service provider. like, domain names have labels such as "com", "net", and "org" that belong to specific providers ๐Ÿ’–

now, Section 9 of RFC 7484 [RFC7484] points out that the method doesn't cover entity queries, name server queries, help queries, or queries using certain search patterns ๐Ÿ™ˆ the reason is that the identifiers for those are usually not structured enough to link back to one provider. this document describes a practice for adding structure to RDAP identifiers, which makes it possible to find the authoritative server for more RDAP queries โœจ

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 ๐Ÿซถ yes, the capitals matter, bestie ๐Ÿ’…


Part 1 of 3. More coming up, so stay tuned ๐Ÿฆ‹

2. Object Naming Practice โœจ

okay so this is the part where we figure out how to tag object identifiers so a client can find the right server for an RDAP query ๐Ÿ”๐Ÿ’– the way it works is you prepend the HYPHEN-MINUS character "-" (U+002D, which RFC 3986 [RFC3986] calls an "unreserved" character) to an IANA-registered value that stands for the service provider ๐ŸŽ€ so a provider identified by the string "ARIN" gets written as -ARIN ๐Ÿฆ‹

combined with the rdapConformance attribute from Section 4, these tags get tacked onto the end of RDAP query object identifiers so the authoritative server can be identified without any mix-ups ๐Ÿ’… building on the example in Section 3.1.5 of RFC 7482 [RFC7482], an RDAP entity handle can be built so a client can bootstrap an entity query ๐ŸŒธ

so if you want info on entity handle "XXXX" at provider "ARIN", the identifier is:

XXXX-ARIN

clients that want to bootstrap an entity query split this identifier into a handle part and a service provider part ๐Ÿงš handles can have HYPHEN-MINUS characters inside them too, so the service provider identifier is whatever follows the last HYPHEN-MINUS in the tagged identifier ๐Ÿ™ˆ the service provider identifier is then used to fetch a base RDAP URL from an IANA registry, and the base URL plus the handle get stitched together into a full RDAP query path segment ๐Ÿ“

for example, say the base RDAP URL "https://example.com/rdap/" is linked to provider "YYYY" in an IANA registry. a client parses the tagged entity identifier "XXXX-YYYY" into handle "XXXX" and provider "YYYY". it then looks up "YYYY" in the registry to get "https://example.com/rdap/". the RDAP query URL is built from that base URL and the entity path segment in Section 3.1.5 of RFC 7482 [RFC7482], using "XXXX-YYY" as the handle value. the complete RDAP query URL becomes "https://example.com/rdap/entity/XXXX-YYYY".

hmm wait, the original example builds the query from "XXXX-YYY" but the handle it parsed was "XXXX-YYYY", so I'm copying the text exactly as written here. the wording is in the source, so it stays ๐Ÿ™ˆ

implementing this means tagging the unstructured potential query identifiers in RDAP responses ๐Ÿ’œ check out these elided examples ("..." marks the stuff we skipped) from Section 5.3 of RFC 7483 [RFC7483], where the handle identifiers have been tagged with the provider tags "RIR", "DNR", and "ABC", in that order:

{
  "objectClassName" : "domain",
  "handle" : "XXXX-RIR",
  "ldhName" : "0.2.192.in-addr.arpa",
  "nameservers" :
  [
    ...
  ],
  "secureDNS":
  {
    ...
  },
  "remarks" :
  [
    ...
  ],
  "links" :

  [
    ...
  ],
  "events" :
  [
    ...
  ],
  "entities" :
  [
    {
      "objectClassName" : "entity",
      "handle" : "XXXX-RIR",
      "vcardArray":
      [
        ...
      ],
      "roles" : [ "registrant" ],
      "remarks" :
      [
        ...
      ],
      "links" :
      [
        ...
      ],
      "events" :
      [
        ...
      ]
    }
  ],
  "network" :
  {
    "objectClassName" : "ip network",
    "handle" : "XXXX-RIR",
    "startAddress" : "192.0.2.0",
    "endAddress" : "192.0.2.255",
    "ipVersion" : "v4",
    "name": "NET-RTR-1",
    "type" : "DIRECT ALLOCATION",
    "country" : "AU",
    "parentHandle" : "YYYY-RIR",
    "status" : [ "active" ]
  }
}

                                 Figure 1

{
  "objectClassName" : "domain",
  "handle" : "XXXX-YYY-DNR",
  "ldhName" : "xn--fo-5ja.example",
  "unicodeName" : "foo.example",
  "variants" :
  [
    ...
  ],
  "status" : [ "locked", "transfer prohibited" ],
  "publicIds":
  [
    ...
  ],
  "nameservers" :
  [
    {
      "objectClassName" : "nameserver",
      "handle" : "XXXX-DNR",
      "ldhName" : "ns1.example.com",
      "status" : [ "active" ],
      "ipAddresses" :
      {
        ...
      },
      "remarks" :
      [
        ...
      ],
      "links" :
      [
        ...
      ],
      "events" :
      [
        ...
      ]
    },
    {
      "objectClassName" : "nameserver",
      "handle" : "XXXX-DNR",
      "ldhName" : "ns2.example.com",
      "status" : [ "active" ],
      "ipAddresses" :
      {
        ...
      },
      "remarks" :

      [
        ...
      ],
      "links" :
      [
        ...
      ],
      "events" :
      [
        ...
      ]
    }
  ],
  "secureDNS":
  {
    ...
  },
  "remarks" :
  [
    ...
  ],
  "links" :
  [
    ...
  ],
  "port43" : "whois.example.net",
  "events" :
  [
    ...
  ],
  "entities" :
  [
    {
      "objectClassName" : "entity",
      "handle" : "XXXX-ABC",
      "vcardArray":
      [
        ...
      ],
      "status" : [ "validated", "locked" ],
      "roles" : [ "registrant" ],
      "remarks" :
      [
        ...
      ],
      "links" :
      [
        ...

      ],
      "events" :
      [
        ...
      ]
    }
  ]
}

                                 Figure 2

as Section 5 of RFC 7483 [RFC7483] explains, RDAP responses can include "self" links ๐Ÿฆ‹ the service provider tags and the self references SHOULD be consistent ๐Ÿ’– if they aren't, the service provider tag wins when you use these values to figure out which provider it is ๐Ÿ‘‘

โš ๏ธ there's a risk of unpredictable processing if the HYPHEN-MINUS character shows up for non-separator reasons inside an entity handle ๐Ÿ’€ a client could wrongly think that the HYPHEN-MINUS is a separator and that whatever comes after it is a provider identifier ๐Ÿ˜ญ a client that asks the IANA registry about what it thinks is a valid provider will probably get an unexpected, invalid result ๐Ÿ’” so using HYPHEN-MINUS as the provider tag separator MUST be flagged by adding an rdapConformance value to query responses, as described in Section 4 ๐Ÿซถ

why HYPHEN-MINUS? two reasons ๐ŸŒˆ first, it's a familiar separator in operational use ๐Ÿ“ second, it avoids clashing with URI-reserved characters โœจ RFC 3986 [RFC3986] gives us a list of unreserved characters in its Section 2.3, which offered a few options:

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

ALPHA and DIGIT got kicked out because they're commonly used in entity handles for non-separator stuff ๐Ÿ™… HYPHEN-MINUS is commonly used as a separator, and recognizing that practice cuts down on implementation requirements and operational risk ๐Ÿ”ฅ the rest got excluded because they aren't widely used as separators in handles ๐Ÿ’…


3. Bootstrap Service Registry for Provider Object Tags ๐ŸŽ€

the bootstrap service registry for the RDAP service provider space uses the structure from Section 3 of RFC 7484 [RFC7484] ๐Ÿงš the JSON output of this registry has contact info for the registered service provider identifiers (alphanumeric identifiers that name RDAP service providers) and base RDAP service URLs, like this:

{
  "version": "1.0",
  "publication": "YYYY-MM-DDTHH:MM:SSZ",
  "description": "RDAP bootstrap file for service provider object tags",
  "services": [
    [
      ["contact@example.com"],
      ["YYYY"],
      [
        "https://example.com/rdap/"
      ]
    ],
    [
      ["contact@example.org"],
      ["ZZ54"],
      [
        "http://rdap.example.org/"
      ]
    ],
    [
      ["contact@example.net"],
      ["1754"],
      [
        "https://example.net/rdap/",
        "http://example.net/rdap/"
      ]
    ]
  ]
 }

                                 Figure 3

alphanumeric provider identifiers follow the suffix portion (\w{1,8}) of the "roidType" syntax in Section 4.2 of RFC 5730 [RFC5730] ๐Ÿ’œ

3.1. Registration Procedure ๐Ÿฆ‹

the service provider registry is filled using the "First Come First Served" policy from RFC 8126 [RFC8126] ๐Ÿ’– IANA can derive and assign provider identifier values on request ๐ŸŒธ registration requests include an email address tied to the registered provider identifier, the requested identifier (or a note that IANA should assign one), and one or more base RDAP URLs tied to that identifier ๐Ÿ“


4. RDAP Conformance ๐Ÿ‘‘

RDAP responses that contain values described in this document MUST indicate conformance with this specification by including an rdapConformance [RFC7483] value of rdap_objectTag_level_0 ๐Ÿซถ the info needed to register this value in the "RDAP Extensions" registry is in Section 5.2 ๐Ÿ“

here's an example rdapConformance structure with the extension included:

          "rdapConformance" :
          [
            "rdap_level_0",
            "rdap_objectTag_level_0"
          ]

Figure 4


5. IANA Considerations ๐ŸŒˆ

IANA has created the RDAP "Bootstrap Service Registry for Provider Object Tags" listed below and made it available as a JSON object โœจ the contents of this registry are described in Section 3, and the formal syntax is specified in Section 10 of RFC 7484 [RFC7484] ๐Ÿงš

5.1. Bootstrap Service Registry Structure ๐Ÿ’…

entries in this registry contain the following info:

  • an email address that identifies a contact associated with the registered RDAP service provider value.
  • an alphanumeric value that identifies the RDAP service provider being registered.
  • one or more URLs that provide the RDAP service regarding this registration. The URLs are expected to supply the same data, but they can differ in scheme or other components as required by the service operator.

5.2. RDAP Extensions Registry ๐Ÿ”ฅ

IANA has registered the following value in the "RDAP Extensions" registry:

   Extension identifier: rdap_objectTag
   Registry operator: Any
   Published specification: This document
   Contact: IESG <iesg@ietf.org>

   Intended usage: This extension describes a best practice for
   structuring entity identifiers to enable query bootstrapping.

6. Security Considerations ๐Ÿ”

๐Ÿšจ this is the serious part, bestie ๐Ÿšจ

this practice uses IANA as a well-known, centrally trusted authority so users can get RDAP data from an authoritative source ๐Ÿ’– that cuts the risk of sending queries to non-authoritative sources and leaking query info to the wrong people ๐Ÿ™… using TLS 1.2 [RFC5246] or TLS 1.3 [RFC8446], which obsoletes TLS 1.2, to protect the connection to IANA lets the server prove it's run by IANA ๐Ÿ‘‘ it also gives integrity protection for the referral info, plus privacy through data confidentiality ๐Ÿซถ the subsequent RDAP connection runs as usual and keeps the same security properties of the RDAP protocols themselves, as described in RFC 7481 [RFC7481] โœจ

7. References ๐Ÿ“š

7.1. Normative References โœจ

Okay bestie, these are the must-reads ๐Ÿ“š Every tag below is one the spec leans on, so here they are with all their details:

7.2. Informative References โœจ

These ones are the background reading ๐Ÿงš Helpful to know about, but the spec doesn't depend on them to work:


Acknowledgements ๐Ÿซถ

The authors gave a huge shoutout to Tom Harrison, Patrick Mevzek, and Marcos Sanz for helping build this doc ๐Ÿ’– They also called out the Regional Internet Registry (RIR) operators (AFRINIC, APNIC, ARIN, LACNIC, and RIPE). Those folks have been tagging handle identifiers for years, and their experience gave the whole design a ton of inspiration ๐ŸŒˆ Literal legends.

Authors' Addresses ๐Ÿ’œ

Here's who wrote it, with their contact details exactly as published:

Scott Hollenbeck
Verisign Labs
12061 Bluemont Way
Reston, VA  20190
United States of America

Email: shollenbeck@verisign.com
URI:   http://www.verisignlabs.com/


Andrew Lee Newton
American Registry for Internet Numbers
PO Box 232290
Centreville, VA  20120
United States of America

Email: andy@arin.net
URI:   http://www.arin.net
๐Ÿ“ฆ where this page comes from