<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.35 (Ruby 3.3.8) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

]>


<rfc ipr="trust200902" docName="draft-gallagher-openpgp-hkp-10" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="HKP">OpenPGP HTTP Keyserver Protocol</title>

    <author fullname="Daphne Shaw">
      <organization>Jabberwocky Tech</organization>
      <address>
        <email>dshaw@jabberwocky.com</email>
      </address>
    </author>
    <author fullname="Andrew Gallagher" role="editor">
      <organization>PGPKeys.EU</organization>
      <address>
        <email>andrewg@andrewg.com</email>
      </address>
    </author>
    <author fullname="Daniel Huigens">
      <organization>Proton AG</organization>
      <address>
        <email>d.huigens@protonmail.com</email>
      </address>
    </author>

    <date year="2026" month="April" day="29"/>

    <area>sec</area>
    <workgroup>openpgp</workgroup>
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 68?>

<t>This document specifies a series of conventions to implement an OpenPGP keyserver using the Hypertext Transfer Protocol (HTTP).
As this document is a codification and extension of a protocol that is already in wide use, strict attention is paid to backward compatibility with these existing implementations.</t>



    </abstract>

    <note title="About This Document" removeInRFC="true">
      <t>
        The latest revision of this draft can be found at <eref target="https://andrewgdotcom.gitlab.io/draft-gallagher-openpgp-hkp"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-gallagher-openpgp-hkp/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        OpenPGP Working Group mailing list (<eref target="mailto:openpgp@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/openpgp/"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/openpgp/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://gitlab.com/andrewgdotcom/draft-gallagher-openpgp-hkp"/>.</t>
    </note>


  </front>

  <middle>


<?line 73?>

<section anchor="introduction"><name>Introduction</name>

<t>For ease of use, public key cryptography requires a key distribution system.
For many years, the most commonly used system has been a keyserver - a server that stores public keys and/or certificates, with a searchable interface.
The HTTP Keyserver Protocol is a OpenPGP keyserver implemented using HTTP.</t>

</section>
<section anchor="conventions-definitions"><name>Conventions and Definitions</name>

<t>The term "OpenPGP Certificate" is used in this document interchangeably with "OpenPGP Transferable Public Key", as defined in <xref section="10.1" sectionFormat="of" target="RFC9580"/>.</t>

<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>

<?line -18?>

</section>
<section anchor="keyserver-use-cases"><name>Keyserver Use Cases</name>

<t>A keyserver is typically used for the following (non-exhaustive) use cases:</t>

<section anchor="certificate-discovery"><name>Certificate Discovery</name>

<t>When initiating secure communication with a new correspondent, a client will typically attempt to discover the encryption key(s) that it should use.
This is a subtle issue with many security considerations, however many discovery methods involve looking up a certificate on a server using a human-readable identifier such as an email address.</t>

</section>
<section anchor="certificate-refresh"><name>Certificate Refresh</name>

<t>Certificates in OpenPGP are dynamic objects, therefore it is important to refresh known certificates in order to pick up the latest changes.
These changes can include new subkeys and User IDs, updated self-signatures and third-party certifications, and revocations.
In some cases it may no longer be possible to search by User ID, therefore it is <bcp14>RECOMMENDED</bcp14> that clients refresh known certificates by primary key fingerprint search.</t>

</section>
<section anchor="reference-resolution"><name>Reference Resolution</name>

<t>The OpenPGP wire format includes fields that reference primary keys or subkeys by either Key ID or fingerprint.
A client may therefore wish to search for previously unknown certificates based on such a reference.</t>

</section>
</section>
<section anchor="hkp-and-http"><name>HKP and HTTP</name>

<t>As HKP is implemented over HTTP, everything in <xref target="RFC9110"></xref> applies to HKP as well, and HKP error codes are the same as the ones used in HTTP.</t>

<t>Due the very large deployment of HKP clients based on HTTP version 1.0, HKP keyservers <bcp14>MUST</bcp14> support HTTP 1.0.
HKP keyservers <bcp14>MAY</bcp14> additionally support other HTTP versions.</t>

<t>(( dshaw : I expect this to be controversial, but we've got tons of deployed code that only works with 1.0.
I'd be willing to discuss removing this <bcp14>MUST</bcp14> or make it a <bcp14>SHOULD</bcp14> and add a "implementation notes" section pointing out the problem instead.
See issue #5.
))</t>

<t>When used over HTTPS, HKP is commonly referred to as "HKPS".</t>

<t>HKP(S) are distinguished from generic use of HTTP(S) by using the URI schemes "hkp" and "hkps" <xref target="RFC7595"></xref>.
HKP is assigned port number 11371 and HKPS is assigned 11372 (although this is rarely used in practice).
For reasons of maximum compatibility with firewalls and filtering HTTP proxies, HKP(S) are often served over the standard HTTP(S) port(s) (TCP ports 80 and 443).</t>

<t>By convention and history, HKP defaults to HTTP on TCP port 11371, and HKPS defaults to HTTPS on TCP port 443.</t>

<t>(( andrewg : if we assign hkps, we appear to be required to specify a dedicated port, even though nobody uses it.
See issue #14.
))</t>

<t>A keyserver <bcp14>SHOULD</bcp14> support both HKP and HKPS.
A client <bcp14>SHOULD</bcp14> use HKPS, or a transport method with equivalent security properties, such as Tor hidden services <xref target="TOR"></xref>.</t>

<section anchor="request-paths"><name>Request Paths</name>

<t>HKP defines three paths, namely "/pks/v2" for the v2 API (<xref target="v2-api"/>), "/pks/lookup" for legacy lookups (<xref target="legacy-lookups"/>), and "/pks/add" for legacy submission (<xref target="legacy-submission"/>).
Paths beginning with "/pks/v&lt;?&gt;" are reserved for future versions of HKP.</t>

<t>A keyserver <bcp14>MAY</bcp14> support requests to other paths under "/pks", but these are outside the scope of this document.
These alternative paths have historically been used to provide human-readable interfaces such as HTML forms, and functionality extensions such as <xref target="SKS"></xref>.</t>

</section>
<section anchor="http-status"><name>HTTP Status Codes</name>

<t>When a status or error code needs to be returned by a keyserver, the most appropriate HTTP code from <xref target="RFC9110"></xref> should be used.
It is good practice to return the most specific error code possible: for example, returning 404 ("Not Found") rather than 400 ("Bad Request") when a certificate is not found.</t>

<t>This document gives suggested HTTP error codes for several common situations.
Note that these are only suggestions, and implementations may have good reasons (such as not revealing the reason why a request failed) for using other error codes.</t>

<t>Clients <bcp14>SHOULD</bcp14> understand the following codes:</t>

<texttable title="Status Codes" anchor="status-codes">
      <ttcol align='left'>Status Code</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>200 OK</c>
      <c>Request succeeded</c>
      <c>403 Forbidden</c>
      <c>The requested category/operation is not permitted</c>
      <c>404 Not found</c>
      <c>The search returned no results, or path not found</c>
      <c>410 Gone</c>
      <c>Requested data has been permanently deleted, e.g. due to RTBF</c>
      <c>422 Unprocessable content</c>
      <c>Submission was not well formed</c>
      <c>501 Not implemented</c>
      <c>The requested category/operation is not supported</c>
</texttable>

<t>In addition, a client <bcp14>SHOULD</bcp14> understand 3xx redirect codes.</t>

</section>
</section>
<section anchor="v2-api"><name>The v2 API</name>

<t>The v2 API is a RESTful interface that uses the GET, PUT, POST, DELETE, HEAD, and OPTIONS methods.
The URL path (<xref section="3.3" sectionFormat="of" target="RFC3986"/>) is built up of the base path "/pks/v2", followed by request-specific URL path components.</t>

<section anchor="v2-lookup-format"><name>v2 Lookup Format</name>

<t>Certificate lookups are done via an HTTP GET request.</t>

<t>v2 lookups normally include both "category" and "identifier" URL path components.
They are appended to "/pks/v2" as follows:</t>

<figure><artwork><![CDATA[
GET /pks/v2/<category>/<identifier>
]]></artwork></figure>

<t>The "category" and "identifier" components <bcp14>MUST</bcp14> be supplied.</t>

<t>When the v2 lookup format is being used, v2 output format (<xref target="v2-output-format"/>) <bcp14>MUST</bcp14> be returned.</t>

<t>The v2 lookup format is designed so that a basic HKP service can be implemented using static files.</t>

<texttable title="v2 Lookup Categories" anchor="v2-lookup-categories">
      <ttcol align='left'>Category</ttcol>
      <ttcol align='left'>Identifier format</ttcol>
      <ttcol align='left'>Output data</ttcol>
      <ttcol align='left'>See</ttcol>
      <c><spanx style="verb">certs/by-identity</spanx></c>
      <c>identity</c>
      <c>Certificate bundle</c>
      <c><xref target="identity-category"/></c>
      <c><spanx style="verb">certs/by-vfingerprint</spanx></c>
      <c>versioned fingerprint</c>
      <c>Certificate bundle</c>
      <c><xref target="vfingerprint-category"/></c>
      <c><spanx style="verb">certs/by-keyid</spanx></c>
      <c>key ID</c>
      <c>Certificate bundle</c>
      <c><xref target="keyid-category"/></c>
      <c><spanx style="verb">canonical</spanx></c>
      <c>identity</c>
      <c>Canonical bundle</c>
      <c><xref target="canonical-lookup-category"/></c>
      <c><spanx style="verb">index</spanx></c>
      <c>identity</c>
      <c>Index of certificates</c>
      <c><xref target="index-category"/></c>
      <c><spanx style="verb">prefixlog</spanx></c>
      <c>date</c>
      <c>List of prefixes</c>
      <c><xref target="prefixlog-category"/></c>
</texttable>

<section anchor="identity-category"><name>The "certs/by-identity" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "certs/by-identity" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/certs/by-identity/<identifier>
]]></artwork></figure>

<t>The "certs/by-identity" category identifies each certificate by matching the contents of its User ID packet(s) (<xref target="identity-lookups"/>).
The response to a successful "certs/by-identity" request is a certificate bundle as specified in <xref target="certificate-bundle-format"/>, which <bcp14>MUST NOT</bcp14> be ASCII-armored.</t>

<t>A keyserver <bcp14>SHOULD</bcp14> limit the returned certificate bundle to a reasonable length.
Results <bcp14>SHOULD</bcp14> be sorted in order of decreasing confidence in the identity link (<xref target="confidence"/>), and then by creation date (most recent first).
A keyserver <bcp14>MAY</bcp14> choose to only return results where the identity being searched for exceeds a minimum confidence value, and <bcp14>MAY</bcp14> treat "certs/by-identity" as a synonym for "canonical".
If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="vfingerprint-category"><name>The "certs/by-vfingerprint" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "certs/by-vfingerprint" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/certs/by-vfingerprint/<identifier>
]]></artwork></figure>

<t>The "certs/by-vfingerprint" category identifies each certificate by the versioned fingerprint of its primary key or a subkey.
The versioned fingerprint is provided in the "identifier" path component in hexadecimal encoding, without a preceding "0x".
The hexadecimal digits are not case sensitive.</t>

<t>A versioned fingerprint consists of one octet of fingerprint version number and N octets of fingerprint.
This is the same octet sequence used in the Issuer Fingerprint and Intended Recipient Fingerprint subpackets (<xref section="5.2.3" sectionFormat="of" target="RFC9580"/>).</t>

<t>A keyserver:</t>

<t><list style="symbols">
  <t><bcp14>SHOULD</bcp14> include matches with both primary key and subkey fingerprints.</t>
  <t><bcp14>MAY</bcp14> omit matches with encryption-only subkeys.</t>
</list></t>

<t>If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="keyid-category"><name>The "certs/by-keyid" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "certs/by-keyid" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/certs/by-keyid/<identifier>
]]></artwork></figure>

<t>The "certs/by-keyid" category identifies each certificate by the Key ID of its primary key or a subkey (<xref section="5.5.4" sectionFormat="of" target="RFC9580"/>).
The Key ID is provided in the "identifier" path component as 16 hexadecimal digits, without a preceding "0x".
The hexadecimal digits are not case sensitive.</t>

<t>A keyserver:</t>

<t><list style="symbols">
  <t><bcp14>SHOULD</bcp14> include matches with both primary key and subkey Key IDs.</t>
  <t><bcp14>MAY</bcp14> omit matches with encryption-only subkeys.</t>
</list></t>

<t>If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

<t>"certs/by-keyid" is only required for locating a signing key that made either a V3 signature, or a V4 signature with an Issuer Key ID subpacket and no Issuer Fingerprint subpacket.
Issuer Key ID subpackets are not specified for use in later signature versions (<xref section="5.2.3.12" sectionFormat="of" target="RFC9580"/>), and so certificates with versions greater than 4 <bcp14>MUST NOT</bcp14> be returned in response to a "certs/by-keyid" request.</t>

</section>
<section anchor="canonical-lookup-category"><name>The "canonical" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "canonical" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/canonical/<identifier>
]]></artwork></figure>

<t>The "canonical" category is similar to the "certs/by-identity" category, but is intended specifically for certificate discovery (<xref target="certificate-discovery"/>).
A keyserver <bcp14>MUST</bcp14> return either the canonical bundle of the identity being searched for (<xref target="canonical-bundles"/>), or a 404 Not Found error.</t>

</section>
<section anchor="index-category"><name>The "index" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "index" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/index/<identifier>
]]></artwork></figure>

<t>This requests a list of certificates on the keyserver whose User IDs match the identity given in the "identifier" path component (<xref target="identity-lookups"/>).
This list is returned in JSON format as specified in <xref target="v2-indexes"/>.</t>

<t>A keyserver <bcp14>SHOULD</bcp14> limit the returned index to a reasonable length.
Results <bcp14>SHOULD</bcp14> be sorted in order of decreasing confidence in that identity (<xref target="confidence"/>), and then by creation date (most recent first).
A keyserver <bcp14>MAY</bcp14> choose to only return results where the identity being searched for exceeds a minimum confidence value.
If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="prefixlog-category"><name>The "prefixlog" Lookup Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "prefixlog" lookup category.</t>

<figure><artwork><![CDATA[
GET /pks/v2/prefixlog/<identifier>
]]></artwork></figure>

<t>"prefixlog" requests a list of fingerprint prefixes that indicate which certificates have been modified since 00:00:00 UTC on a specific date.
The date is provided in the "identifier" path component using the "full-date" format as per <xref section="5.6" sectionFormat="of" target="RFC3339"/>, i.e. "2025-12-31".</t>

<t>The returned data is a list of CRLF-separated, hexadecimal-encoded, primary key fingerprint prefixes, and each prefix is truncated at a hex-digit (nybble) boundary.
Fingerprint prefixes do not include the version number.
The keyserver <bcp14>SHOULD</bcp14> calibrate the prefix length so that it is long enough to provide collision resistance, but short enough to maintain a useful anonymity cohort.
For example, if the prefix length was too short, clients could be induced to make excessive numbers of network requests.
A client <bcp14>MUST NOT</bcp14> make any assumptions about the length of the prefixes returned.</t>

<t>A client that wishes to update its local keystore from a keyserver <bcp14>MAY</bcp14> first make a "prefixlog" request with the date of the last successful refresh.
It can then compare the returned list of prefixes to see if any of them are present in its local keystore, and make subsequent "certs/by-vfingerprint" requests as appropriate (<xref target="vfingerprint-category"/>).
In this way, it can avoid making unnecessary requests that will return no updates, but will still leak information to the keyserver.</t>

<t>Note that the <spanx style="verb">prefixlog</spanx> endpoint always returns fingerprint prefixes, regardless of fingerprint version.
This contrasts with v4 Key IDs, which are constructed from fingerprint suffixes.</t>

<t>A keyserver <bcp14>MUST NOT</bcp14> support indexing or downloading certificates by prefix.</t>

</section>
<section anchor="options-lookup-method"><name>OPTIONS Lookup Method</name>

<t>A client <bcp14>MAY</bcp14> attempt to detect which lookup categories a keyserver supports by making an OPTIONS request (<xref section="9.3.7" sectionFormat="of" target="RFC9110"/>) to a lookup path with the "category" path component present but the "identifier" component absent.</t>

<t>A keyserver that supports the lookup category <bcp14>MAY</bcp14> respond with:</t>

<t><list style="symbols">
  <t>a 200 "OK" code,</t>
  <t>an <spanx style="verb">Allow:</spanx> response header that includes the value "GET" (<xref section="10.2.1" sectionFormat="of" target="RFC9110"/>).</t>
</list></t>

<t>Otherwise, it <bcp14>SHOULD</bcp14> respond with an error code such as 501 "Not Implemented".
Note however that a keyserver that does not support OPTIONS (for example, if it is implemented using static files) <bcp14>MAY</bcp14> return another error code such as 404 "Not Found" or 405 "Method Not Allowed".</t>

<t>A client <bcp14>SHOULD NOT</bcp14> attempt to make a GET request to a lookup path without both the "category" and "identifier" path components present.
A keyserver <bcp14>SHOULD</bcp14> return an error code such as 403 "Forbidden" to such a request.</t>

</section>
<section anchor="head-lookup-method"><name>HEAD Lookup Method</name>

<t>A client <bcp14>MAY</bcp14> attempt to retrieve the metadata of a certificate or certificate bundle by making a HEAD request (<xref section="9.3.2" sectionFormat="of" target="RFC9110"/>) to a full lookup path, with the "category" and "identifier" components present.
A keyserver <bcp14>SHOULD</bcp14> respond with the same header fields that it would have responded with if a GET request had been made.</t>

</section>
<section anchor="identity-lookups"><name>v2 Identity Lookups</name>

<t>The format of User IDs in OpenPGP has historically been vaguely specified and loosely interpreted (see <xref target="I-D.dkg-openpgp-userid-conventions"/>).
A particular identity may therefore be represented by an arbitrary number of different User ID packets.
Implementers should bear in mind that end users will typically search for identities, and not specific representations of that identity.</t>

<t>For example, the User ID strings <spanx style="verb">Andrew Gallagher &lt;andrew@example.com&gt;</spanx> and <spanx style="verb">Andrew B. Gallagher (work email) &lt;andrew@example.com&gt;</spanx> are both representations of the underlying identity <spanx style="verb">andrew@example.com</spanx>.</t>

<t>v2 "certs/by-identity", "canonical" and "index" lookup requests <bcp14>MUST</bcp14> only return results if the "identifier" path component exactly matches one of the following:</t>

<t><list style="symbols">
  <t>The portion between angle brackets (<spanx style="verb">&lt;...&gt;</spanx>) in an email-address style User ID.</t>
  <t>The full text string in a non-email-address User ID.</t>
</list></t>

<t>A keyserver <bcp14>SHOULD</bcp14> parse an email-address style User ID defensively.
In particular, if there is more than one substring of a User ID that could reasonably be interpreted as an email address, then a keyserver <bcp14>SHOULD NOT</bcp14> return an identity match on either substring.</t>

<t>Text lookups <bcp14>SHOULD NOT</bcp14> be case sensitive.
DNS names are not case sensitive, therefore any identity that contains a DNS name (including email addresses) cannot be reliably located using case sensitive matching.
Since the interpretation of User IDs is application-specific, a client <bcp14>MUST</bcp14> check that any User IDs returned from a keyserver are correctly case matched for the intended application.</t>

</section>
<section anchor="lookup-examples"><name>Lookup Examples</name>

<t>Get all certificates containing the email address <spanx style="verb">dshaw@example.com</spanx>:</t>

<figure><artwork><![CDATA[
https://keys.example.com/pks/v2/certs/by-identity/dshaw@example.com
]]></artwork></figure>

<t>Get certificate 0xCAFEDADACAFEDADACAFEDADACAFEDADACAFEDADACAFEDADACAFEDADACAFEDADA (v6 fingerprint):</t>

<figure><artwork><![CDATA[
https://keys.example.com/pks/v2/certs/by-vfingerprint/06cafedadacafedadacafedadacafedadacafedadacafedadacafedadacafedada
]]></artwork></figure>

<t>Get certificate 0xDEADBEEFDECAFBAD (64-bit Key ID):</t>

<figure><artwork><![CDATA[
https://keys.example.com/pks/v2/certs/by-keyid/DEADBEEFDECAFBAD
]]></artwork></figure>

</section>
</section>
<section anchor="v2-submission-format"><name>v2 Submission Format</name>

<t>A keyserver <bcp14>MAY</bcp14> accept submissions via an HTTP POST or PUT request, as specified in <xref section="9.3" sectionFormat="of" target="RFC9110"/>.</t>

<t>v2 submission requests include a "category" URL path component, and optionally an "identifier" path component.
These are appended to "/pks/v2" as follows:</t>

<figure><artwork><![CDATA[
POST /pks/v2/<category>
PUT /pks/v2/<category>/<identifier>
]]></artwork></figure>

<t>The "category" path component <bcp14>MUST</bcp14> be supplied.
In PUT submission requests, the "identifier" path component is required.
In POST submission requests, the "identifier" path component is omitted.</t>

<texttable title="v2 Submission Request Categories" anchor="v2-submission-request-categories">
      <ttcol align='left'>Category</ttcol>
      <ttcol align='left'>Method</ttcol>
      <ttcol align='left'>Input data</ttcol>
      <ttcol align='left'>Output data</ttcol>
      <ttcol align='left'>See</ttcol>
      <c><spanx style="verb">certs</spanx></c>
      <c>POST</c>
      <c>certificate bundle</c>
      <c>submission response</c>
      <c><xref target="certs-category"/></c>
      <c><spanx style="verb">sendtoken</spanx></c>
      <c>POST</c>
      <c>email address</c>
      <c>(none)</c>
      <c><xref target="sendtoken-category"/></c>
      <c><spanx style="verb">canonical</spanx></c>
      <c>PUT</c>
      <c>canonical bundle</c>
      <c>submission response</c>
      <c><xref target="canonical-submission-category"/></c>
</texttable>

<t>Unless otherwise specified, a keyserver <bcp14>SHOULD</bcp14> respond to v2 submissions with a JSON document as described in <xref target="submission-responses"/>.</t>

<t>If a keyserver does not support submission via HTTP, then requests to do so should return an appropriate HTTP error code, such as 403 ("Forbidden") if certificate submission has been disallowed, or 404 ("Not Found") if the server does not support the requested submission category.</t>

<section anchor="certs-category"><name>The v2 "certs" Submission Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "certs" submission category.</t>

<figure><artwork><![CDATA[
POST /pks/v2/certs
]]></artwork></figure>

<t>A keyserver that implements it <bcp14>SHOULD</bcp14> support the basic submission workflow described in <xref target="basic-submission"/>.
It <bcp14>MAY</bcp14> support other workflows; if so it <bcp14>SHOULD</bcp14> advertise them as described in <xref target="feature-detection"/>.</t>

<t>A keyserver <bcp14>MAY</bcp14> verify the request and reject any submissions that cannot be verified.
This verification <bcp14>SHOULD</bcp14> use a reliable means of authentication, such as login credentials or a Bearer token (<xref target="token-authentication"/>).</t>

</section>
<section anchor="sendtoken-category"><name>The v2 "sendtoken" Submission Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "sendtoken" submission category.</t>

<figure><artwork><![CDATA[
POST /pks/v2/sendtoken
]]></artwork></figure>

<t>The body of the POST request is a single email address.
It <bcp14>SHOULD</bcp14> have a content-type of <spanx style="verb">text/plain</spanx>.
The keyserver <bcp14>SHOULD</bcp14> respond with an empty document.</t>

<t>A keyserver that supports the "sendtoken" request category <bcp14>SHOULD</bcp14> attempt to verify the email address by sending a time-limited Bearer token via email.
A client that receives the verification email can then use the token in a canonical submission request (<xref target="canonical-submission-category"/>).
A keyserver <bcp14>MAY</bcp14> limit the number and frequency of verification requests.</t>

<t>The verification email <bcp14>SHOULD</bcp14> contain a <spanx style="verb">multipart/alternative</spanx> message with two parts:</t>

<t><list style="symbols">
  <t>A JSON-LD structured mail document <xref target="I-D.ietf-sml-structured-email"></xref>.</t>
  <t>A human-readable document containing instructions for manual submission.</t>
</list></t>

<t>The context for the JSON-LD document is <spanx style="verb">http://hockeypuck.io/contexts/hkp-sendtoken.jsonld</spanx> (( TBC, issue #40 )), which contains the following fields:</t>

<texttable title="Structured Mail Fields" anchor="structured-mail-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>JSON-LD Type</ttcol>
      <c><spanx style="verb">url</spanx></c>
      <c>URL to be used for submission</c>
      <c><spanx style="verb">http://schema.org/url</spanx></c>
      <c><spanx style="verb">token</spanx></c>
      <c>verification token</c>
      <c><spanx style="verb">http://schema.org/accessCode</spanx></c>
      <c><spanx style="verb">expires</spanx></c>
      <c>expiry time of the token</c>
      <c><spanx style="verb">http://schema.org/expires</spanx></c>
</texttable>

<t>The URL is the full URL to be used for submission, including the identifier component.
The token is a randomly-generated string suitable for inclusion verbatim in an <spanx style="verb">Authentication: Bearer</spanx> HTTP header (<xref target="token-authentication"/>).
The expiry time <bcp14>MUST</bcp14> be given in UTC, in the format <spanx style="verb">yyyy-mm-ddThh:mm:ssZ</spanx>.</t>

<t>(( TBC: this follows a prove-then-submit model, which is the inverse of KOO's current submit-then-prove process.
The rationale is that submit-then-prove often silently degrades to "submit-then-forget-to-prove".
Failed advance proofs are less likely to be mis-reported as a success.
In addition, prove-then-submit more easily generalises to other forms of verification.
Is this defensible?
issue #41 ))</t>

<section anchor="sample-json-ld-document"><name>Sample JSON-LD Document</name>

<figure><artwork><![CDATA[
{
    "@context": "http://hockeypuck.io/contexts/hkp-sendtoken.jsonld",
    "url": "https://keyserver.example/pks/v2/canonical/alice@openpgp.example",
    "token": "sOmE+bAsE64/rAnd0M+Tok3n",
    "expires": "2001-01-01T01:01:01Z"
}
]]></artwork></figure>

</section>
</section>
<section anchor="canonical-submission-category"><name>The v2 "canonical" Submission Category</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "canonical" submission category.</t>

<figure><artwork><![CDATA[
PUT /pks/v2/canonical/<identifier>
]]></artwork></figure>

<t>The request path is the same as the one used for the "canonical" lookup category (<xref target="canonical-lookup-category"/>).</t>

<t>A keyserver that implements it <bcp14>SHOULD</bcp14> support the basic submission workflow described in <xref target="basic-submission"/>.
It <bcp14>MAY</bcp14> support other workflows; if so it <bcp14>SHOULD</bcp14> advertise them as described in <xref target="feature-detection"/>.</t>

<t>This instructs the server that for the identity (<xref target="identity-lookups"/>) supplied in the request path:</t>

<t><list style="symbols">
  <t>The certificates contained in the submission that have the corresponding identity are regarded by the owner as canonical for that identity,</t>
  <t>The owner wishes for these certificates to be served in the same order and format that they appear in the submission, and:</t>
  <t>Any certificates for that identity that are not contained in the submission are not (or no longer) canonical for that identity.</t>
</list></t>

<t>A keyserver <bcp14>MUST</bcp14> verify the request and reject any submissions that cannot be verified.
This verification <bcp14>SHOULD</bcp14> use a reliable means of authentication, such as login credentials or a Bearer token (<xref target="token-authentication"/>).
Once the keyserver verifies the submission, it stores the resulting canonical bundle (<xref target="canonical-bundles"/>) and updates any internal confidence values as necessary (<xref target="confidence"/>).</t>

</section>
<section anchor="basic-submission"><name>Basic Submission</name>

<t>Basic submission uses a content-type of <spanx style="verb">application/pgp-keys;armor=no</spanx> (<xref section="5" sectionFormat="of" target="I-D.gallagher-openpgp-media-types"/>).
The body of the POST or PUT request contains a certificate bundle as specified in <xref target="certificate-bundle-format"/>, which <bcp14>MUST NOT</bcp14> be ASCII-armored.</t>

<section anchor="token-authentication"><name>Token Authentication</name>

<t>When using token authentication with a basic submission workflow, the client adds an Authentication request header containing a Bearer token obtained via a "sendtoken" request (<xref target="sendtoken-category"/>).</t>

<figure><artwork><![CDATA[
Authentication: Bearer <token>
]]></artwork></figure>

<t>This token <bcp14>MUST</bcp14> correspond to one of the identities present in the canonical bundle being submitted.
A client <bcp14>SHOULD</bcp14> remove any User IDs not related to the token.
A keyserver <bcp14>MAY</bcp14> reject a canonical bundle that contains User IDs not related to the token.</t>

</section>
</section>
<section anchor="advanced-submission"><name>Advanced Submission</name>

<t>Advanced submission uses a content-type of <spanx style="verb">multipart/form-data</spanx>.
The body of the POST or PUT request contains a multipart with one or more parts.
The required part has a content-type of <spanx style="verb">application/pgp-keys;armor=no</spanx> (<xref section="5" sectionFormat="of" target="I-D.gallagher-openpgp-media-types"/>) and <bcp14>MUST</bcp14> be named "keytext".
This part contains a certificate bundle as specified in <xref target="certificate-bundle-format"/>, which <bcp14>MUST NOT</bcp14> be ASCII-armored.</t>

<t>Other parts <bcp14>MAY</bcp14> be included as required by an advanced submission workflow.
No advanced submission workflows are currently specified.</t>

</section>
<section anchor="feature-detection"><name>Submission Feature Detection Using OPTIONS</name>

<t>A client <bcp14>MAY</bcp14> attempt to detect which certificate submission workflows a keyserver supports by making an OPTIONS request (<xref section="9.3.7" sectionFormat="of" target="RFC9110"/>) to a submission path with the "category" path component present but the "identifier" path component absent.
A keyserver that supports v2 submission <bcp14>SHOULD</bcp14> respond with:</t>

<t><list style="symbols">
  <t>a 200 code,</t>
  <t>an <spanx style="verb">Allow:</spanx> response header that includes the value "POST" or "PUT" as appropriate (<xref section="10.2.1" sectionFormat="of" target="RFC9110"/>),</t>
  <t>one or more <spanx style="verb">Accept:</spanx> response header(s) (<xref section="12.5.1" sectionFormat="of" target="RFC9110"/>).</t>
</list></t>

<t><spanx style="verb">Accept</spanx> response media types <bcp14>MAY</bcp14> include:</t>

<t><list style="symbols">
  <t><spanx style="verb">application/pgp-keys</spanx> - basic submission without proof</t>
  <t><spanx style="verb">application/pgp-keys;proof=tokens</spanx> - basic submission with token proof</t>
  <t><spanx style="verb">multipart/form-data;proof=dkim</spanx> - advanced submission with DKIM proof (EXPERIMENTAL)</t>
</list></t>

<t>(( TODO: check the requirements for CORS preflight, issue #38 ))</t>

</section>
<section anchor="canonical-bundles"><name>Canonical Bundles</name>

<t>A certificate bundle submitted or returned via a "canonical" request is called a "canonical bundle".
A canonical bundle represents both the list of certificates that the key holder wishes to be associated with an identity, and their preferred form of those certificates.
A keyserver <bcp14>SHOULD</bcp14> serve only canonical bundles in response to a "canonical" lookup request.
A keyserver <bcp14>MAY</bcp14> serve full copies of the matching certificate(s) in response to a "certs" lookup request.
For example, a full copy may include valid certificate components obtained by non-canonical submission, but not present in the canonical bundle.</t>

<t>When submitting a canonical bundle, any new certificate components <bcp14>SHOULD</bcp14> be merged into the full copy of the corresponding certificate, if the keyserver supports it.
Any valid key or self-certification revocations known to the keyserver <bcp14>SHOULD</bcp14> be merged into the corresponding canonical bundle(s), if any.
This applies both to revocations already present in the key store, and to those submitted at any later date.
A keyserver <bcp14>SHOULD NOT</bcp14> modify a canonical bundle in any other way.</t>

<t>A keyserver that accepts submissions <bcp14>MUST</bcp14> allow a valid key revocation certificate for any key to be submitted without identity verification.
A valid key revocation signature <bcp14>SHOULD</bcp14> be applied to all copies of the key that it revokes, and <bcp14>SHOULD</bcp14> be served in response to all requests for that key.
An implementation <bcp14>MAY</bcp14> however omit some revocations for brevity - for example, if two valid revocations exist with different timestamps but otherwise identical effect, an implementation <bcp14>MAY</bcp14> serve the older revocation and omit the newer one.</t>

<t>Other methods such as <xref target="I-D.dkg-openpgp-1pa3pc"/> are more appropriate for controlling the form of certificates returned by non-canonical requests.</t>

</section>
<section anchor="submission-examples"><name>Submission Examples</name>

<t>(( TODO: issue #39 ))</t>

</section>
</section>
</section>
<section anchor="legacy-api"><name>The Legacy API</name>

<t>For backwards compatibility with the existing installed client base, a Legacy API is defined.
New implementations <bcp14>SHOULD</bcp14> use the v2 API.</t>

<section anchor="legacy-lookups"><name>Legacy Lookup Format</name>

<t>Legacy certificate lookups are done via an HTTP GET request.
The URL path (<xref section="3.3" sectionFormat="of" target="RFC3986"/>) is always "/pks/lookup", and is followed by a request-specific query string (<xref section="3.4" sectionFormat="of" target="RFC3986"/>).
No URL path components under "/pks/lookup" are used.</t>

<t>Most Legacy lookups contain both the "op" (operation) and "search" variables.
These roughly correspond to the "category" and "identifier" components of the v2 API, but with subtly different semantics.
The "op" variable determines what operation the keyserver will execute, and the "search" variable determines which certificates are operated on.</t>

<t>The "op" and "search" variables are supplied as HTTP query strings, in the form <spanx style="verb">&lt;variable-name&gt;=&lt;value&gt;</spanx>:</t>

<figure><artwork><![CDATA[
/pks/lookup?op=<op>&search=<search>[&...]
]]></artwork></figure>

<t>The "op" variable <bcp14>MUST</bcp14> be supplied, and the "search" variable <bcp14>MUST</bcp14> be supplied unless the "stats" operation is being requested (<xref target="stats-operation"/>).</t>

<t>There may also be modifier variables, as specified in <xref target="legacy-modifier-variables"/> below.
Keyservers <bcp14>MUST</bcp14> ignore any unknown query string parameters.</t>

<section anchor="operation-lookup-variable"><name>The "op" (Operation) Lookup Variable</name>

<t>The "op" (operation) variable specifies the lookup operation to be performed on the keyserver.
The "op" variable is generally accompanied by a "search" variable to specify the certificates that should be looked up.</t>

<t>If a particular operation is not supported, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 501 ("Not Implemented").
The server <bcp14>SHOULD NOT</bcp14> return an error code (such as 404 ("Not Found")) that could be interpreted by the client as an explicit statement of non-existence.</t>

<texttable title="Legacy Lookup Operations" anchor="legacy-lookup-operations">
      <ttcol align='left'>Operation</ttcol>
      <ttcol align='left'>Search format</ttcol>
      <ttcol align='left'>Output data</ttcol>
      <ttcol align='left'>See</ttcol>
      <c><spanx style="verb">get</spanx></c>
      <c>text</c>
      <c>Certificate bundle</c>
      <c><xref target="get-operation"/></c>
      <c><spanx style="verb">hget</spanx></c>
      <c>SKS hash</c>
      <c>Certificate bundle</c>
      <c><xref target="hget-operation"/></c>
      <c><spanx style="verb">index</spanx></c>
      <c>text</c>
      <c>Index of certificates</c>
      <c><xref target="index-operation"/></c>
      <c><spanx style="verb">vindex</spanx></c>
      <c>text</c>
      <c>Index of certificates</c>
      <c><xref target="vindex-operation"/></c>
      <c><spanx style="verb">stats</spanx></c>
      <c>(none)</c>
      <c>Implementation info</c>
      <c><xref target="stats-operation"/></c>
</texttable>

</section>
<section anchor="get-operation"><name>The "get" Operation</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "get" operation.</t>

<t>The "get" operation requests certificates from the keyserver by textual search.
A string that specifies which certificate(s) to return is provided in the "search" variable.</t>

<t>The response to a successful "get" operation is an ASCII-armored certificate bundle as specified in <xref target="certificate-bundle-format"/>.</t>

<t>A keyserver <bcp14>SHOULD</bcp14> limit the returned certificate bundle to a reasonable length.
Results from a User ID search <bcp14>SHOULD</bcp14> be sorted in order of decreasing confidence in that identity (<xref target="confidence"/>), and then by creation date (most recent first).
A keyserver <bcp14>MAY</bcp14> choose to only return results where the identity being searched for has a nonzero confidence value.
If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="hget-operation"><name>The "hget" (hash get) Operation</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "hget" operation.</t>

<t>"hget" requests a certificate from a keyserver by specifying its <xref target="SKS"></xref> digest.
The digest is provided in the "search" variable in hexadecimal encoding, without a preceding "0x".
The hexadecimal digits are not case sensitive.</t>

<t>If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="index-operation"><name>The "index" Operation</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "index" operation.</t>

<t>The "index" operation requests a list of certificates on the keyserver that match the text in the "search" variable.
Historically, the "index" operation returned a human-readable HTML document containing links for each found certificate, but this is not required.</t>

<t>A keyserver <bcp14>SHOULD</bcp14> limit the returned index to a reasonable length.
Results from a User ID search <bcp14>SHOULD</bcp14> be sorted in order of decreasing confidence in that identity (<xref target="confidence"/>), and then by creation date (most recent first).
If no certificates match the request, the keyserver <bcp14>SHOULD</bcp14> return an appropriate HTTP error code such as 404 ("Not Found").</t>

</section>
<section anchor="vindex-operation"><name>The "vindex" (verbose index) Operation (Deprecated)</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "vindex" operation.
The "vindex" operation is deprecated.
Historically, a "vindex" response was the same as "index" with the addition of showing the signatures on each certificate, but this is not required.
A server that supports "vindex" <bcp14>SHOULD</bcp14> treat it as a synonym for "index".</t>

</section>
<section anchor="stats-operation"><name>The "stats" (statistics/status) Operation (Deprecated)</name>

<t>A keyserver <bcp14>MAY</bcp14> support the "stats" operation.
The "stats" operation is deprecated.
It is <bcp14>RECOMMENDED</bcp14> to use a URL outside the standard HKP paths (such as "/pks/stats") instead.</t>

<t>The output of the "stats" operation is implementation-dependent, but may include diagnostic output, configuration state, or other metadata.
The "search" variable <bcp14>SHOULD NOT</bcp14> be supplied, and <bcp14>SHOULD</bcp14> be ignored if received.</t>

</section>
<section anchor="search-lookup-variable"><name>The "search" Lookup Variable</name>

<t>The "search" variable contains arbitrary text encoded as usual for a HTTP URL.
This text may represent a Key ID, or fingerprint, or some text from a User ID on the certificate being sought, depending on the operation.</t>

<section anchor="legacy-searches"><name>Legacy Key ID and Fingerprint Searches</name>

<t>To search for a certificate by the Key ID or fingerprint of a primary key or subkey, a client <bcp14>SHOULD</bcp14> use a v2 lookup and either the "certs/by-keyid" (<xref target="keyid-category"/>) or "certs/by-vfingerprint" (<xref target="vfingerprint-category"/>) lookup category (as appropriate).</t>

<t>If making a Legacy lookup, a client <bcp14>SHOULD</bcp14> use the "get" operation and prefix the "search" string with "0x" to indicate a hexadecimal number.
Key ID strings are 16 hexadecimal digits (64 bits).
Fingerprint strings are either 32 (version 3), 40 (version 4), or 64 (version 6) hexadecimal digits and do not include the version number.
The hexadecimal digits are not case sensitive.</t>

<t>A keyserver:</t>

<t><list style="symbols">
  <t><bcp14>SHOULD</bcp14> accept fingerprints and <bcp14>MAY</bcp14> accept 64-bit Key IDs in the Legacy lookup "search" variable.</t>
  <t><bcp14>SHOULD</bcp14> include matches with both primary key and subkey fingerprints and Key IDs.</t>
  <t><bcp14>MAY</bcp14> omit matches with encryption-only subkeys.</t>
  <t><bcp14>MUST NOT</bcp14> return results for 32-bit "short Key ID" searches, as these do not provide sufficient collision resistance.</t>
  <t><bcp14>MUST NOT</bcp14> return certificates with versions later than 4 for Key ID searches.</t>
  <t><bcp14>MUST NOT</bcp14> return version 6 (or later) certificates in the results for Legacy machine-readable requests, but <bcp14>MAY</bcp14> do so for Legacy human-readable requests (<xref target="legacy-mr-output"/>).</t>
</list></t>

<t>V3 certificates are no longer considered secure, but <bcp14>MAY</bcp14> be distributed for historical reference.</t>

</section>
<section anchor="legacy-text-searches"><name>Legacy Text Searches</name>

<t>To perform a Legacy search for a certificate by the text of a User ID, a client <bcp14>SHOULD</bcp14> use the "get" or "index" operation (as appropriate) and <bcp14>MUST NOT</bcp14> prefix the "search" string with "0x".
A keyserver <bcp14>MUST NOT</bcp14> return version 6 (or later) certificates in the results for Legacy machine-readable requests, but <bcp14>MAY</bcp14> do so for Legacy human-readable requests (<xref target="legacy-mr-indexes"/>).</t>

<t>Legacy text searches <bcp14>SHOULD</bcp14> only return results if the "search" variable exactly matches one of the following:</t>

<t><list style="symbols">
  <t>The full text string of a User ID.</t>
  <t>The portion between angle brackets (<spanx style="verb">&lt;...&gt;</spanx>) in an email-address style User ID.</t>
</list></t>

<t>Text searches <bcp14>SHOULD NOT</bcp14> be case sensitive.
DNS names are not case sensitive, therefore any User ID that contains a DNS name (including email addresses) cannot be reliably located using case sensitive matching.
Since the interpretation of User IDs is application-specific, a client <bcp14>MUST</bcp14> check that any User IDs returned from a keyserver are correctly case matched for the intended application.</t>

<t>A client making a Legacy text search <bcp14>SHOULD</bcp14> set the modifier variable "exact=on" (<xref target="exact-variable"/>).</t>

<t>To ensure that relevant results are returned, it is <bcp14>RECOMMENDED</bcp14> that implementations limit themselves to a subset of UTF-8 when generating both User IDs and search strings:</t>

<t><list style="symbols">
  <t>Canonicalise to Unicode Normalization Form C <xref target="UNF"></xref>.</t>
  <t>Do not use punycode <xref target="RFC3492"></xref>.</t>
  <t>Use lowercase in the domain part of email addresses.</t>
  <t>Avoid leading or trailing whitespace.</t>
  <t>Avoid control characters, including format effectors (such as tabs or newlines).</t>
</list></t>

<t>A keyserver <bcp14>MUST NOT</bcp14> return legacy text search results for a search string that begins with "0x".
Since the "0x" prefix is generally understood as indicating a fingerprint or key ID, violating this convention could enable a key substitution attack.</t>

</section>
</section>
<section anchor="legacy-lookup-examples"><name>Legacy Lookup Examples</name>

<t>Search for all certificates containing the email address <spanx style="verb">dshaw@example.com</spanx>, using plaintext HTTP:</t>

<figure><artwork><![CDATA[
http://keys.example.com:11371/pks/lookup?search=dshaw@example.com&op=index
]]></artwork></figure>

<t>Get certificate 0xDEADBEEFDECAFBADDEADBEEFDECAFBADDEADBEEFDECAFBAD (v4 fingerprint), using HTTPS:</t>

<figure><artwork><![CDATA[
https://keys.example.com/pks/lookup?op=get&search=0xDEADBEEFDECAFBADDEADBEEFDECAFBADDEADBEEFDECAFBAD
]]></artwork></figure>

<t>Get certificate 0xDEADBEEFDECAFBAD (64-bit Key ID), using HTTPS:</t>

<figure><artwork><![CDATA[
https://keys.example.com/pks/lookup?op=get&search=0xDEADBEEFDECAFBAD
]]></artwork></figure>

</section>
</section>
<section anchor="legacy-submission"><name>Legacy Submission Format</name>

<t>Legacy certificate submissions are performed via an HTTP POST request.
The URL path (<xref section="3.3" sectionFormat="of" target="RFC3986"/>) is always "/pks/add".
No URL path components under "/pks/add" are used, and there are no mandatory query strings.</t>

<t>The body of the POST message has a content-type of <spanx style="verb">application/x-www-form-urlencoded</spanx>.
It contains a "keytext" field whose value is an ASCII-armored certificate bundle as specified in <xref target="certificate-bundle-format"/>.
The ASCII armored certificate bundle <bcp14>MUST</bcp14> be form-urlencoded as specified in <xref section="8.2.1" sectionFormat="of" target="RFC1866"/>.</t>

<t>There may also be modifier variables, as specified in <xref target="legacy-modifier-variables"/> below.
Modifiers are passed using HTTP query strings as specified in <xref section="3.4" sectionFormat="of" target="RFC3986"/>.
HTTP query strings <bcp14>MAY</bcp14> be given in any order.
Keyservers <bcp14>MUST</bcp14> ignore any unknown query strings.</t>

<t>Note that more than one certificate may be submitted in a single transaction.</t>

<t>If a keyserver does not support adding certificates via HTTP, then requests to do so should return an appropriate HTTP error code, such as 403 ("Forbidden") if certificate submission has been disallowed, or 404 ("Not Found") if the server does not support the legacy submission API.</t>

</section>
<section anchor="legacy-modifier-variables"><name>Legacy Modifier Variables</name>

<t>These variables are used to modify basic Legacy requests.</t>

<texttable title="Legacy Variable Names" anchor="legacy-variable-names">
      <ttcol align='left'>Name</ttcol>
      <ttcol align='left'>Context</ttcol>
      <ttcol align='left'>Value</ttcol>
      <ttcol align='left'>See</ttcol>
      <c>options</c>
      <c>any</c>
      <c>list of flags</c>
      <c><xref target="options-variable"/></c>
      <c>fingerprint</c>
      <c>lookup</c>
      <c>"on" or "off"</c>
      <c><xref target="fingerprint-variable"/></c>
      <c>hash</c>
      <c>lookup</c>
      <c>"on" or "off"</c>
      <c><xref target="hash-variable"/></c>
      <c>exact</c>
      <c>lookup</c>
      <c>"on" or "off"</c>
      <c><xref target="exact-variable"/></c>
</texttable>

<section anchor="options-variable"><name>The "options" Variable</name>

<t>This variable takes one or more option values, separated by commas.
These are used to modify the behavior of the keyserver on a per-request basis.
Each value indicates a boolean flag, where the presence of the value indicates "true" and the absence "false".</t>

<texttable title="Legacy Option Values" anchor="legacy-option-values">
      <ttcol align='left'>Name</ttcol>
      <ttcol align='left'>Context</ttcol>
      <ttcol align='left'>See</ttcol>
      <c>nm</c>
      <c>submission</c>
      <c><xref target="nm-option"/></c>
      <c>mr</c>
      <c>lookup</c>
      <c><xref target="mr-option"/></c>
</texttable>

<section anchor="nm-option"><name>The "nm" (No Modification) Option</name>

<t>As keyservers may modify submitted certificates to suit a particular policy, this option is used to inform the keyserver that the submitter would rather have the submission fail completely than have the submitted certificate(s) modified.
An example of this would be a keyserver that does not accept User IDs with an email address outside of the local domain.
If such a certificate was submitted, the keyserver <bcp14>MAY</bcp14> trim any noncompliant User IDs before accepting the certificate.
If this option was set, then such a certificate submission <bcp14>SHOULD</bcp14> fail with an appropriate error code such as 422 (Unprocessable content).</t>

<t>"nm" is meaningful for submissions only.</t>

</section>
<section anchor="mr-option"><name>The "mr" (Machine-Readable) Option</name>

<t>The machine-readable option instructs the server that a program (rather than a person) is making a Legacy request, so the output <bcp14>SHOULD</bcp14> be in Legacy machine-readable format.
If a v2 request format is being used, this option has no effect.
See <xref target="legacy-mr-output"/> for the specific details of Legacy machine-readable output.</t>

<t>An implementation that does not wish to provide a human-readable interface <bcp14>MAY</bcp14> choose to behave as if this option is always present.
Implementations <bcp14>SHOULD NOT</bcp14> provide a Legacy interface without supporting machine-readable output.</t>

<t>"mr" is meaningful for Legacy lookups only.</t>

</section>
</section>
<section anchor="fingerprint-variable"><name>The "fingerprint" Variable</name>

<t>This variable takes one argument: "on" or "off".
If present and on, it instructs the server to provide the primary key fingerprint for each certificate in a Legacy "index" or "vindex" operation.
This variable has no effect on any other operation.
The exact format of the displayed fingerprint, like the "index" and "vindex" operations themselves, is implementation defined in Legacy human-readable output.
In Legacy machine-readable indexes, a value of "on" indicates that the "keyid" field <bcp14>SHOULD</bcp14> contain the fingerprint, except for v3 certificates (<xref target="legacy-mr-indexes"/>).
An implementation <bcp14>SHOULD</bcp14> treat this variable as being "on" for all Legacy machine-readable indexes.
An implementation <bcp14>MAY</bcp14> decide to ignore this variable and/or set the default behaviour to "on" for Legacy human-readable indexes.</t>

<t>"fingerprint" is meaningful for Legacy lookups only.</t>

</section>
<section anchor="hash-variable"><name>The "hash" Variable</name>

<t>This variable takes one argument: "on" or "off".
If present and on, it instructs the server to provide the <xref target="SKS"></xref> digest of each certificate in an "index" or "vindex" operation in the Legacy human-readable output format.
This variable has no effect on any other operation, or on Legacy machine-readable output.
The exact format of the displayed digest, like the "index" and "vindex" operations themselves, is implementation defined.
An implementation <bcp14>MAY</bcp14> decide to ignore this variable and/or set the default behaviour to "on".</t>

<t>"hash" is meaningful for Legacy lookups only.</t>

</section>
<section anchor="exact-variable"><name>The "exact" Variable</name>

<t>This variable takes one argument: "on" or "off".
If set to "off", it instructs the server that it <bcp14>MAY</bcp14> use non-exact matching for the contents of the "search" variable in text searches (<xref target="legacy-text-searches"/>).
How a keyserver handles non-exact text searches is implementation defined.
For example, a keyserver <bcp14>MAY</bcp14> use case-insensitive or tokenized searching.</t>

<t>A keyserver implementation <bcp14>SHOULD</bcp14> set the default behaviour to "on" and <bcp14>MAY</bcp14> ignore this variable.</t>

<t>"exact" is meaningful for Legacy lookups only.</t>

</section>
</section>
</section>
<section anchor="output-formats"><name>Output Formats</name>

<t>HKP was originally intended for both human and programmatic use.
In general, the Legacy human-readable output is implementation specific.
The "machine-readable" option is used to tailor the output of Legacy requests for automated use.
For interoperability, the Legacy machine-readable output <bcp14>MUST</bcp14> carefully follow the guidelines given here.
A client implementation <bcp14>SHOULD NOT</bcp14> attempt to parse Legacy human-readable output.</t>

<t>The v2 API always returns either non-armored certificate bundles or JSON <xref target="RFC8259"></xref>, depending on the request.</t>

<section anchor="v2-output-format"><name>v2 Output Format</name>

<t>Clients making v2 requests:</t>

<t><list style="symbols">
  <t><bcp14>MUST</bcp14> silently ignore any primary keys with unknown versions or algorithms.</t>
  <t><bcp14>MUST</bcp14> silently ignore any unknown fields in JSON responses.</t>
</list></t>

<t>In response to a v2 request, a keyserver:</t>

<t><list style="symbols">
  <t><bcp14>MUST</bcp14> set the HTTP header <spanx style="verb">Access-Control-Allow-Origin: *</spanx>, as specified in <xref target="CORS"></xref>.</t>
  <t><bcp14>MUST</bcp14> use the format specified in <xref target="v2-indexes"/> when responding to "index" lookups.</t>
  <t><bcp14>MUST</bcp14> use the format specified in <xref target="submission-responses"/> when responding to "certs" submissions.</t>
  <t><bcp14>MUST</bcp14> return non-armored (binary) certificate bundles in response to lookup requests.</t>
  <t><bcp14>MUST</bcp14> set <spanx style="verb">Content-Type: application/json</spanx> for JSON responses.</t>
  <t><bcp14>MUST</bcp14> set <spanx style="verb">Content-Type: application/pgp-keys;armor=no</spanx> when returning non-armored certificate bundles (<xref section="5" sectionFormat="of" target="I-D.gallagher-openpgp-media-types"/>).</t>
  <t><bcp14>MAY</bcp14> set <spanx style="verb">Last-Modified:</spanx> to indicate the modification date of the requested certificate or certificate bundle (<xref section="8.8.2" sectionFormat="of" target="RFC9110"/>).</t>
</list></t>

<section anchor="v2-indexes"><name>v2 Indexes</name>

<t>A v2 "index" request <bcp14>SHOULD</bcp14> return a JSON list of certificates.
If the search was for an identity, it <bcp14>SHOULD</bcp14> be sorted in decreasing order of confidence (<xref target="confidence"/>).
Each certificate object contains some or all of the following fields:</t>

<texttable title="v2 Index Fields" anchor="v2-index-certificate-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>version</c>
      <c>integer</c>
      <c>version of the primary key (<bcp14>REQUIRED</bcp14>)</c>
      <c>fingerprint</c>
      <c>string</c>
      <c>fingerprint of the primary key (<bcp14>REQUIRED</bcp14>)</c>
      <c>creation</c>
      <c>string</c>
      <c>creation date of the key</c>
      <c>expiration</c>
      <c>string</c>
      <c>expiration date of the key</c>
      <c>isExpired</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>isRevoked</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>algorithm</c>
      <c>algorithm</c>
      <c>(<xref target="v2-index-algorithm-fields"/>)</c>
      <c>userIDs</c>
      <c>userID array</c>
      <c>(<xref target="v2-index-userid-fields"/>)</c>
      <c>subkeys</c>
      <c>subkey array</c>
      <c>(<xref target="v2-index-subkey-fields"/>)</c>
</texttable>

<texttable title="v2 Index Algorithm Fields" anchor="v2-index-algorithm-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>code</c>
      <c>integer</c>
      <c>algorithm ID (<bcp14>REQUIRED</bcp14>)</c>
      <c>name</c>
      <c>string</c>
      <c>a human-readable identifier for the algorithm</c>
      <c>bitLength</c>
      <c>integer</c>
      <c>key length in bits (DSA/RSA/ElGamal keys only)</c>
</texttable>

<texttable title="v2 Index UserID Fields" anchor="v2-index-userid-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>uidString</c>
      <c>string</c>
      <c>User ID string contents (<bcp14>REQUIRED</bcp14>)</c>
      <c>creation</c>
      <c>string</c>
      <c>creation date of (the first signature over) the User ID</c>
      <c>expiration</c>
      <c>string</c>
      <c>expiration date of the User ID</c>
      <c>isExpired</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>isRevoked</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>confidence</c>
      <c>integer</c>
      <c>(<xref target="confidence"/>)</c>
</texttable>

<texttable title="v2 Index Subkey Fields" anchor="v2-index-subkey-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>version</c>
      <c>integer</c>
      <c>version of the subkey (<bcp14>REQUIRED</bcp14>)</c>
      <c>fingerprint</c>
      <c>string</c>
      <c>fingerprint of the subkey (<bcp14>REQUIRED</bcp14>)</c>
      <c>creation</c>
      <c>string</c>
      <c>creation date of the subkey</c>
      <c>expiration</c>
      <c>string</c>
      <c>expiration date of the subkey</c>
      <c>isExpired</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>isRevoked</c>
      <c>boolean</c>
      <c>&#160;</c>
      <c>algorithm</c>
      <c>algorithm</c>
      <c>(<xref target="v2-index-algorithm-fields"/>)</c>
</texttable>

<t>Fingerprints are given in hexadecimal notation, without any "0x" prefix.
Timestamps are given in UTC as per <xref section="5.6" sectionFormat="of" target="RFC3339"/>.
Algorithm IDs are as specified in <xref section="9.1" sectionFormat="of" target="RFC9580"/>.</t>

<t>The only required fields are the version and fingerprint of any key material, and the uidString of any User IDs.
Implementations <bcp14>MAY</bcp14> omit algorithms, subkeys and User IDs from indexes; however if they are present they <bcp14>MUST</bcp14> contain the required fields.</t>

</section>
</section>
<section anchor="submission-responses"><name>v2 and Legacy Submission Responses</name>

<t>A v2 or Legacy submission <bcp14>MAY</bcp14> return an empty response, or it <bcp14>MAY</bcp14> return a JSON object summarising the changes.
The JSON object <bcp14>MAY</bcp14> contain any or all of the following fields, each of which is an array of certificate objects:</t>

<texttable title="Submission Response Fields" anchor="submission-response-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Type</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>inserted</c>
      <c>certificate array</c>
      <c>newly added certificates</c>
      <c>updated</c>
      <c>certificate array</c>
      <c>updated certificates</c>
      <c>deleted</c>
      <c>certificate array</c>
      <c>deleted certificates</c>
      <c>ignored</c>
      <c>certificate array</c>
      <c>certificates with no new information</c>
      <c>invalid</c>
      <c>certificate array</c>
      <c>certificates that could not be processed</c>
</texttable>

<t>Each certificate object <bcp14>MUST</bcp14> contain "version" and "fingerprint" fields, as in <xref target="v2-index-certificate-fields"/>.</t>

<t>Certificates in the "ignored" and "invalid" arrays <bcp14>MAY</bcp14> also contain a "comment" field describing the reason for their rejection.
The comment is a human-readable string, and <bcp14>MAY</bcp14> be displayed to the user.</t>

</section>
<section anchor="legacy-mr-output"><name>Legacy machine-readable Output</name>

<t>Clients requesting machine-readable output in Legacy lookup requests:</t>

<t><list style="symbols">
  <t><bcp14>SHOULD</bcp14> supply <spanx style="verb">options=mr</spanx> (<xref target="mr-option"/>).</t>
  <t><bcp14>MUST</bcp14> silently ignore any content preceding or following a returned armored key block.</t>
  <t><bcp14>MUST</bcp14> silently ignore any primary keys with unknown versions or algorithms.</t>
</list></t>

<t>Keyservers returning Legacy machine-readable output:</t>

<t><list style="symbols">
  <t><bcp14>MUST</bcp14> set the HTTP header <spanx style="verb">Access-Control-Allow-Origin: *</spanx>, as specified in <xref target="CORS"></xref>.</t>
  <t><bcp14>MUST</bcp14> return ASCII-armored certificate bundles.</t>
  <t><bcp14>MUST NOT</bcp14> return version 6 (or later) certificates.</t>
  <t><bcp14>MUST</bcp14> set <spanx style="verb">Content-Type: application/pgp-keys</spanx> when returning ASCII-armored certificate bundles (the "get" and "hget" operations), as specified in <xref section="7" sectionFormat="of" target="RFC3156"/>.</t>
  <t><bcp14>MAY</bcp14> set <spanx style="verb">Last-Modified:</spanx> to indicate the modification date of the requested certificate or certificate bundle (<xref section="8.8.2" sectionFormat="of" target="RFC9110"/>).</t>
  <t><bcp14>MUST</bcp14> use the format specified in <xref target="legacy-mr-indexes"/> when returning indexes (the "index" and "vindex" operations).</t>
  <t><bcp14>MAY</bcp14> return statistics in JSON format <xref target="RFC8259"></xref>, the schema of which is otherwise implementation-dependent.</t>
</list></t>

<t>ASCII-armored responses <bcp14>MAY</bcp14> be wrapped in any HTML or other text desired, except that the actual certificate data consisting of an initial line break, the <spanx style="verb">-----BEGIN PGP PUBLIC KEY BLOCK-----</spanx> header, the armored certificate data itself, the <spanx style="verb">-----END PGP PUBLIC KEY BLOCK-----</spanx> footer, and a final line break <bcp14>MUST NOT</bcp14> be modified from the form specified in <xref target="RFC9580"></xref>.</t>

<section anchor="legacy-mr-indexes"><name>Legacy machine-readable Indexes</name>

<t>The Legacy machine-readable index format is a list of newline-separated records, consisting of colon-separated fields.
The document is 7-bit clean, and as such is sent with no encoding and <spanx style="verb">Content-Type: text/plain</spanx>.</t>

<t>The machine-readable response <bcp14>MAY</bcp14> be prefixed by an information record:</t>

<figure><artwork><![CDATA[
info:<version>:<count>
]]></artwork></figure>

<texttable title="Legacy Information Record Fields" anchor="legacy-information-record-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>version</c>
      <c>the version of this output format</c>
      <c>count</c>
      <c>the number of certificates returned</c>
</texttable>

<t>If this line is not included, or the version information is not supplied, the version number is assumed to be 1.
Currently, only version 1 is defined.</t>

<t>Note that "count" is the number of certificates, and not the number of lines returned.
That is, it <bcp14>SHOULD</bcp14> match the number of "pub" lines returned.</t>

<t>The certificate listings themselves are made up of several records per certificate.
The first record specifies the primary key:</t>

<figure><artwork><![CDATA[
pub:<keyID>:<code>:<bitLength>:<creation>:<expiration>:<flags>
]]></artwork></figure>

<texttable title="Legacy Public Key Record Fields" anchor="legacy-public-key-record-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>keyID</c>
      <c>fingerprint or long Key ID</c>
      <c>code</c>
      <c>algorithm ID</c>
      <c>bitLength</c>
      <c>key length in bits</c>
      <c>creation</c>
      <c>creation date of the key</c>
      <c>expiration</c>
      <c>expiration date of the key</c>
      <c>flags</c>
      <c>letter codes to indicate details of the key</c>
</texttable>

<t>Since it is not possible to calculate the Key ID from a V3 fingerprint, for V3 primary keys the "keyID" field <bcp14>SHOULD</bcp14> contain the 16-digit long Key ID only.
Otherwise, a keyserver <bcp14>SHOULD</bcp14> return a fingerprint if available (<xref target="fingerprint-variable"/>).</t>

<t>Fingerprints and long Key IDs are given in hexadecimal notation, without any "0x" prefix.
Timestamps are given in seconds since midnight on 1st January 1970.
Algorithm IDs are as specified in <xref section="9.1" sectionFormat="of" target="RFC9580"/>.</t>

<t>Following the "pub" record are one or more "uid" records to indicate User IDs on the certificate:</t>

<figure><artwork><![CDATA[
uid:<uidString>:<creation>:<expiration>:<flags>
]]></artwork></figure>

<texttable title="Legacy User ID Record Fields" anchor="legacy-index-userid-fields">
      <ttcol align='left'>Field</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c>uidString</c>
      <c>User ID string contents</c>
      <c>creation</c>
      <c>creation date of (the first self-signature over) the User ID</c>
      <c>expiration</c>
      <c>expiration date of the User ID</c>
      <c>flags</c>
      <c>letter codes to indicate details of the User ID</c>
</texttable>

<t>The User ID string <bcp14>MUST</bcp14> use percent-encoding (<xref section="2.1" sectionFormat="of" target="RFC3986"/>) for anything that isn't 7-bit safe as well as for any <spanx style="verb">:</spanx> and <spanx style="verb">%</spanx> characters that appear in a field value.
Any other characters <bcp14>MAY</bcp14> be percent-encoded, as desired.</t>

<t>The information for the "creation", "expiration", and "flags" fields is taken from the User ID self-signature, if any, and applies to the User ID in question, not to the certificate as a whole.</t>

<t>Primary key and User ID records may contain a "flags" field containing a sequence of alphabetical characters, one per flag.
Flags <bcp14>MAY</bcp14> be given in any order.
The meaning of "disabled" is implementation-specific.
Note that individual flags may be unimplemented, so the absence of a given flag does not necessarily mean the absence of the detail.</t>

<texttable title="Legacy Record Flags" anchor="legacy-record-flags">
      <ttcol align='left'>Flag</ttcol>
      <ttcol align='left'>Description</ttcol>
      <c><spanx style="verb">r</spanx></c>
      <c>revoked</c>
      <c><spanx style="verb">d</spanx></c>
      <c>disabled</c>
      <c><spanx style="verb">e</spanx></c>
      <c>expired</c>
</texttable>

<t>Note that empty fields are allowed.
For example, a primary key with no expiration date would have the "expirationdate" field empty.
Also, a keyserver that does not track a particular piece of information may leave that field empty as well.
Colons for empty fields on the end of each line <bcp14>MAY</bcp14> be left off, if desired.
All dates are given in the number of seconds since 1970-01-01T00:00:00 UTC.</t>

<t>For backwards compatibility with the installed client base, Legacy machine-readable lookup requests <bcp14>MUST</bcp14> omit version 6 (and later) certificates from the returned indexes.</t>

</section>
</section>
</section>
<section anchor="confidence"><name>Confidence</name>

<t>Traditionally, keyservers did not perform any checks against uploaded content other than simple parseability.
This left them open to abuse such as flooding and third-party signature spam.
Most modern keyservers are now able to perform cryptographic validity tests, and automated content moderation is generally possible.</t>

<t>It is <bcp14>RECOMMENDED</bcp14> that a keyserver assigns a "confidence" value to each User ID in its database.
The exact definition of "confidence" is implementation-dependent, but <bcp14>MAY</bcp14> include checks such as email verification or third-party certifications.</t>

<t>A keyserver <bcp14>MAY</bcp14> represent confidence as a number between 0 and 255, where values of 120 or greater indicate "complete confidence", in a v2 Index User ID object (<xref target="v2-index-userid-fields"/>).
This is numerically compatible with the "trust amount" field specified in <xref section="5.2.3.21" sectionFormat="of" target="RFC9580"/>, but it is not required to calculate it in the same way or represent it internally as an integer value.
The confidence field in a v2 Index User ID object is intended as a heuristic for sorting and filtering responses to lookup requests, and is not a replacement for cryptographic verification.
A client <bcp14>SHOULD NOT</bcp14> rely on this confidence field, and <bcp14>SHOULD</bcp14> perform its own checks.
A keyserver that wishes to publish a cryptographically-verifiable statement about its internal confidence value <bcp14>MAY</bcp14> do so using a certification signature.</t>

</section>
<section anchor="certificate-bundle-format"><name>Certificate Bundle Format</name>

<t>HKP uses a "certificate bundle" as its primary data representation for both input and output.</t>

<t>A certificate bundle is a sequence of one or more OpenPGP certificates (Transferable Public Keys), concatenated directly, as specified in Sections <xref target="RFC9580" section="10.1" sectionFormat="bare"/> and <xref target="RFC9580" section="3.6" sectionFormat="bare"/> of <xref target="RFC9580"/>.
An ASCII-armored certificate bundle is a certificate bundle that has been encoded as a single armored block, as specified in <xref section="6.2" sectionFormat="of" target="RFC9580"/>.
The Legacy API uses ASCII-armored certificate bundles exclusively, whereas the v2 API uses non-armored certificate bundles exclusively.</t>

<t>Certificate bundles are often called "keyrings", however the term "keyring" is used to refer to several related but distinct concepts:</t>

<t><list style="symbols">
  <t>A sequence of one or more Transferable Public Keys ("public keyring")</t>
  <t>A sequence of one or more Transferable Secret Keys ("private/secret keyring")</t>
  <t>A sequence of packets forming a single Transferable Public Key</t>
  <t>A sequence of packets forming a single Transferable Secret Key</t>
</list></t>

<t>It is therefore <bcp14>RECOMMENDED</bcp14> that implementations avoid using the term "keyring" without qualification.</t>

<section anchor="detached-revocations"><name>Detached Revocations</name>

<t>For OpenPGP certificates prior to version 6, revocation signatures have customarily been distributed as a detached "revocation certificate", as per <xref section="10.1.3" sectionFormat="of" target="RFC9580"/>.
An HKP server <bcp14>SHOULD</bcp14> allow submission of these detached revocations.</t>

<t>An HKP implementation <bcp14>MAY</bcp14> accept or serve an ASCII-armored "mixed certificate bundle" where one or more revoked certificates have been replaced by their detached revocation certificate(s).
Such a "mixed certificate bundle" <bcp14>MUST</bcp14> be sorted so that all detached revocation certificates appear first.
This ensures that detached revocations cannot be mistaken for signatures over another primary key.</t>

<t>Mixed certificate bundles <bcp14>MUST NOT</bcp14> be served in responses to v2 lookup requests.</t>

</section>
</section>
<section anchor="certificate-discovery-using-hkps"><name>Certificate Discovery Using HKPS</name>

<t>SRV records <xref target="RFC2782"></xref> are commonly used by clients to discover the location of internet services.
We can use the "openpgpkey" service name to locate an HKPS service for certificate discovery.
HKP clients <bcp14>SHOULD</bcp14> support SRV records.</t>

<section anchor="openpgpkey-srv-record"><name>The "openpgpkey" SRV Record</name>

<t>The service name for HKPS discovery is "openpgpkey", and the protocol name is "https".
The service and protocol labels are therefore "_openpgpkey" and "_https" respectively.
These are prepended to the domain part of the email addresses for which certificates are being published:</t>

<figure><artwork><![CDATA[
_openpgpkey._https.<domain-part>
]]></artwork></figure>

<t>A domain owner wishing to publish OpenPGP certificates for their users would create one or more SRV records at this location, each referencing the address and port number of a keyserver that is authoritative for that domain.
Each unique domain part for which email addresses are supported will have its own SRV records.</t>

</section>
<section anchor="discovery-lookup-over-hkps"><name>Discovery Lookup Over HKPS</name>

<t>When making an HKPS discovery request, a client <bcp14>SHOULD</bcp14> use an HTTP GET request to an authoritative keyserver using the "canonical" lookup category, with the email address in the "identifier" component.</t>

<t>Note that discovery is performed using the "canonical" lookup category, to ensure that the discovery results have been filtered.
The domain owner <bcp14>SHOULD</bcp14> take reasonable steps to ensure that any certificates returned from this lookup request are valid certificates for the identity in the "identifier" component.
Discovery <bcp14>MAY</bcp14> be implemented at low cost by serving such requests from a static filesystem.</t>

<t>It is <bcp14>RECOMMENDED</bcp14> that certificates returned from discovery are subject to further verification on the client side wherever possible, to mitigate against compromise of the discovery server.</t>

</section>
<section anchor="certificate-discovery-example"><name>Certificate Discovery Example</name>

<t>A client trying to locate a certificate for isabella@example.com makes a DNS request for the SRV record at <spanx style="verb">_openpgpkey._https.example.com.</spanx>.
This would return:</t>

<figure><artwork><![CDATA[
_openpgpkey._https.example.com. 3600 IN SRV 1 1 443 keyserver.example.com
]]></artwork></figure>

<t>On finding this record, the client makes an HTTP GET request for the following URL:</t>

<figure><artwork><![CDATA[
hkps://keyserver.example.com:443/pks/v2/canonical/isabella@example.com
]]></artwork></figure>

<t>The keyserver returns the canonical bundle for isabella@example.com, and the client proceeds to check its validity according to the local policy.</t>

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

<t>As described here, a keyserver is a searchable database of OpenPGP Certificates accessed over the network.
While there may be security considerations arising from distributing arbitrary certificates in this manner, this does not impact the security of OpenPGP itself.</t>

<t>Without some sort of trust relationship between the client and server, information returned from a keyserver in arbitrary search results cannot be trusted by the client until the OpenPGP client actually retrieves and checks the certificate for itself.
This is important and must be stressed: without a specific reason to treat information otherwise, all search results <bcp14>SHOULD</bcp14> be regarded as untrustworthy and informational only.</t>

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

<t>This document allocates the ports 11371 and 11372, the service names "hkps" and "openpgpkey", and the URI schemes "hkp" and "hkps".</t>

<section anchor="updated-registry-entries"><name>Updated Registry Entries</name>

<t>IANA is requested to update the contact details for port 11371 in the "Service Name and Transport Protocol Port Number" registry to "Daphne Shaw".</t>

</section>
<section anchor="new-registry-entries"><name>New Registry Entries</name>

<t>IANA is requested to add the following entries to the "Service Name and Transport Protocol Port Number" registry as per <xref target="RFC6335"></xref>:</t>

<texttable title="Service Name and Transport Protocol Port Number Registry" anchor="service-name-port-registry">
      <ttcol align='left'>Service Name</ttcol>
      <ttcol align='left'>Port</ttcol>
      <ttcol align='left'>Transport Protocol</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Contact</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>hkps</c>
      <c>11372</c>
      <c>tcp and udp</c>
      <c>OpenPGP HTTP Keyserver (Secure)</c>
      <c>Daphne Shaw</c>
      <c>This document</c>
      <c>openpgpkey</c>
      <c>&#160;</c>
      <c>&#160;</c>
      <c>OpenPGP Certificate Discovery</c>
      <c>Daphne Shaw</c>
      <c>This document</c>
</texttable>

<t>IANA is requested to add the following entries to the "URI Schemes" registry as per <xref target="RFC7595"></xref>:</t>

<texttable title="Uniform Resource Identifier (URI) Schemes Registry" anchor="uri-schemes-registry">
      <ttcol align='left'>URI Scheme</ttcol>
      <ttcol align='left'>Description</ttcol>
      <ttcol align='left'>Status</ttcol>
      <ttcol align='left'>Reference</ttcol>
      <c>hkp</c>
      <c>OpenPGP HTTP Keyserver</c>
      <c>Permanent</c>
      <c>This document</c>
      <c>hkps</c>
      <c>OpenPGP HTTP Keyserver (Secure)</c>
      <c>Permanent</c>
      <c>This document</c>
</texttable>

</section>
</section>


  </middle>

  <back>


<references title='References' anchor="sec-combined-references">

    <references title='Normative References' anchor="sec-normative-references">



<reference anchor="RFC1866">
  <front>
    <title>Hypertext Markup Language - 2.0</title>
    <author fullname="T. Berners-Lee" initials="T." surname="Berners-Lee"/>
    <author fullname="D. Connolly" initials="D." surname="Connolly"/>
    <date month="November" year="1995"/>
    <abstract>
      <t>This document defines a HTML 2.0 (to distinguish it from the previous informal specifications). [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="1866"/>
  <seriesInfo name="DOI" value="10.17487/RFC1866"/>
</reference>
<reference anchor="RFC2782">
  <front>
    <title>A DNS RR for specifying the location of services (DNS SRV)</title>
    <author fullname="A. Gulbrandsen" initials="A." surname="Gulbrandsen"/>
    <author fullname="P. Vixie" initials="P." surname="Vixie"/>
    <author fullname="L. Esibov" initials="L." surname="Esibov"/>
    <date month="February" year="2000"/>
    <abstract>
      <t>This document describes a DNS RR which specifies the location of the server(s) for a specific protocol and domain. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="2782"/>
  <seriesInfo name="DOI" value="10.17487/RFC2782"/>
</reference>
<reference anchor="RFC3156">
  <front>
    <title>MIME Security with OpenPGP</title>
    <author fullname="M. Elkins" initials="M." surname="Elkins"/>
    <author fullname="D. Del Torto" initials="D." surname="Del Torto"/>
    <author fullname="R. Levien" initials="R." surname="Levien"/>
    <author fullname="T. Roessler" initials="T." surname="Roessler"/>
    <date month="August" year="2001"/>
    <abstract>
      <t>This document describes how the OpenPGP Message Format can be used to provide privacy and authentication using the Multipurpose Internet Mail Extensions (MIME) security content types described in RFC 1847. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="3156"/>
  <seriesInfo name="DOI" value="10.17487/RFC3156"/>
</reference>
<reference anchor="RFC3339">
  <front>
    <title>Date and Time on the Internet: Timestamps</title>
    <author fullname="G. Klyne" initials="G." surname="Klyne"/>
    <author fullname="C. Newman" initials="C." surname="Newman"/>
    <date month="July" year="2002"/>
    <abstract>
      <t>This document defines a date and time format for use in Internet protocols that is a profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="3339"/>
  <seriesInfo name="DOI" value="10.17487/RFC3339"/>
</reference>
<reference anchor="RFC3986">
  <front>
    <title>Uniform Resource Identifier (URI): Generic Syntax</title>
    <author fullname="T. Berners-Lee" initials="T." surname="Berners-Lee"/>
    <author fullname="R. Fielding" initials="R." surname="Fielding"/>
    <author fullname="L. Masinter" initials="L." surname="Masinter"/>
    <date month="January" year="2005"/>
    <abstract>
      <t>A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource. This specification defines the generic URI syntax and a process for resolving URI references that might be in relative form, along with guidelines and security considerations for the use of URIs on the Internet. The URI syntax defines a grammar that is a superset of all valid URIs, allowing an implementation to parse the common components of a URI reference without knowing the scheme-specific requirements of every possible identifier. This specification does not define a generative grammar for URIs; that task is performed by the individual specifications of each URI scheme. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="66"/>
  <seriesInfo name="RFC" value="3986"/>
  <seriesInfo name="DOI" value="10.17487/RFC3986"/>
</reference>
<reference anchor="RFC8259">
  <front>
    <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
    <author fullname="T. Bray" initials="T." role="editor" surname="Bray"/>
    <date month="December" year="2017"/>
    <abstract>
      <t>JavaScript Object Notation (JSON) is a lightweight, text-based, language-independent data interchange format. It was derived from the ECMAScript Programming Language Standard. JSON defines a small set of formatting rules for the portable representation of structured data.</t>
      <t>This document removes inconsistencies with other specifications of JSON, repairs specification errors, and offers experience-based interoperability guidance.</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="90"/>
  <seriesInfo name="RFC" value="8259"/>
  <seriesInfo name="DOI" value="10.17487/RFC8259"/>
</reference>
<reference anchor="RFC9110">
  <front>
    <title>HTTP Semantics</title>
    <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
    <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
    <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
    <date month="June" year="2022"/>
    <abstract>
      <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document describes the overall architecture of HTTP, establishes common terminology, and defines aspects of the protocol that are shared by all versions. In this definition are core protocol elements, extensibility mechanisms, and the "http" and "https" Uniform Resource Identifier (URI) schemes.</t>
      <t>This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="97"/>
  <seriesInfo name="RFC" value="9110"/>
  <seriesInfo name="DOI" value="10.17487/RFC9110"/>
</reference>
<reference anchor="RFC9580">
  <front>
    <title>OpenPGP</title>
    <author fullname="P. Wouters" initials="P." role="editor" surname="Wouters"/>
    <author fullname="D. Huigens" initials="D." surname="Huigens"/>
    <author fullname="J. Winter" initials="J." surname="Winter"/>
    <author fullname="Y. Niibe" initials="Y." surname="Niibe"/>
    <date month="July" year="2024"/>
    <abstract>
      <t>This document specifies the message formats used in OpenPGP. OpenPGP provides encryption with public key or symmetric cryptographic algorithms, digital signatures, compression, and key management.</t>
      <t>This document is maintained in order to publish all necessary information needed to develop interoperable applications based on the OpenPGP format. It is not a step-by-step cookbook for writing an application. It describes only the format and methods needed to read, check, generate, and write conforming packets crossing any network. It does not deal with storage and implementation questions. It does, however, discuss implementation issues necessary to avoid security flaws.</t>
      <t>This document obsoletes RFCs 4880 ("OpenPGP Message Format"), 5581 ("The Camellia Cipher in OpenPGP"), and 6637 ("Elliptic Curve Cryptography (ECC) in OpenPGP").</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9580"/>
  <seriesInfo name="DOI" value="10.17487/RFC9580"/>
</reference>

<reference anchor="CORS" target="https://fetch.spec.whatwg.org/#cors-protocol">
  <front>
    <title>Cross Origin Resource Sharing</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="UNF" target="https://www.unicode.org/reports/tr15/">
  <front>
    <title>Unicode Normalization Forms</title>
    <author fullname="Ken Whistler">
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>



<reference anchor="I-D.gallagher-openpgp-media-types">
   <front>
      <title>Media Types for OpenPGP</title>
      <author fullname="Andrew Gallagher" initials="A." surname="Gallagher">
         <organization>PGPKeys.EU</organization>
      </author>
      <date day="8" month="August" year="2025"/>
      <abstract>
	 <t>   This document updates the specification of existing media types, and
   specifies additional media types, for the identification of OpenPGP
   data in non-MIME contexts.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-gallagher-openpgp-media-types-00"/>
   
</reference>

<reference anchor="I-D.ietf-sml-structured-email">
   <front>
      <title>Structured Email</title>
      <author fullname="Hans-Jörg Happel" initials="H." surname="Happel">
         <organization>audriga GmbH</organization>
      </author>
      <date day="21" month="October" year="2025"/>
      <abstract>
	 <t>   This document specifies how a machine-readable version of the content
   of email messages can be added to those messages.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-ietf-sml-structured-email-05"/>
   
</reference>
<reference anchor="RFC2119">
  <front>
    <title>Key words for use in RFCs to Indicate Requirement Levels</title>
    <author fullname="S. Bradner" initials="S." surname="Bradner"/>
    <date month="March" year="1997"/>
    <abstract>
      <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="2119"/>
  <seriesInfo name="DOI" value="10.17487/RFC2119"/>
</reference>
<reference anchor="RFC8174">
  <front>
    <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
    <author fullname="B. Leiba" initials="B." surname="Leiba"/>
    <date month="May" year="2017"/>
    <abstract>
      <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="8174"/>
  <seriesInfo name="DOI" value="10.17487/RFC8174"/>
</reference>



    </references>

    <references title='Informative References' anchor="sec-informative-references">



<reference anchor="RFC3492">
  <front>
    <title>Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)</title>
    <author fullname="A. Costello" initials="A." surname="Costello"/>
    <date month="March" year="2003"/>
    <abstract>
      <t>Punycode is a simple and efficient transfer encoding syntax designed for use with Internationalized Domain Names in Applications (IDNA). It uniquely and reversibly transforms a Unicode string into an ASCII string. ASCII characters in the Unicode string are represented literally, and non-ASCII characters are represented by ASCII characters that are allowed in host name labels (letters, digits, and hyphens). This document defines a general algorithm called Bootstring that allows a string of basic code points to uniquely represent any string of code points drawn from a larger set. Punycode is an instance of Bootstring that uses particular parameter values specified by this document, appropriate for IDNA. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="3492"/>
  <seriesInfo name="DOI" value="10.17487/RFC3492"/>
</reference>
<reference anchor="RFC6335">
  <front>
    <title>Internet Assigned Numbers Authority (IANA) Procedures for the Management of the Service Name and Transport Protocol Port Number Registry</title>
    <author fullname="M. Cotton" initials="M." surname="Cotton"/>
    <author fullname="L. Eggert" initials="L." surname="Eggert"/>
    <author fullname="J. Touch" initials="J." surname="Touch"/>
    <author fullname="M. Westerlund" initials="M." surname="Westerlund"/>
    <author fullname="S. Cheshire" initials="S." surname="Cheshire"/>
    <date month="August" year="2011"/>
    <abstract>
      <t>This document defines the procedures that the Internet Assigned Numbers Authority (IANA) uses when handling assignment and other requests related to the Service Name and Transport Protocol Port Number registry. It also discusses the rationale and principles behind these procedures and how they facilitate the long-term sustainability of the registry.</t>
      <t>This document updates IANA's procedures by obsoleting the previous UDP and TCP port assignment procedures defined in Sections 8 and 9.1 of the IANA Allocation Guidelines, and it updates the IANA service name and port assignment procedures for UDP-Lite, the Datagram Congestion Control Protocol (DCCP), and the Stream Control Transmission Protocol (SCTP). It also updates the DNS SRV specification to clarify what a service name is and how it is registered. This memo documents an Internet Best Current Practice.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="165"/>
  <seriesInfo name="RFC" value="6335"/>
  <seriesInfo name="DOI" value="10.17487/RFC6335"/>
</reference>
<reference anchor="RFC7595">
  <front>
    <title>Guidelines and Registration Procedures for URI Schemes</title>
    <author fullname="D. Thaler" initials="D." role="editor" surname="Thaler"/>
    <author fullname="T. Hansen" initials="T." surname="Hansen"/>
    <author fullname="T. Hardie" initials="T." surname="Hardie"/>
    <date month="June" year="2015"/>
    <abstract>
      <t>This document updates the guidelines and recommendations, as well as the IANA registration processes, for the definition of Uniform Resource Identifier (URI) schemes. It obsoletes RFC 4395.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="35"/>
  <seriesInfo name="RFC" value="7595"/>
  <seriesInfo name="DOI" value="10.17487/RFC7595"/>
</reference>

<reference anchor="SKS" target="https://github.com/sks-keyserver/sks-keyserver/wiki">
  <front>
    <title>Synchronising Key Server Wiki</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="TOR" target="https://spec.torproject.org/">
  <front>
    <title>Tor Specifications</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>



<reference anchor="I-D.dkg-openpgp-1pa3pc">
   <front>
      <title>First-Party Approved Third-Party Certifications in OpenPGP</title>
      <author fullname="Daniel Kahn Gillmor" initials="D. K." surname="Gillmor">
         <organization>ACLU</organization>
      </author>
      <date day="6" month="September" year="2024"/>
      <abstract>
	 <t>   An OpenPGP certificate can grow in size without bound when third-
   party certifications are included.  This document describes a way for
   the owner of the certificate to explicitly approve of specific third-
   party certifications, so that relying parties can safely prune the
   certificate of any unapproved certifications.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-dkg-openpgp-1pa3pc-02"/>
   
</reference>

<reference anchor="I-D.dkg-openpgp-userid-conventions">
   <front>
      <title>OpenPGP User ID Conventions</title>
      <author fullname="Daniel Kahn Gillmor" initials="D. K." surname="Gillmor">
         <organization>ACLU</organization>
      </author>
      <date day="25" month="August" year="2023"/>
      <abstract>
	 <t>   OpenPGP User IDs are UTF-8 strings.  Existing documents claim that by
   conventione, they contain &quot;an RFC 2822 name-addr object&quot;, but that&#x27;s
   not the case.  This document attempts to better describe the actual
   conventions about User IDs in the deployed OpenPGP ecosystem.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-dkg-openpgp-userid-conventions-00"/>
   
</reference>



    </references>

</references>


<?line 1128?>

<section anchor="acknowledgments"><name>Acknowledgments</name>

<t>This document is a formalization and extension of HKP, originally implemented in the PKS keyserver by Marc Horowitz, which in turn was based on earlier work by Brian LaMacchia and Michael Graff.
The "prefixlog" request category is based on an earlier proposal by Daniel Kahn Gillmor and Vincent Breitmoser.</t>

<t>The authors would like to thank Peter Gutmann for his work on the Certstore protocol, some of which was applicable here, and the members of the pgp-keyserver-folk mailing list who contributed valuable comments and suggestions.
They would also like to thank Bart Butler, Daniel Kahn Gillmor, Heiko Schäfer, Justus Winter and Vincent Breitmoser for help with the v2 request format.</t>

</section>
<section anchor="document-history"><name>Document History</name>

<t>Note to RFC Editor: this section should be removed before publication.</t>

<section anchor="changes-between-draft-gallagher-openpgp-hkp-09-and-draft-gallagher-openpgp-hkp-10"><name>Changes Between draft-gallagher-openpgp-hkp-09 and draft-gallagher-openpgp-hkp-10</name>

<t><list style="symbols">
  <t>Added JSON-LD example.</t>
  <t>Fixed some obsolete references.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-08-and-draft-gallagher-openpgp-hkp-09"><name>Changes Between draft-gallagher-openpgp-hkp-08 and draft-gallagher-openpgp-hkp-09</name>

<t><list style="symbols">
  <t>Refactored to separate v2 and Legacy sections.</t>
  <t>v2 API is now RESTful.</t>
  <t>v2 uses "category" and "identifier" instead of "op" and "search".</t>
  <t>v2 keywords are less terse.</t>
  <t>Defined "canonical bundle".</t>
  <t>Defined "identity".</t>
  <t>Resurrected SRV-based discovery.</t>
  <t>Added basic vs advanced submission.</t>
  <t>Added structured email.</t>
  <t>Specified bearer token authentication.</t>
  <t>Specified use of OPTIONS and HEAD.</t>
  <t>Specified the Last-Modified response header.</t>
  <t>Clarify subkey lookups.</t>
  <t>Sideline inexact matching.</t>
  <t>Discourage badly-behaved User IDs.</t>
  <t>Removed some misused HTTP return codes.</t>
  <t>Added tabular summaries.</t>
  <t>Added Daniel Huigens as co-author.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-07-and-draft-gallagher-openpgp-hkp-08"><name>Changes Between draft-gallagher-openpgp-hkp-07 and draft-gallagher-openpgp-hkp-08</name>

<t><list style="symbols">
  <t>Verified uploads now use prove-then-submit workflow.</t>
  <t>Removed SRV and discovery discussion (temporarily?).</t>
  <t>Added definitions of "discovery", "refresh" and "reference resolution".</t>
  <t>Normalised "certificate" terminology and warned about unqualified use of "keyring".</t>
  <t>Renumbered HKPv1 to HKPv2 for avoidance of confusion, and reordered path components.</t>
  <t>HKPv2 is now explicitly a binary protocol, and uses simplified paths.</t>
  <t>Defined v2 submission requests and "cb" option.</t>
  <t>Explicitly forbade mixed certificate bundle responses to v2 lookups.</t>
  <t>"since" is now "prefixlog".</t>
  <t>"get" operation is now <bcp14>MAY</bcp14>.</t>
  <t>"x-*" parameters are no longer specified (as per RFC6648).</t>
  <t>Fixed several errata.</t>
  <t>Expanded commentary and guidance.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-06-and-draft-gallagher-openpgp-hkp-07"><name>Changes Between draft-gallagher-openpgp-hkp-06 and draft-gallagher-openpgp-hkp-07</name>

<t><list style="symbols">
  <t>Added "authget" and "since" operations.</t>
  <t>Defined confidence.</t>
  <t>Added more explicit guidance re sorting, filtering and error codes.</t>
  <t>Key version MR output field is now "keyversion" to distinguish from the output format version.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-05-and-draft-gallagher-openpgp-hkp-06"><name>Changes Between draft-gallagher-openpgp-hkp-05 and draft-gallagher-openpgp-hkp-06</name>

<t><list style="symbols">
  <t>Updated references.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-04-and-draft-gallagher-openpgp-hkp-05"><name>Changes Between draft-gallagher-openpgp-hkp-04 and draft-gallagher-openpgp-hkp-05</name>

<t><list style="symbols">
  <t>Allow detached revocations in keyrings.</t>
  <t>Redesigned v2 request format to use path components for required fields.</t>
  <t>Added openpgpkey discovery file.</t>
  <t>Added "vfpget" and "kidget" operations.</t>
  <t>Added meaningful "exact" semantics.</t>
  <t>HKPS is now <bcp14>SHOULD</bcp14>.</t>
  <t>Defined port 11372.</t>
  <t>IANA registry tables.</t>
  <t>Deprecated <spanx style="verb">op=stats</spanx>.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-03-and-draft-gallagher-openpgp-hkp-04"><name>Changes Between draft-gallagher-openpgp-hkp-03 and draft-gallagher-openpgp-hkp-04</name>

<t><list style="symbols">
  <t>Reworded certificate lookups section for clarity.</t>
  <t>Separate section for keyring format.</t>
  <t>Specify detached revocations.</t>
  <t>Updated references.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-02-and-draft-gallagher-openpgp-hkp-03"><name>Changes Between draft-gallagher-openpgp-hkp-02 and draft-gallagher-openpgp-hkp-03</name>

<t><list style="symbols">
  <t>Clients <bcp14>SHOULD</bcp14> supply the <spanx style="verb">v=1</spanx> api-versioning variable.</t>
  <t>machine-readable output includes key version field.</t>
  <t>Clients <bcp14>MUST</bcp14> silently ignore leading and trailing cruft, trailing unknown fields, and unknown flags.</t>
  <t>Clients <bcp14>MUST</bcp14> silently ignore keys with unknown versions or algorithms.</t>
  <t>All other m-r index specs (CORS, Content-Type etc.) are now <bcp14>MUST</bcp14>.</t>
  <t>Included the <spanx style="verb">hash</spanx> variable from SKS.</t>
</list></t>

</section>
<section anchor="changes-between-draft-gallagher-openpgp-hkp-01-and-draft-gallagher-openpgp-hkp-02"><name>Changes Between draft-gallagher-openpgp-hkp-01 and draft-gallagher-openpgp-hkp-02</name>

<t><list style="symbols">
  <t>Tightened up BCP-14 language.</t>
  <t>Included <spanx style="verb">op=hget</spanx> from SKS.</t>
  <t>Options now strictly boolean with default false, variables less strict.</t>
  <t>More detail about HTTP status code usage.</t>
</list></t>

</section>
<section anchor="changes-between-draft-shaw-openpgp-hkp-00-and-draft-gallagher-openpgp-hkp-01"><name>Changes Between draft-shaw-openpgp-hkp-00 and draft-gallagher-openpgp-hkp-01</name>

<t><list style="symbols">
  <t>Improved text structure.</t>
  <t>Added references to HTTPS/HKPS, and hkp:/hkps: URL schemes.</t>
  <t>Forbade short IDs and deprecated V3 keys.</t>
  <t>Included <spanx style="verb">op=stats</spanx> from SKS.</t>
  <t>Mentioned CORS.</t>
  <t>Made use of terminology more consistent.</t>
  <t>Replaced custom status codes with standard HTTP status codes.</t>
</list></t>

</section>
</section>


  </back>

<!-- ##markdown-source:
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

-->

</rfc>

