Authenticity: This release is quantum‑signed (ML‑DSA‑87) with a detached, offline‑verifiable signature.
Verify in two easy ways:
-
Single‑Download Bundle (best UX)
- Download the zip from the GitHub Release:
black-bagg-0.4.10+qsig.zip
- Run
./verify.sh inside the bundle to verify the detached .qsig against the .crate and trust SPKI
-
Registry‑only (crates.io)
- Download the crate:
curl -sSL -o black-bagg-0.4.10.crate https://crates.io/api/v1/crates/black-bagg/0.4.10/download
- Install Quantum‑Sign:
cargo install quantum-sign
- Get signature + trust:
cargo download black-bagg-sigs --version 0.4.10-qsig.1
- Verify from inside the signatures crate directory:
quantum-sign verify --json --inp ../black-bagg-0.4.10.crate --sig signatures/black-bagg-0.4.10.crate.qsig --trustdb signatures/trust
Black‑Bag (black-bagg crate)

Ultra-secure, zero-trace, pure-Rust CLI vault that operates entirely from RAM and favors modern, conservative cryptographic choices with optional post‑quantum protections.
Table of Contents
- Overview
- RAM‑Only Security Model
- Cryptography (Detailed)
- Installation
- Quick Start with RAM Drive (macOS)
- Basic Usage
- RAM Drive Sizes
- Security Notes
- What’s Fixed in This Version
- Platform Support
- License
- Appendix: Advanced Usage
Features
- RAM-Only Execution: Runs entirely in volatile memory
- Post-Quantum Cryptography: ML-KEM and MLDSA algorithms
- Zero Disk Traces: No swap, no temp files, no forensic artifacts
- Fixed Contact Display: All contact fields now properly display with
get --reveal
- Memory Locking: Prevents secrets from being swapped to disk
Installation
# Installs the CLI binary names `black-bag` and `black-bag-setup`
cargo install black-bagg
Quick Start with RAM Drive (macOS)
# Create 512MB RAM disk
BLACK_BAG_RAM_SIZE=512 black-bag init --ram-drive
# Or manually create RAM disk
DISK=$(hdiutil attach -nomount ram://1048576) # 512MB
diskutil erasevolume APFS "SecureVault" $DISK
# Run black-bag from RAM
cd /Volumes/SecureVault
black-bag init
Basic Usage
# Initialize vault
black-bag init
# Add login
black-bag add login --title "GitHub" --username "user"
# Add contact (with fixed display)
black-bag add contact \
--full-name "John Doe" \
--phones "555-1234" \
--emails "john@example.com"
# View contact (all fields now display properly)
black-bag get <UUID> --reveal
# List all entries
black-bag list
RAM Drive Sizes
- 256MB: Minimal vault (~1000 entries)
- 512MB: Standard vault (~5000 entries) [Default]
- 1GB: Large vault (~10000 entries)
- 2GB: Maximum security (entire binary in RAM)
Security Notes
- Master passphrase required for all operations
- Argon2id key derivation (memory-hard, tunable)
- XChaCha20-Poly1305 authenticated encryption (AEAD)
- Optional post-quantum recipients and signatures
- Memory locking and zeroization to limit residue
RAM‑Only Security Model
Black‑Bag is designed to minimize persistent artifacts while aligning operational practices with the cryptographic model.
- Ephemeral execution
- Run from a RAM disk so the binary and working set live in volatile memory.
- Vault plaintext and DEK exist only in memory; ciphertext on disk is AEAD‑protected.
- Memory locking and zeroization
- On Unix, sensitive buffers are mlock’d (feature
mlock) to avoid paging.
- Secrets are wrapped in
Zeroizing and cleared on drop.
- No temp file leakage
- Uses safe temp handling; avoids plaintext temp files. CBOR serialization happens in memory before encryption.
- Swap/journaling considerations
- Running from RAM reduces incidental writes from shells, editors, or FS journaling.
- Still use a trusted host and disable unnecessary background indexing.
How this ties to the cryptography
- KEK/DEK separation: Your passphrase derives a KEK (Argon2id). The DEK is random and only wrapped under KEK; plaintext DEK never hits disk.
- AEAD with contextual AAD: XChaCha20‑Poly1305 encrypts the vault; AAD binds what is protected (e.g., “sealed‑dek”, “payload”), limiting cross‑context misuse.
- PQ recipients/signatures: Optional ML‑KEM recipients for wrapping and ML‑DSA detached signatures for integrity of exported artifacts or backups.
- Replay/tamper resistance: AEAD tags protect against unauthorized modification; versioned metadata enables safe forward upgrades.
Hardening checklist
- Use a strong passphrase (long, high‑entropy phrase > 6 random words).
- Increase Argon2 memory/time on powerful hosts; rotate keys when you change KDF parameters.
- Operate from a RAM disk; prefer minimal, hardened hosts while the vault is open.
- Keep CLI sessions short; close the vault promptly; avoid screen recordings and terminal logging.
Cryptography (Detailed)
This section documents the current design found in the source. It focuses on confidential storage, integrity, key management, and memory safety. The CLI is intentionally simple, and the crypto posture prioritizes misuse‑resilience and clear failure modes.
High‑Level Design
- Vault keys and payloads are protected with modern AEAD (XChaCha20‑Poly1305) and contextual associated data (AAD).
- The data‑encryption key (DEK) is random and is itself wrapped by a key‑encryption key (KEK) derived from the user passphrase via Argon2id.
- On supported Unix platforms, secret material is mlock’d to reduce paging to disk. Memory is zeroized on drop.
- Optional post‑quantum (PQ) capabilities are available for recipients and signatures when the
pq feature is enabled.
Primitives and Libraries
- AEAD: XChaCha20‑Poly1305 (
chacha20poly1305)
- 256‑bit key; 24‑byte XChaCha nonce (random from
OsRng).
- Provides confidentiality and integrity. Nonce uniqueness is ensured by random generation per encryption.
- KDF: Argon2id (
argon2)
- Tunable memory/time/parallelism; default parameters are selected to be safe on modern hardware and can be increased.
- Randomness:
rand with OsRng (system CSPRNG).
- Serialization: CBOR via
ciborium for structured, self‑describing records.
- Signatures:
- Classical: Ed25519 (
ed25519-dalek).
- PQ (optional via
pq feature): ML‑DSA (mldsa87) for detached signatures (pqcrypto-mldsa).
- PQ Key Encapsulation (optional via
pq): ML‑KEM‑1024 (ml-kem, kem).
- Secret Sharing (for recovery flows): Shamir’s Secret Sharing via
sharks.
- Secure wiping:
zeroize and Zeroizing wrappers.
- Memory locking (Unix):
mlock/munlock via libc behind the mlock feature (enabled by default).
Key Hierarchy and Data Flow
-
Passphrase → KEK
- Argon2id derives a 32‑byte KEK from the user passphrase and a per‑vault salt.
- Parameters: memory (KiB), time (iterations), lanes are persisted in the vault’s metadata to ensure repeatable derivation across hosts.
-
KEK wraps the DEK
- A randomly generated 256‑bit DEK is sealed (AEAD) under the KEK with AAD binding the context.
- AAD values disambiguate what is being protected (e.g., “sealed‑dek”) to harden against cross‑context misuse.
-
DEK encrypts the payload
- Vault contents are serialized (CBOR) and encrypted under the DEK with XChaCha20‑Poly1305, again with contextual AAD.
-
Optional recipients/signatures (PQ lane)
- When
pq is enabled, the crate supports ML‑KEM recipients for wrapping material and ML‑DSA (mldsa87) detached signatures for authenticity of external artifacts.
AEAD Construction Details
- Algorithm: XChaCha20‑Poly1305 (IETF Poly1305 tag, 16 bytes).
- Nonce: 24‑byte XChaCha nonces sampled from
OsRng; uniqueness is enforced through randomness (no reuse within the vault’s lifecycle).
- AAD: Context strings bind the ciphertext to its purpose, preventing several classes of substitution.
Argon2id Parameters
- Mode: Argon2id (hybrid data‑independent/data‑dependent for side‑channel and GPU‑resistance balance).
- Output: 32 bytes (KEK size for the AEAD key).
- Tunables captured in the vault:
mem_cost_kib: recommended ≥ 256 MiB for interactive use on modern CPUs (adjust per device constraints).
time_cost: default around 3 for interactive CLI; raise on powerful hosts.
lanes: typically 1 for predictability; can be raised when more cores and memory bandwidth are available.
Tip: You can start with lower memory on resource‑constrained systems and re‑key the vault later with a stronger setting.
Signatures
- Default builds include Ed25519 for classical signatures.
- PQ signatures (ML‑DSA via
pqcrypto-mldsa) are available under the pq feature. Use detached signatures for external exports or backup manifest integrity.
Post‑Quantum Recipients
- Uses ML‑KEM‑1024 as the KEM primitive for recipient wrapping in PQ mode. This provides strong IND‑CCA2 security against both classical and (conservative) quantum adversaries.
- Hybridization (classical + PQ) is supported by the underlying libs and can be adopted where dual‑track trust is desired.
Secret Sharing (Recovery)
- Leverages the
sharks crate to split sensitive material (e.g., recovery codes or exported secrets) with an M‑of‑N policy.
- Shares are uniformly random and independent; reconstruction requires meeting the threshold.
Memory Safety Posture
- mlock: On supported Unix platforms and with the default
mlock feature, the DEK region is locked in RAM (not swappable).
- Zeroization: Secret buffers are wrapped with
Zeroizing and cleared on drop; critical structs implement Zeroize/ZeroizeOnDrop.
- Minimal copies: Code paths try to avoid unnecessary allocations for secret material.
Serialization and Format
- Format: CBOR via
ciborium for compactness and schema‑friendly evolution.
- Versioning: Vault metadata includes a
VAULT_VERSION for forward migration.
- AAD labels: e.g.,
black-bag::sealed-dek, black-bag::payload are embedded as AAD to prevent cross‑component misuse.
Threat Model (Summary)
This tool aims to:
- Resist disk forensics (RAM‑only operation, mlock where possible, zeroization).
- Provide confidentiality and integrity of vault contents under compromise of plaintext disk.
- Remain robust to nonce misuse via XChaCha’s extended nonce and random sampling.
Out of scope:
- Compromised host OS or persistent malware with live access to your terminal session.
- Side‑channel attacks from privileged co‑resident processes on the same host.
- Cloud sync, remote KMS, or transparent team sharing (by design, the tool is local, explicit, and operator‑driven).
Operational guidance:
- Use a strong passphrase; consider a passphrase manager or physical key entry policies.
- Increase Argon2 memory/time on powerful hosts; re‑key if you later change parameters.
- Consider enabling
pq when you need PQ recipients/signatures for backups or exports.
- Keep your machine free of telemetry/recorders while using the vault.
What's Fixed in This Version
v0.4.5
- Fixed: Contact records now display all fields (full_name, emails, phones) with
get --reveal
- Added: Built-in RAM drive support
- Improved: Memory security with better mlock handling
v0.3.4 Bug Fix
Previously, RecordData::Contact had an empty render_sensitive() implementation at line 1605.
Now properly displays all contact fields when using --reveal.
Platform Support
- macOS: Full RAM disk support via hdiutil
- Linux: tmpfs support
- Windows: ImDisk required for RAM drives
License
MIT OR Apache-2.0
Appendix: Advanced Usage
-
Re‑key vault with stronger Argon2 parameters
# Example: raise Argon2 memory to 512 MiB during rotation
black-bag rotate --mem-kib 524288
-
Generate a TOTP code for an existing record
# Replace with a real UUID from `black-bag list`
black-bag totp code --id 01234567-89ab-cdef-0123-456789abcdef
-
Split a recovery secret into M‑of‑N shares
black-bag backup split --threshold 3 --shares 5 --out ./shares/
# Reconstruct later by providing any 3 shares
black-bag backup combine --in ./shares/ --out ./recovered.key
-
Build features
# Default features include `mlock` and `pq`
cargo build --release
# Disable PQ lane if not needed
cargo build --no-default-features --features mlock --release
# Or explicitly enable PQ
cargo build --features pq,mlock --release
Quantum‑Sign Authenticity
This release includes an offline‑verifiable detached signature using Quantum‑Sign (ML‑DSA‑87).
Verify this crate’s tarball:
# 1) Download the exact tarball from crates.io
curl -sSL -o black-bagg-0.4.9.crate \
https://crates.io/api/v1/crates/black-bagg/0.4.9/download
# 2) Obtain signature + trust (published as a companion crate)
cargo download black-bagg-sigs --version 0.4.9-qsig.1
cd black-bagg-sigs-0.4.9-qsig.1
# 3) Verify offline
quantum-sign verify --json \
--inp ../black-bagg-0.4.9.crate \
--sig signatures/black-bagg-0.4.9.crate.qsig \
--trustdb signatures/trust
Expected: status: ok, alg: mldsa-87, digest_alg: sha512, canonical: true.