GPG Sync v0.3 Adds Support for the Keylist RFC

PGP has a reputation for being complicated. After five years of using it within First Look Media – yup, everyone at this company has been using PGP encrypted email for years, including the reporters at The Intercept – it’s clear that the complicated part isn’t encrypting, decrypting, signing, or verifying. These days, PGP email clients make that simple, even for cryptographic newbies. Rather, it’s key management: making sure everyone has the correct public key for everyone else.

This is why we developed GPG Sync, a tool for securely subscribing to centrally managed lists of PGP keys known as keylists. When a new employee starts at FLM, they get a laptop, an email address, and a PGP key, and GPG Sync automatically ensures that their PGP keyring always has the correct public keys – over 230 of them, at this point – of everyone else who works at the company. If they want to send someone an encrypted email, even someone they haven’t met yet, they simply write them an email, making sure the encryption icon is selected. That’s it.

GPG Sync has served us well over the years – we wouldn’t have been able to scale our use of PGP without it – but it also has some limitations: It uses GnuPG, which is far from the only implementation of OpenPGP. So you can’t use GPG Sync to subscribe to keylists if you use non-GPG encrypted email software like ProtonMail, Mailvelope, Canary Mail, or OpenKeychain. And GPG doesn’t exist on mobile, so GPG Sync can’t either.

For this reason, we started the Keylist RFC project, with the goal of turning the keylists used by GPG Sync into an Internet standard so that other software in the PGP ecosystem can allow their users to subscribe to keylists too. If you’re interested in the details, check out the draft standard: Distributing OpenPGP Keys with Signed Keylist Subscriptions.

GPG Sync 0.3

Today, we’re releasing GPG Sync 0.3 which officially supports the draft Keylist RFC. You can download it here. Here’s what has changed:

First, when we initially developed GPG Sync, the keylist format was just a simple text file with one fingerprint per line, and comments which start with the # character. In order to make it easier for machines to parse this data, and to be able to include more robust metadata and comments within the keylist, such as a suggested keyserver to use, we switched to a JSON-based format.

This is what an old legacy keylist looked like:

# this is a sample keylist
927F419D7EC82C2F149C1BD1403C2657CD994F73 # Micah Lee <micah.lee@theintercept.com>
91C0C982A41F8D3939531A71FAB737F9C5C1CA80 # Warrant Canary signing key

Here’s that same keylist, but using the format specified in the Keylist RFC, along with some extra machine-readable metadata (note that in the list of keys, only the fingerprint field is required for each key, the other fields are optional):

{
  "metadata": {
    "signature_uri": "https://example.com/keylist.json.asc",
    "comment": "This is an sample keylist"
  },
  "keys": [
    {
      "fingerprint": "927F419D7EC82C2F149C1BD1403C2657CD994F73",
      "name": "Micah Lee",
      "email": "micah.lee@theintercept.com"
    },
    {
      "fingerprint": "91C0C982A41F8D3939531A71FAB737F9C5C1CA80",
      "name": "Warrant Canary Signing Key",
      "comment": "More info on the FLM warrant canary: https://firstlook.media/canary"
    }
  ]
}

Second, when you configure GPG Sync, you now only need to supply two pieces of information:

1. A URL where the keylist is hosted, and 2. The fingerprint of the “authority key” that’s used to PGP-sign the keylist

When GPG Sync refreshes a keylist, it fetches the authority key from a keyserver, downloads the keylist and the keylist’s signature, and then uses the authority key to confirm that keylist’s signature is valid – if it doesn’t verify, it doesn’t refresh.

In previous versions of GPG Sync, wherever you hosted the keylist, you had to also host the signature file with the same filename but with .sig at the end (so, if your keylist was at https://example.com/fingerprints.txt, your signature had to be at https://example.com/fingerprints.txt.sig).

With the new Keylist RFC format, instead you specify the location of the signature file signature_uri metadata field. This allows for more robust hosting options for your keylist – for example, in private GitHub gists.

And third, while GPG Sync 0.3 supports the new Keylist RFC, it’s also backwards compatible and still works with legacy keylist files. If your organization already uses GPG Sync, your users can safely upgrade to 0.3 and keep syncing existing legacy keylist.

If you want to redirect them to a new keylist, just add a comment to the top of your legacy keylist file like this, and change the URL to point to your new JSON-formatted keylist (make sure to update the signature after making this change as well):

# new_keylist_uri = https://example.com/keylist.json

The next time your users who have upgraded to 0.3 refresh the legacy keylist, after GPG Sync confirms that the signature verifies, it will automatically update its keylist URL and will start fetching the new keylist in the future.

For more information on using GPG Sync, check out the wiki on GitHub.