black-bag
black-bag is a zero-trace, no-compromise command-line vault for high-risk operators. It ships as a single Rust binary with the strongest defaults we can provide: Argon2id hardening, ML-KEM-1024 cascaded wrapping (Kyber), XChaCha20-Poly1305 payload encryption, zeroization of every secret buffer, and page-locked memory on Unix. There is no optional telemetry, no cloud, no GUI—just a laser-focused CLI that keeps secrets safe even under hostile conditions.
Highlights
- Zero-trace posture – secrets never touch stdout, logs, temp files, or the clipboard. All input happens via hidden TTY prompts and is stored only after AEAD encryption.
- Modern crypto pipeline – Argon2id → ML-KEM-1024 (Kyber) → random 32-byte DEKs sealed with XChaCha20-Poly1305. Writes are atomic/fdatasync’d with strict permissions and zeroized in memory on drop.
- Rich record catalogue – logins, contacts, identity docs, secure notes, payment cards, SSH keys, PGP keys, TOTP seeds, recovery kits, bank accounts, Wi-Fi profiles, API credentials, and crypto wallets. Every record supports tagging and full-text queries.
- Cross-platform parity – builds cleanly on macOS, Linux, and Windows.
mlockis enabled automatically on supported Unix platforms and degrades gracefully elsewhere. - Security by default – all protective features are enabled in every binary; there are no configuration flags that weaken the threat posture.
Quick start
# prerequisites: Rust toolchain 1.81+ (via rustup) and a standard build environment
Recommended hygiene:
- Run from an encrypted disk.
- Disable shell history or use
HISTCONTROL=ignorespacewith leading spaces. - Set
RUST_BACKTRACE=0in operational shells.
Creating your vault
You’ll be prompted for the master passphrase twice. The vault stores under the platform data directory (e.g., ~/.config/black_bag/vault.cbor).
Adding records
# login
# contact
# identity document
# secure note
# bank account
# Wi-Fi profile
# API credential
# crypto wallet
# totp secret
# totp codes
Sensitive fields (passwords, passphrases, API secrets, private keys) are collected via hidden prompts after the command issues—nothing sensitive ever appears in argv or shell history.
Listing, filtering, and querying
Inspect a specific record:
Rotation, health, and recovery
black-bag rotate– rewraps the master DEK with fresh randomness.black-bag doctor– prints health info (Argon2 params, feature flags, item counts).black-bag recovery split/combine– manage Shamir shares for catastrophic recovery.black-bag version– display binary version, target, and compiled features (mlock, pq, fuzzing, etc.).black-bag backup keygen/sign/verify– manage ML-DSA-87 (or legacy Ed25519) authenticity for offline backups.
CLI Command Reference
| Command | Purpose | Notes |
|---|---|---|
black-bag init [--mem-kib <KiB>] |
Create a new vault with Argon2id + ML-KEM-1024 wrapping | Default memory cost: 262 144 KiB (256 MiB) |
black-bag add <record-type> [...] |
Add login/contact/id/note/bank/wifi/api/wallet/totp/ssh/pgp/recovery records | Sensitive fields captured via hidden prompts |
black-bag list [--kind KIND] [--tag TAG] [--query Q] |
Show masked summaries | Combine filters for scoped audits |
black-bag get <UUID> [--reveal] |
Inspect records; optionally reveal secrets on a TTY | --reveal denied on non-interactive stdout |
black-bag totp code <UUID> [--time <UNIX>] |
Generate TOTP codes | Supports historic/time-skew analysis |
black-bag rotate [--mem-kib <KiB>] |
Rewrap master DEK with fresh randomness | Optional Argon2 memory override |
black-bag doctor [--json] |
Print health diagnostics | JSON output ready for monitoring pipelines |
black-bag recovery split/combine |
Manage Shamir shares for disaster recovery | Configurable thresholds and share counts |
black-bag backup keygen/sign/verify |
Manage ML-DSA-87 (or Ed25519) backup signatures | Produces .int + .int.sig companions |
black-bag selftest |
Run embedded round-trip checks | Useful after upgrades or migrations |
black-bag version |
Display build version, target, and enabled features (mlock, pq, fuzzing) |
Validate release binaries |
Backup workflow (PQ-safe)
# one-time: generate ML-DSA-87 keys for signing sidecars
# copy the ciphertext and immediately mint/update integrity + signature sidecars
# later, verify both bit-rot and authenticity before restore
The signing command produces two companions next to the ciphertext: vault-*.cbor.int (BLAKE3 tag keyed with the ML-KEM public key) and vault-*.cbor.int.sig (ML-DSA-87 or Ed25519 signature). Ship all three files together and treat any verification failure as tampering until proven otherwise.
Rotation, health, and recovery
black-bag rotate– rewraps the master DEK with fresh randomness.black-bag doctor– prints health info (Argon2 params, feature flags, item counts).black-bag recovery split/combine– manage Shamir shares for catastrophic recovery.black-bag selftest– quick sanity check of encryption/decryption paths.black-bag version– confirm binary target/profile and compiled features (mlock,pq, etc.).
Threat model (summary)
See docs/THREAT_MODEL.md for assumptions, adversary capabilities, and residual risks. Treat the vault ciphertext as sensitive and keep backups offline.
Building and testing
CI should run the same three commands on every commit. Tests cover cryptographic round-trips, helper utilities, and zero-trace guarantees.
Memory Locking (mlock)
On Unix platforms, when built with the default mlock feature, black-bag locks sensitive memory (passphrases, DEKs, and secret buffers) using mlock(2) for the lifetime of those values and unlocks it on drop. This reduces the risk of secrets being paged to disk.
- Status check:
black-bag doctorreports whethermlockis enabled and functional on the host. - macOS:
mlockgenerally works for unprivileged processes within system limits. If you run into failures, check per-process limits withulimit -land consider adjusting them in your launch environment. - Linux:
mlockrequires sufficientRLIMIT_MEMLOCKorCAP_IPC_LOCK.- Temporary session limit (KB):
ulimit -l 65536(example: 64 MiB) - Or grant the binary capability (use with care):
sudo setcap cap_ipc_lock=+ep $(command -v black-bag)
- Temporary session limit (KB):
Notes:
- Locking is best‑effort; when the OS refuses the lock, black-bag continues to function but warns in
doctoroutput. You should raise limits untildoctorreportsmlock: enabled and working. - On non‑Unix targets, the
mlockfeature is ignored and no attempts are made to pin memory.
Shamir Secret Sharing
The recovery split / combine commands now use the vetted sharks crate (GF(2^8)) under the hood, keeping the same CLI and share format (id-base64). See docs/SHAMIR.md for details and security notes.
Mission-ready checklist
- Argon2id + ML-KEM-1024 + XChaCha20-Poly1305 enabled by default
- No GUI, clipboard, or plaintext log exposure
- Cross-platform parity (Windows/macOS/Linux)
- Comprehensive record catalogue with search & tagging
- Lint/tests clean with zero warnings
- Operator docs and threat model committed
For production roll-out, schedule an independent cryptography/code audit and set up fuzzing pipelines (see docs/FURTHER_HARDENING.md).