-
Notifications
You must be signed in to change notification settings - Fork 0
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.
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.
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]
Generate a bifrost key on your first machine:
heimdal key genExport it for safekeeping before moving on:
heimdal key exportStore 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 blobGenerate a new random bifrost key and store it in the OS keychain.
heimdal key genIf 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.
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.
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.
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.
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...heimdal key export
# Copy the blob to your password manager entry for these dotfilesOn 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 cacheheimdal key show
# Copy the hex string to a secure noteRestore with:
heimdal key set
# Paste the hex string when promptedIf your bifrost key is compromised, generate a new one and re-encrypt all history files:
heimdal history rekeyThis command:
- Loads the current bifrost key and derives old subkeys
- Generates a new random bifrost key and derives new subkeys
- Decrypts every
*.jsonl.encfile with the old key and re-encrypts with the new key (atomically) - Re-encrypts the secrets manifest
- 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 exportRe-encrypting with the same key (
heimdal key genwithoutrekey) leaves your history unreadable. Always runheimdal history rekeywhen rotating the key.
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) |
No bifrost key found. Run `heimdal key gen` first.
Run heimdal key gen or heimdal key import to set a key.
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.
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- History Sync - Sync shell history across machines
- Secret Management - Manage secrets
- Commands Overview - Full command reference