NAME
hkdf-tree —
deterministic hierarchical passphrase
derivation from a master seed
SYNOPSIS
hkdf-tree |
derive [--salt
salt] --info
info [--output-len
n] [--raw] |
hkdf-tree |
list --config
file [-v,
--verbose] [--status
status] [--derivation
kind] |
hkdf-tree |
show --config
file --entry
info-string [--newline] |
hkdf-tree |
report --config
file --output
file [--title
title] [--subtitle
subtitle] [--fingerprint
fp] [--entry
info-string] [--status
status] [--derivation
kind] |
DESCRIPTION
hkdf-tree derives passphrases
deterministically from a single high-entropy master seed using HKDF-SHA256
(RFC 5869). Each credential is identified by a hierarchical info-string of
the form
<domain>/<realm>/<purpose>-v<N>,
declared in a YAML inventory together with its encoding (Diceware,
alphanumeric, numeric, or base64). The same seed, salt, and info-string
always reproduce the same passphrase; nothing derived is ever stored.
Subcommands that derive (derive,
show, report) read the
master seed as raw
bytes from standard input. Hex-encoded seeds must be decoded first,
for example with ‘xxd -r -p’.
SUBCOMMANDS
derive- Apply HKDF-SHA256 to the seed on stdin with
--saltand--info, and write--output-lenbytes (default 32) to stdout, hex-encoded unless--rawis given. This is the low-level primitive; it does not consult an inventory. list- Load and validate the inventory given by
--configand print one info-string per entry, deterministically sorted.-vadds derivation kind, status, and encoding per line.--status(active, retired, reserved) and--derivation(hkdf, manual, service-generated) filter the listing and may be repeated. show- Derive and encode a single entry, looked up by
--entry, and print the resulting passphrase to stdout without a trailing newline (add one with--newline). Entries with manual or service-generated derivation are refused. report- Generate a printable A4 PDF (
--output), one card per inventory entry: a human-readable title (the purpose'susagetext) next to a QR code, followed by info-string, encoding, passphrase, paper-backup destinations, and notes. The output file is created with mode 0600.--fingerprintprints a short seed fingerprint on the cover page for cross-verification against the paper backup.By default every entry is included.
--entryrestricts the report to the given info-string and may be repeated;--statusand--derivationfilter as they do forlist, but apply only when--entryis absent, so an explicitly named entry can never be dropped silently. Selection happens before derivation: passphrases of unselected entries are never computed and therefore never reach the output file. Reprinting one card thus exposes exactly that one secret. An info-string that matches nothing is an error, and no file is written — otherwise a typo would be indistinguishable from a successful run until the passphrase is needed and cannot be reproduced.
EXIT STATUS
The hkdf-tree utility exits 0 on
success, and >0 if an error occurs. A usage error (unknown flag,
missing argument) exits with status 2.
EXAMPLES
Derive the low-level bytes for one entry:
xxd -r -p seed.hex | hkdf-tree derive \
--salt acme-hkdf-v1 --info alice/laptop/fde-daily-v1
List all active HKDF-derived entries:
hkdf-tree list --config ~/.config/hkdf-tree/inventory.yaml \
--status active --derivation hkdf -v
Reproduce one passphrase:
hkdf-tree show --config inventory.yaml \
--entry alice/laptop/fde-daily-v1 --newline < seed.bin
Generate the paper-backup report:
hkdf-tree report --config inventory.yaml \
--output /tmp/report.pdf --subtitle "$(date +%F)" < seed.bin
Reprint a single card, deriving nothing else:
hkdf-tree report --config inventory.yaml \
--entry alice/laptop/fde-recovery-v1 \
--output /tmp/one.pdf < seed.bin
SEE ALSO
gpg(1), RFC 5869
Project documentation: README.md, docs/ in the source repository.
AUTHORS
Dr. Johannes Brügmann <dr.johannes.bruegmann@gmail.com>
SECURITY CONSIDERATIONS
The PDF report contains every derived passphrase in plaintext. Write it to volatile storage (tmpfs), print on an offline printer, and destroy the file afterwards; the tool never encrypts anything itself. The master seed should only be entered on trusted, preferably air-gapped systems. The inventory file contains no secrets, only structure and public parameters (including the salt), and may be backed up freely.