Hockeypuck OpenPGP Public Keyserver

1. Configuration

Hockeypuck reads configuration from a TOML-format configuration file.

1.1. Hosting


These settings are displayed on the stats page (/pks/lookup?op=stats). The contact field should contain the long key ID or full fingerprint of the keyserver administrator. The hostname field should be set to the external hostname of the server (which may differ from the keyserver host, if reverse-proxied). hostname may be used to identify the server in synchronizing pool.

1.2. Logging


If not configured, hockeypuck will log INFO level messages and higher severity to standard error.

1.3. Static HTML files

Hockeypuck will serve static files from / out of the webroot path, so long as the path names do not conflict with HKP routed requests (like /pks/lookup).


index.html will be served by default if the path resolves to a directory and the file exists.

1.4. Custom HTML templates

By default, Hockeypuck will respond to HKP operations op=index, op=vindex and op=stats with an application/json response. The underlying structs for these responses can be used in HTML templates of your own design to customize the output.

Specify these templates with:


The path must be to a file containing a valid Go html/template.

indexTemplate and vindexTemplate operate on a struct containing two top-level fields,

statsTemplate operates on an instance of server.stats.

See the packaged templates for an example.

1.5. Storage

1.5.1. MongoDB

If storage is not otherwise configured, Hockeypuck defaults to connecting to a MongoDB server at localhost:27017. This is effectively:


The dsn field is just the host:port of the MongoDB server.

With MongoDB, Hockeypuck uses database name hkp and collection name keys by default. This can be changed with the options:


1.5.2. PostgreSQL

PostgreSQL >= 9.4 is required for use with Hockeypuck, as the JSONB data type is used to store most of the public key material. Some fields are broken out into separate columns for indexing. For details, refer to the PostgreSQL storage backend, pghkp.v1.

To use PostgreSQL:

dsn="database=hkp host=/var/run/postgresql port=5432 sslmode=disable"

See the pq driver package documentation for details on how to construct the connection string.

1.6. Peering

Hockeypuck supports the SKS reconciliation (recon) protocol.

1.6.1. Local peer options


The above are default settings if not otherwise specified.

httpAddr determines the address that will be advertised to remote peers for retrieving key material with /pks/hashquery requests.

reconAddr determines the listen address for the recon server. This is conventionally :11370 among SKS keyservers.

1.6.2. Adding remote peers



Create a section for each peer [hockeypuck.conflux.recon.partner.peername], where peername is a unique logical name given to each peer (it doesn't have to relate to the hostnames or anything).

Each peer must declare a httpAddr and reconAddr. These are usually the same host, but they might differ, especially if the HKP service is reverse-proxied. Protocol and network options

version="1.1.3"                # this is default
allowCIDRs=[""]      # default is []
filters=["yminsky.dedup"]      # default is []

version is the protocol compatibility version (SKS release version) advertised to remote peers. Hockeypuck does not use this field.

allowCIDRS is used to allow incoming recon connections from remote addresses other than the defined peers. This is especially useful when inbound connections to Hockeypuck are subject to NAT (some cloud providers do this). If not specified, inbound connections are only allowed from partner IP addresses.

filters are labels that indicate the type of processing that has been applied to key material. Recent versions of SKS typically require filters=["yminsky.dedup"], which indicates that duplicate PGP packets have been dropped from key material. Hockeypuck deduplicates key material regardless; this field is only used for protocol compatibility with SKS. Prefix tree location


The prefix tree is used to keep track of which keys the peer has, for synchronization purposes.

The path given should be a writeable directory that already exists.