Publish and Test OpenPGP Keys with gpg-wks-client

gpg-wks-client drives Web Key Directory publishing, so people can fetch your OpenPGP key from your email address alone. No keyserver hunting required. You will finish with a repeatable way to test WKD and Web Key Service (WKS) support, calculate the lookup location for an address, and either create a publication request or build a local WKD directory. These examples use the installed GnuPG 2.4.4 gpg-wks-client.

Allow about fifteen minutes. You need GnuPG, a public key with the address you intend to publish, and a WKS provider already configured for your domain. The first checks are ordinary, unprivileged commands. A production directory may need elevated privileges because of its ownership, but do not use sudo unless the destination actually requires it.

1. Confirm the installed command

Check the version and the command names before using an example. This changes nothing: no keys, no mail, no server configuration:

$ gpg-wks-client --version
gpg-wks-client (GnuPG) 2.4.4
$ gpg-wks-client --help

The important commands are --supported, --check, --create, --read, --receive, --install-key and --remove-key. The separate --print-wkd-hash and --print-wkd-url commands are useful for checking the address mapping without publishing anything.

Checkpoint: Make sure the output identifies GnuPG 2.4.4, or adjust your expectations if your package is a different version. Option details can change between releases.

2. Test whether the domain offers WKS

Pass an address in the domain to --supported. The address only identifies the domain; it does not need to be the mailbox you will eventually publish:

$ gpg-wks-client --verbose --supported [email protected]
gpg-wks-client: provider for '[email protected]' does NOT support the Web Key Directory
$ printf 'exit status: %s\n' "$?"
exit status: 1

A supported provider returns status 0. An unsupported one returns a non-zero status and, with --verbose, a diagnostic like the one above. Normal operation is silent, so a script should test the exit status rather than search for text.

For machine-readable probing, pass domain names with --with-colons. This changes the input rule: command-line arguments become domains, not email addresses:

$ gpg-wks-client --supported --with-colons example.net
example.net:0:0::

The fields describe WKD support, WKS support, an error code, protocol version and policy flags. The exact values depend on the domain and release. Treat an unsuccessful probe as a provider or DNS/HTTPS issue to investigate, never as permission to publish directly anyway.

3. Check a key and calculate its WKD location

Use --check to ask whether a key is available for a mailbox:

$ gpg-wks-client --check [email protected]
$ printf 'exit status: %s\n' "$?"
exit status: 0

Status 0 means a key was found. A non-zero status means it was not found, or the lookup failed. If you need the actual public key file for inspection, use a separate GnuPG export command; --check is only a test.

To see the identifier WKD uses, supply the user ID to --print-wkd-hash:

$ gpg-wks-client --print-wkd-hash 'Alice Example <[email protected]>'
kei1q4tipxxu1yj79k9kfukdhfy631xe [email protected]

The value is derived from the mailbox, including its normalised form, so do not copy a hash from another address. To print the complete fetch URL instead:

$ gpg-wks-client --print-wkd-url [email protected]
https://openpgpkey.example.net/.well-known/openpgpkey/example.net/hu/kei1q4tipxxu1yj79k9kfukdhfy631xe?l=alice

Both commands are read-only. Neither proves the returned URL actually contains the key, so use --check for the client-side availability test.

4. Create a publication request without sending it

Find the full fingerprint of the key whose user ID contains the mailbox, then create a mail request and save it for review:

$ fingerprint='0123456789ABCDEF0123456789ABCDEF01234567'
$ gpg-wks-client --output wks-request.eml --create "$fingerprint" [email protected]
$ sed -n '1,12p' wks-request.eml
From: ...
To: ...
Subject: ...

The fingerprint and address are positional arguments. The command writes a properly formatted mail to the file, but it does not deliver it. Review the recipient, address and key before touching any delivery mechanism. The provider may reject a domain that never passed the support test, and the request can fail if the fingerprint or user ID is wrong.

Warning: --send hands the generated mail to the installed sendmail command. It sends a real message and may be irreversible once the mail system accepts it. Use it only after reviewing the saved request, and only once you have confirmed the local mail route. To undo a mistaken request, contact the WKS provider or administrator; there is no universal client-side recall.

5. Maintain a local WKD directory

For testing, or a service that serves files from a local directory, install a key into a directory you control. This example keeps all state under a temporary path:

$ wkd_dir='/tmp/example-wkd'
$ mkdir -p "$wkd_dir"
$ gpg-wks-client --directory "$wkd_dir" --install-key "$fingerprint" [email protected]
gpg-wks-client: key 0123456789ABCDEF0123456789ABCDEF01234567 published for '[email protected]'

The default top-level directory is openpgpkey; use --directory or -C when the web server uses a different root. The installed layout contains a domain directory, a hu file named with the WKD hash, and a policy file. Inspect it before exposing the directory through a web server:

$ find "$wkd_dir" -type f -print
/tmp/example-wkd/example.net/hu/kei1q4tipxxu1yj79k9kfukdhfy631xe
/tmp/example-wkd/example.net/policy

Destructive action: --remove-key removes the selected address from that local directory. Check the exact mailbox first and keep a backup if the directory is authoritative:

$ gpg-wks-client --directory "$wkd_dir" --remove-key [email protected]
$ test ! -e "$wkd_dir/example.net/hu/kei1q4tipxxu1yj79k9kfukdhfy631xe" && echo 'key removed'
key removed

This does not revoke the OpenPGP key, delete it from any keyring, or withdraw a message already sent. Restore the removed file from your backup, or run --install-key again with the same key and address.

6. Process a provider confirmation

After a provider sends a confirmation mail, use --receive for an encrypted MIME message. Use --read when the MIME message is already decrypted. Both commands read the message from standard input and produce another mail that must itself be delivered:

$ gpg-wks-client --receive < confirmation.eml > response.eml
$ test -s response.eml && echo 'response created'
response created

Keep the response file until you have checked its headers and destination. Do not swap --receive and --read casually: the former expects encrypted input, the latter expects already decrypted input. Feed neither command arbitrary mail until you understand which key and mailbox the response addresses.

Done means