Step 1
Export your public key as binary
WKD serves OpenPGP binary, not ASCII armored. From PGPony, get the public key out via the
Exchange tab → Show My Key → Share
(gives you the ASCII-armored block; convert to binary on the desktop). Or use a desktop gpg
copy if you already have one:
If PGPony only outputs ASCII armored, convert on the desktop:
gpg --import your-public-key.asc
gpg --export YOUR_FINGERPRINT > pubkey.gpg
The resulting pubkey.gpg is what goes on the web server.
Step 2
Compute the WKD hash
Run on desktop gpg:
gpg --with-wkd-hash --list-keys you@yourdomain.com
Look for the line below your User ID:
uid [ultimate] You <you@yourdomain.com>
7we1qpoqxxh1ie3wxxxxxxxxxxxxxxxx@yourdomain.com
The hash on the left of @ is the localpart-hash you need. Z-base-32 encoded SHA-1
of the lowercased localpart. This is your filename on the server.
Step 3
Decide on Direct or Advanced method
Direct method: WKD lives on your main domain.
URL pattern: https://yourdomain.com/.well-known/openpgpkey/hu/HASH
Advanced method: WKD lives on a dedicated subdomain.
URL pattern: https://openpgpkey.yourdomain.com/.well-known/openpgpkey/yourdomain.com/hu/HASH
Clients try Advanced first, fall back to Direct. Setting up both is most robust; Direct alone
is simpler and usually sufficient.
Step 4
Create the directory structure
On your web server (using Direct method, document root /var/www/yourdomain.com):
mkdir -p /var/www/yourdomain.com/.well-known/openpgpkey/hu
cd /var/www/yourdomain.com/.well-known/openpgpkey
Step 5
Place the public key binary
Copy your pubkey.gpg into the hu/ directory, renaming it to the
hash from Step 2 (no file extension):
cp pubkey.gpg /var/www/yourdomain.com/.well-known/openpgpkey/hu/7we1qpoqxxh1ie3wxxxxxxxxxxxxxxxx
Step 6
Add the policy file
Create an empty policy file at .well-known/openpgpkey/policy. Its existence
signals WKD support; its content is not used (in practice):
touch /var/www/yourdomain.com/.well-known/openpgpkey/policy
Step 7
Configure web server headers
The WKD endpoint should serve with Content-Type: application/octet-stream and
permissive CORS (so JavaScript-based clients can fetch). Nginx example:
location /.well-known/openpgpkey/ {
default_type application/octet-stream;
add_header Access-Control-Allow-Origin "*";
add_header Cache-Control "public, max-age=3600";
}
Reload Nginx: sudo nginx -s reload.
Step 8
Test from a desktop
Confirm WKD returns your key:
gpg --auto-key-locate=clear,wkd --locate-keys you@yourdomain.com
Successful WKD discovery prints your key. Failure prints a "no public key" error or fetch
failure. Recheck the hash, file path, and Content-Type header.