smol projects

keyoxide: claims and proofs for your virtual id

17.08.2023 3 min read

This ramble is going to be a bit of a mess and perhaps plain incorrect because I’m still trying to wrap my head around all this.


Provides a way to claim and prove various profiles associated with your online identity, e.g. Github, Reddit, etc.

Getting started

  • Create your Keyoxide profile
  • You probably want to use GPG if you’re using the CLI, and Kleopatra for GUI.
  • Follow “Step 1” & “Step 2”. For platform-specific implementation, refer to “Available claims/proofs” in the sidebar of the docs


Key value pairs. Example:

[email protected]=dns:DOMAIN?type=TXT # DNS
[email protected]=https://gist.github.com/USERNAME/GIST_ID # Github

Found on this page.

Will look different depending on the platform.

After you’ve generated your pubkey.asc and uploaded it to https://keys.openpgp.org/upload, you probably want to add notations.

After adding a new notation, reupload the key.

gpg --keyserver hkps://keys.openpgp.org --send-keys FINGERPRINT

AFAIK, this is what Keyoxide uses to see what claims you are trying to make and whether proofs have been verified (I mean, my profile page changes after I add a notation and reupload the key, so…).

Removing a notation

gpg --edit-key your-fingerprint
showpref # list all your notations
uid 1 # choose the UID you want to remove the notation from
notation [email protected]=dns:DOMAIN?type=TXT

Add notation to multiple UIDs

uid 1 # select UID 1
uid 2 # select UID 2
notation=[email protected]=dns:DOMAIN?type=TXT

Adding an email (associate another email to existing fingerprint)

Disclaimer: I’m really not sure about this section, but here goes…

gpg --edit-key your-fingerprint
adduid [email protected]
# complete the interative steps

The important thing is, (it seems that) we can’t simply re-run gpg --keyserver to update the key. We’ll need to manually upload it to https://keys.openpgp.org. Following this, Keyoxide should learn of the new email.

Again - I’m not 100% sure if it was the manual upload that triggered the changes. It could be that updates required some time to propagate - but these were the steps that worked for me.

WKD (Web Key Directory)

TLDR: host your own keys on your own server/domain

gpg --with-wkd-hash -k [email protected]
# some other stuff
	[email protected] # everything before "@example.org" is the <HASH>
gpg --export [email protected] > hacabazoakmnagxwmkjerb9yehuwehbm
rsync ./hacabazoakmnagxwmkjerb9yehuwehbm /public/.well-known/openpgpkey/hu/

Instructions for WKD

  • Put the required files in your site
    • https://example.org/.well-known/openpgpkey/policy
    • https://example.org/.well-known/openpgpkey/hu/<HASH>

Check whether it’s working here

Utility for hashing

More instructions to set up openpgp WKD

WKD as a Service

Use this if you have control over DNS but no hosting (?)

  • Delegate the openpgpkey subdomain to wkd.keys.openpgp.org (CNAME record)
  • Then you can retrieve the keys like so: gpg --locate-keys --auto-key-locate clear,nodefault,wkd [email protected]

Astro-specific implementation for WKD

You’ll want to put it in the /public folder, not in /pages.


  1. Getting started
  2. Create your Keyoxide profile
  3. Keyoxide Documentation
  4. Notation
  5. pubkey.asc
  6. Add notations
  7. Instructions for WKD
  8. Check if WKD implementation worked
  9. Utility for hashing
  10. More instructions to set up openpgp WKD
  11. WKD as a Service
  12. Astro-specific implementation for WKD
  13. AstroJS WKD issue with node adapter
  14. Extra: Associate an avatar to your Keyoxide account
Built with Astro and Tailwind 🚀