Skip to main content
  1. Posts/
  2. The Solo Stack/
  3. Dotfiles/

Encrypting SSH Keys with age and chezmoi

·654 words·4 mins
Dotfiles - This article is part of a series.
Part 4: This Article

In the previous article, we spent some time getting a post-quantum enabled version of age installed. Now it’s time to put it to use — by creating an age key and wiring it up with chezmoi to encrypt our SSH keys directly in the dotfiles repo.

Generating a Post-Quantum Age Key
#

First, we create the directory for the key and generate a new post-quantum key pair:

mkdir -p ~/.config/age
age-keygen -pq -o ~/.config/age/dotfiles-repo-key.txt

This generates the key file at ~/.config/age/dotfiles-repo-key.txt. Next, we lock down the permissions so only our user can access it:

chmod 600 ~/.config/age/dotfiles-repo-key.txt
chmod 700 ~/.config/age

Important: Back up this key to a safe location — a USB drive, a vault, Bitwarden, 1Password, whatever works for you. Without this key, there’s no way to decrypt your secrets from the repo. Lose the key, lose access.

Configuring chezmoi for Age Encryption
#

With the key in place, we need to tell chezmoi to use it. Normally, you’d put this configuration in ~/.config/chezmoi/chezmoi.toml — but that file wouldn’t be restored by chezmoi itself, which defeats the purpose.

Fortunately, chezmoi has a template mechanism for exactly this. Instead of creating the config file directly, we create a template that chezmoi will render on every init. This way, the configuration lives in the repo and gets recreated automatically on new machines.

Let’s create that template:

chezmoi cd
touch .chezmoi.toml.tmpl

Then add the following content. First, we define the encryption type:

encryption = "age"

Then we add a section for the age-specific settings — the path to our key (the identity) and the public key (the recipient):

[age]
  identity = "~/.config/age/dotfiles-repo-key.txt"
  recipient = "age1pq1...."

The recipient is the public key from your dotfiles-repo-key.txt file. It’s quite long — that’s the post-quantum cryptography at work.

Now let’s test this by running chezmoi init, which processes the template:

chezmoi init

After this, you should find a file at ~/.config/chezmoi/chezmoi.toml with the rendered contents of your template.

Adding Encrypted SSH Keys to the Repo
#

Now for the actual goal: encrypting our SSH keys and storing them in the dotfiles repo.

This is safe to do because the age private key never gets added to the repo — only the encrypted files do. The public key in .chezmoi.toml.tmpl is not sensitive, so sharing it in the repo is fine.

For my setup, I have id_ed25519_knuth-info and id_ed25519_knuth-info.pub in my .ssh directory, which I use for GitHub access. Your key names may differ. To add them with encryption:

chezmoi add --encrypt ~/.ssh/id_ed25519_knuth-info
chezmoi add --encrypt ~/.ssh/id_ed25519_knuth-info.pub

If everything worked, you should see the encrypted files in the chezmoi repo:

chezmoi cd
ls -al private_dot_ssh/

The files will have an encrypted_ prefix and an .age suffix. Chezmoi also adds a private_ prefix for the private key, so in my case:

encrypted_id_ed25519_knuth-info.pub.age
encrypted_private_id_ed25519_knuth-info.age

To verify that chezmoi can actually decrypt them:

chezmoi cat ~/.ssh/id_ed25519_knuth-info.pub

If you see your public key printed to the terminal, everything is wired up correctly.

Pushing the Changes
#

The last step is to commit and push the encrypted keys to the dotfiles repo:

chezmoi cd
git add -A
git commit -m "add age-encrypted SSH Keys (age post quantum! requires v 1.2.0+)"
git push

From now on, every chezmoi init on a new machine will restore the encrypted SSH keys automatically.

What’s Next
#

Our workflow for setting up a new machine has become a lot more comfortable. We can install git and curl, run chezmoi init with our GitHub username, and our SSH keys come along for the ride.

But we’re not quite there yet. We still need to ensure that age is installed at version 1.2.0 or higher for post-quantum support, and we need to manually place the age key in the right location. On top of that, configuring git inside the chezmoi directory — name, email, and switching from HTTPS to SSH remotes — isn’t automated either. We’ll tackle that in the next post.

Marcus Knuth
Author
Marcus Knuth
Dotfiles - This article is part of a series.
Part 4: This Article

Related

Why apt install age Isn't Enough

·612 words·3 mins
In the previous article, I set up disposable containers to test my chezmoi dotfiles. That works, but there’s still too much manual effort involved — especially the SSH key. Every new container means copying it in by hand. So I decided to encrypt the SSH key with age and store it directly in the dotfiles repo. Chezmoi supports age-based decryption out of the box, which makes this a natural fit. On top of that, I want future tool installations — zsh, tmux, neovim — to be handled automatically too, not typed in manually every time.

Getting Started with Dotfile Management

·1225 words·6 mins
Getting Started with Dotfile Management # Up until now, I’ve mostly been working with GUI-driven IDEs on Windows. I wrote about why I’d like to shift to the terminal — the short version is that a portable, keyboard-driven workflow matters when you’re building solo. But alongside that shift, something else has been happening. Since Docker entered my daily work, I’ve been spending more and more time on Linux again — something I hadn’t done seriously since studying computer science. Linux stepped back into my life gradually, and for a long time I just used it without thinking much about it. I never cared about the fundamentals.

Testing My Dotfiles in Disposable Containers

·880 words·5 mins
In the previous article, we got started with dotfile management and zsh using chezmoi. Now I’d like to experiment — try out new configs, install tools, tweak settings — but without ruining my host’s environment in the process. A safe space to try things out that also plays perfectly into my later dev container goal: one-time containers. They let me practice spinning up my environment from basically nothing, and they allow me to experiment with apps and configurations without any effect on my host machine. If something breaks, I just exit the container and it’s gone.