Skip to content

Encryption Key Management

Aleem Isiaka edited this page Apr 2, 2026 · 1 revision

Encryption Key Management

Heimdal uses a master encryption key called the bifrost key to protect shell history and the secrets manifest in your dotfiles repository.

Table of Contents

Overview

The bifrost key is a 32-byte random key stored in your OS keychain. It is used to:

  • Encrypt shell history files stored in your dotfiles repo (see History Sync)
  • Encrypt the secrets manifest in .heimdal/secrets_manifest.json.enc

Without a bifrost key, Heimdal falls back to plaintext storage for the manifest and skips history encryption. Generate a key before syncing history or using the encrypted manifest.

How It Works

bifrost key (32 bytes, in OS keychain)
    │
    ├── BLAKE3 derive → history_key  → encrypts *.jsonl.enc files
    └── BLAKE3 derive → manifest_key → encrypts secrets_manifest.json.enc

Each derived subkey is domain-separated so the same bifrost key can safely serve multiple purposes without key reuse.

Encryption uses XChaCha20-Poly1305 with a fresh 24-byte random nonce per ciphertext. The format is:

[0x01 version byte][24-byte nonce][ciphertext + 16-byte auth tag]

Setup

Generate a bifrost key on your first machine:

heimdal key gen

Export it for safekeeping before moving on:

heimdal key export

Store the exported blob somewhere safe (password manager, printed paper). You will need it to set up other machines or recover after losing the keychain entry.

On a second machine, import the exported blob:

heimdal key import
# You will be prompted for the passphrase and blob

Commands

heimdal key gen

Generate a new random bifrost key and store it in the OS keychain.

heimdal key gen

If a key already exists, this replaces it. The old key is discarded — run heimdal history rekey first if you have encrypted history files to preserve.

heimdal key set

Set an existing bifrost key. Always prompted interactively to avoid exposing the key in shell history.

heimdal key set
# Bifrost key (hex): [hidden input]

Use this to restore a key from a hex backup or to set the same key on a new machine without the export/import blob format.

heimdal key show

Print the current bifrost key as a hex string.

heimdal key show
# bifrost key: 3a7f2c...

Use this for manual backup or to copy the raw key to another machine. Keep the output private.

heimdal key export

Export the bifrost key as a passphrase-protected base64url blob, safe to store anywhere.

heimdal key export
# Enter export passphrase: [hidden]
# Confirm passphrase: [hidden]
# Exported key blob:
# AGIh3xK...

The blob format is: base64url([32-byte Argon2id salt][XChaCha20-Poly1305(bifrost, passphrase-derived key)]). The passphrase is processed with Argon2id (memory-hard), making brute-force attacks expensive.

heimdal key import

Import a passphrase-protected blob from heimdal key export.

# Interactive — prompted for blob and passphrase
heimdal key import

# Pass the blob directly (passphrase is still prompted)
heimdal key import AGIh3xK...

Backup and Restore

Recommended: Export to a Password Manager

heimdal key export
# Copy the blob to your password manager entry for these dotfiles

On a new machine:

heimdal init --repo git@github.com:user/dotfiles.git --profile default
heimdal key import
# Paste the blob when prompted, enter your passphrase
heimdal history sync   # decrypt and rebuild history cache

Alternative: Hex Backup

heimdal key show
# Copy the hex string to a secure note

Restore with:

heimdal key set
# Paste the hex string when prompted

Rekeying

If your bifrost key is compromised, generate a new one and re-encrypt all history files:

heimdal history rekey

This command:

  1. Loads the current bifrost key and derives old subkeys
  2. Generates a new random bifrost key and derives new subkeys
  3. Decrypts every *.jsonl.enc file with the old key and re-encrypts with the new key (atomically)
  4. Re-encrypts the secrets manifest
  5. Replaces the bifrost key in the OS keychain

After rekey completes, the old key is no longer valid. Export and back up the new key immediately:

heimdal key export

Re-encrypting with the same key (heimdal key gen without rekey) leaves your history unreadable. Always run heimdal history rekey when rotating the key.

Security Model

What the bifrost key protects:

  • Shell history in the dotfiles repo (each entry individually encrypted)
  • The secrets manifest file in the dotfiles repo

What it does NOT protect:

  • The local plaintext staging file at ~/.heimdal/history_staging.jsonl
  • The local history cache at ~/.heimdal/history.cache

Both local files are plaintext. This is an accepted trade-off: encrypting on every keystroke would add latency to every shell command. The bifrost key protects history in the git repo, which may be public. The local machine is assumed to be trusted. Users who require encryption at rest on the local machine should use full-disk encryption (FileVault, LUKS, BitLocker).

Key storage:

Platform Backend
macOS macOS Keychain
Linux Secret Service (GNOME Keyring, KWallet)

Troubleshooting

No bifrost key found

No bifrost key found. Run `heimdal key gen` first.

Run heimdal key gen or heimdal key import to set a key.

Passphrase-protected blob fails to decrypt

Check that you are using the correct passphrase. There is no recovery from a forgotten passphrase — if you also lost the hex backup, the key cannot be recovered and encrypted history files are unreadable.

History files unreadable after heimdal key gen

If you ran heimdal key gen without first running heimdal history rekey, the new key cannot decrypt files encrypted with the old key. If you have the old key backed up:

heimdal key set    # restore the old key
heimdal history rekey   # re-encrypt with a new key

Next Steps

Clone this wiki locally