<?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-ietf-openpgp-hkp-00" 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="May" day="21"/>

    <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/openpgp-hkp"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ietf-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/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-10-and-draft-ietf-openpgp-hkp-00"><name>Changes Between draft-gallagher-openpgp-hkp-10 and draft-ietf-openpgp-hkp-00</name>

<t>None</t>

</section>
<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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
i/u/p+yj6q8JAQA=

-->

</rfc>

