Switching from GPG to age

It’s been several years since I went through all the trouble of setting up my own GPG keys and securing them in YubiKeys following drduh’s guide. With that approach, you generate one key securely offline and store it on multiple YubiKeys, along with a backup.

It has worked well for me for years, and as the Lindy effect suggests, it would almost certainly continue to.

But as my sub-keys were nearing expiration, I was faced with either renewing (more convenient, no forward secrecy) or rotating them (rather painful, but potentially more secure). However, I’ve realized that I essentially only use these keys for encryption, and almost never for signing. So, instead of doing either of the usual options, I’m going to let my keys expire entirely.

I’m now experimenting with age, which touts itself as “simple, modern, and secure encryption”. If needed, I will use minisign for signatures.

Workflow changes

This required changing a couple of things in my typical workflow.

Password manager

First, and foremost, I needed to switch from pass to passage, a fork of pass that uses age as the backend. This was actually surprisingly easy because passage includes a simple bash script to do the migration.

#! /usr/bin/env bash
set -eou pipefail
cd "${PASSWORD_STORE_DIR:-$HOME/.password-store}"
while read -r -d "" passfile; do
  name="${passfile#./}"; name="${name%.gpg}"
  [[ -f "${PASSAGE_DIR:-$HOME/.passage/store}/$name.age" ]] && continue
  pass "$name" | passage insert -m "$name" || { passage rm "$name"; break; }
done < <(find . -path '*/.git' -prune -o -iname '*.gpg' -print0)

There is no installer for passage, and no Arch packages. But it’s easy enough to install because it’s just a shell script you can throw on your $PATH. Note that for Arch, I also needed to install tree, which it assumes you have.

I also name passage as pass on my machine.

The benefit of this is everything that had pass integration has continued to “just work”. For example, aerc, my email client of choice, behaved exactly the same after the migration.

No more gpg-agent

I would occasionally use gpg-agent as my SSH agent on my machines. It was convenient. However, I also like the idea of having a dedicated SSH key per machine. It makes monitoring their usage and revoking them much finer-grained.

The absence of gpg-agent forced me to set up new keys on all my machines and add them to various servers/services.

Benefits of the age approach

Easy encryption with chezmoi

While I was tending to the encryption area of my personal tech “garden”, I also started leveraging chezmoi’s encryption features. I already use chezmoi for my configuration files, but with encryption, I could also easily add “secrets” to my public dotfiles repo. In my case so far, this just means my copies of my favorite paid font: Berkeley Mono.

chezmoi also has a nice guide for configuring chezmoi to encrypt while asking for a passphrase only once for age.

Easy YubiKey configuration

I was also very pleasantly surprised with how easy it was to switch to age! Last time I set up the GPG keys on my YubiKeys, I spent several hours.

This time, with the help of age-plugin-yubikey and embracing the idea of having unique keys on each YubiKey, but encrypting everything for multiple recipients, setting up my keys was surprisingly trivial. It also generates the keys securely on the hardware key itself, which is nice. The whole process probably took 30 minutes. It was so easy that in the future, I’m very much not intimidated by the thought of rotating keys.

Thoughts

Did I need to switch to age? Of course not.

However, over my career, I repeatedly find that exploring new tools for your core workflows (part of investing in interfaces) is just plain fun. I often learn new ways of thinking about problems. Sometimes, you walk away with a new default that brings some fresh ideas and some delight to your life. Other times, you walk away with your trusty old tool, with greater appreciation for its history and the hard-earned approach it has established. For my uses at the moment, age definitely falls into the former camp.

Tip

This post made it to Hacker News. See the thread for some additional discussion.

Posts from blogs I follow

Running local models is good now

I’ve been working with local models since they came out, and finally, they’re surprisingly good now. I have a 2022 M2 Mac with 64 GB RAM and 1TB storage and I’ve used Mistral 7B Gemma 3 OpenAI OSS-20B Qwen 3 MOE, as well as a number of other Qwen variants…

via ✰Vicki Boykis✰ June 15, 2026

Quoting Julia Evans

[...] Instead, I picture a specific person and I just write for them. Often this person is "me, but 3 years ago" or a good friend. — Julia Evans, write for 1 person Tags: writing, julia-evans

via Simon Willison's Weblog June 15, 2026

A backdoor in a LinkedIn job offer

Last week, I got a LinkedIn message from a recruiter at a small crypto startup. We exchanged a few messages over a couple of days, she described a broken proof-of-concept they needed a lead engineer for, and then sent me a public GitHub repo to review. Spe…

via Roman Imankulov June 15, 2026

Generated by openring-rs from my blogroll.