black-bagg 0.2.1

Ultra-secure, zero-trace, pure-Rust CLI vault for spies, journalists, and privacy maximalists.
Documentation

black-bag

black-bag is a zero‑trace, ultra‑secure, CLI‑only vault for high‑risk operators. It ships as a single Rust binary with strict defaults (Argon2id time=10; lanes≥4), ML‑KEM‑1024 cascaded wrapping, XChaCha20‑Poly1305 encryption, and meticulous I/O hygiene (no stdout secrets by default, no temp files, atomic 0600 writes). Cross‑platform (macOS/Linux/Windows).

Core ideas:

  • Secrets never go to stdout by default; reveals are TTY‑only unless you consciously opt into unsafe modes.
  • Strong crypto: Argon2id → ML‑KEM‑1024 (Kyber1024) → 32‑byte DEK → XChaCha20‑Poly1305 for payload and per‑record secret fields.
  • Strict limits and locking: page‑locking (best effort), input caps, constant‑time ops, sanitized errors.

Contents

  • Install and Build
  • Quick Start
  • Operations Guide (day‑to‑day flows)
  • CLI Reference (every command + flags, with examples)
  • Security Model (short)
  • Configuration (env/feature flags)
  • Troubleshooting

Install and Build

# From crates.io (recommended)
cargo install --locked black-bagg --features pq

# Local build
cargo build --release
install -m 0755 target/release/black-bag ~/.local/bin/black-bag

black-bag --version

Tips:

  • Use an encrypted disk; avoid shell history (e.g., HISTCONTROL=ignorespace).
  • For mission shells, set BLACK_BAG_HARD_MODE=1 to force TTY‑only and disable unsafe stdout/clipboard overrides.

Quick Start

# 1) Initialize vault (256 MiB Argon2 memory)
black-bag init --mem-kib 262144 --argon-lanes auto

# 2) Add a login
black-bag add login --title "Ops" --username phoenix --url https://ops.example --tags mission

# 3) List masked summaries
black-bag list --query ops

# 4) Reveal one record on a TTY
black-bag get <UUID> --reveal  # TTY required

# 5) Add a TOTP seed (prefer SHA‑256)
black-bag add totp --issuer GitHub --account you@example --secret-file ./totp.txt --algorithm sha256
black-bag totp code <UUID>

# 6) Rotate wrapping keys after missions
black-bag rotate

# 7) Split recovery material (3‑of‑7)
black-bag recovery split --threshold 3 --shares 7

Operations Guide

Create and Unlock

  • black-bag init --mem-kib 262144 --argon-lanes auto prompts for a strong passphrase (≥14 NFKC chars and zxcvbn≥3).
  • On first use of commands like list, get, add, the CLI prompts to unlock.

Add Records (selected families)

  • Login: add login --title "Portal" --username alice --url https://example --tags prod
  • Note: add note --title "Protocol" --tags red-team then paste body (Ctrl‑D to end).
  • API: add api --service intel --environment prod --access-key AKIA... --scopes read,write
  • TOTP: add totp --issuer GitHub --account you@example --secret-file ./secret.txt --algorithm sha256
    • Safer alternative: printf 'otpauth://...' | black-bag add totp --otpauth-stdin
    • Optional ASCII QR: add --qr --confirm-qr.
  • SSH/PGP/Recovery: add ssh|pgp|recovery then paste private/armored payload; stored encrypted.

Search and Inspect

  • list (masked): filter with --kind, --tag, --query, or --fuzzy.
  • get <UUID> --reveal shows secrets on TTY. Clipboard copy requires build feature and --unsafe-clipboard.

Rotation, Passphrase Changes, Migration

  • rotate [--mem-kib N] refreshes KEM and rewraps DEK (updates header MAC/epoch).
  • passwd [--mem-kib N] [--argon-lanes auto|N] [--rekey-dek] changes passphrase and optionally rekeys payload DEK.
  • migrate bumps an older vault to latest on‑disk version and recomputes header MAC.

Recovery and Backups

  • Shamir split: recovery split --threshold 3 --shares 7 outputs shares and a share‑set ID (commit). Store separately.
  • Combine: recovery combine --threshold 3 --shares 1-<b64>,2-<b64>,3-<b64> [--set-id ...] [--raw]
    • --raw emits binary to TTY; otherwise base64.
  • Backup check: backup verify --path ~/.config/black_bag/vault.cbor validates public integrity sidecar without passphrase.

CLI Reference (Complete)

Global flags (prefix any subcommand):

  • --unsafe-stdout – allow secrets to flow to stdout/JSON (default off; prefer TTY)
  • --require-mlock – require page‑locking or abort
  • --emit <tty|stdout|json> – preferred output mode for non‑reveal flows (stdout/json require --unsafe-stdout)
  • --agent <none|keychain> – enable keychain agent (feature‑gated)
  • --unsafe-clipboard – allow copying secrets to clipboard (feature‑gated)
  • --duress – operate on a separate duress vault file
  • Env hard mode: BLACK_BAG_HARD_MODE=1 forces TTY‑only/clipboard‑off regardless of flags

init

Initialize a new vault.

black-bag init --mem-kib <KiB> [--argon-lanes auto|N]

Args:

  • --mem-kib (default 262144; min 32768)
  • --argon-lanes auto (CPU cores capped 8, min 4) or integer ≥4

add

Add records in families. Sensitive values are captured by prompt/stdin/file; never argv.

Common options: --title <str> --tags <t1,t2> --notes <str>

Families:

  • login--username <str> --url <str>
  • contact--full-name <str> --emails <e1,e2> --phones <p1,p2>
  • id--id-type <str> --name-on-doc <str> --number <str> --issuing-country <str> --expiry <YYYY-MM-DD> (secret via prompt)
  • note – paste body after prompt (Ctrl‑D to finish)
  • bank--institution <str> --account-name <str> --routing-number <str> (account number via prompt)
  • wifi--ssid <str> --security <str> --location <str> (passphrase via prompt)
  • api--service <str> --environment <str> --access-key <str> --scopes <s1,s2> (secret key via prompt)
  • wallet--asset <str> --address <str> --network <str> (secret key via prompt)
  • totp--issuer <str> --account <str> --secret-file <PATH> --secret-stdin --otpauth-stdin --qr --confirm-qr --digits 6..8 --step <secs> --skew <steps> --algorithm <sha1|sha256|sha512>
  • ssh--label <str> --comment <str> then paste private key
  • pgp--label <str> --fingerprint <str> then paste armored private key
  • recovery--description <str> then paste recovery payload

Examples:

black-bag add login --title "Ops" --username alice --url https://ops --tags prod
black-bag add note --title "Protocol" --tags red-team
black-bag add totp --issuer GitHub --account you@example --secret-file ./secret.txt --algorithm sha256

list

black-bag list [--kind <family>] [--tag <tag>] [--query <text>] [--fuzzy]

Families: login, contact, id, note, bank, wifi, api, wallet, totp, ssh, pgp, recovery

get

black-bag get <UUID> [--reveal] [--clipboard]

Notes: --reveal requires TTY; --clipboard requires feature + --unsafe-clipboard and auto‑clears.

rotate

black-bag rotate [--mem-kib <KiB>]

doctor

black-bag doctor [--json]

Prints ready status, Argon2 params, record count, timestamps, and JSON includes headerMacVerified.

passwd

black-bag passwd [--mem-kib <KiB>] [--argon-lanes auto|N] [--rekey-dek]

migrate

black-bag migrate

export csv

black-bag export csv [--kind <family>] --fields <f1,f2,...> [--include-secrets] --unsafe-stdout

Common fields: id,kind,title,tags,summary,username,url,password,secret_key,totp_secret

backup verify

black-bag backup verify --path <vault.cbor>

recovery split / combine

black-bag recovery split --threshold <n> --shares <m> [--duress]
black-bag recovery combine --threshold <n> --shares <id-b64,...> [--set-id <base32>] [--raw] [--duress]

totp code

black-bag totp code --id <UUID> [--time <unix>]

selftest

black-bag selftest

Security Model (Short)

  • KDF: Argon2id (time=10; lanes≥4, capped 8). Passphrase policy: NFKC, ≥14 chars, uniqueness, zxcvbn≥3.
  • Wrapping: ML‑KEM‑1024 public key + ciphertext. Decapsulation secret sealed with KEK.
  • Payload & secret fields: XChaCha20‑Poly1305 AEAD with distinct AADs; per‑record rDEKs for secrets at rest.
  • Header integrity: keyed BLAKE3 MAC over critical header fields; verified on unlock (constant‑time compare).
  • Public integrity sidecar: Blake3 tag keyed by KEM public to detect bit‑rot without secrets.
  • Anti‑rollback: header epoch + .epoch sidecar (warn/fail); optional keychain epoch pin (feature‑gated) to fail on rollback.
  • Process hardening: no coredumps; tracer/ptrace protections; release panic=abort; sanitized errors by default.
  • Windows ACL: refuse insecure vault directory (Everyone/Authenticated Users write).

References: docs/CRYPTO_POLICY.md, docs/THREAT_MODEL.md, docs/SECURITY_MODEL.md, docs/VAULT_FORMAT.md.

Configuration

  • Env vars: BLACK_BAG_VAULT_PATH, BLACK_BAG_VAULT_DURESS_PATH, BLACK_BAG_UNSAFE_STDOUT, BLACK_BAG_REQUIRE_MLOCK, BLACK_BAG_EMIT, BLACK_BAG_AGENT, BLACK_BAG_UNSAFE_CLIPBOARD, BLACK_BAG_DURESS, BLACK_BAG_HARD_MODE, BLACK_BAG_STRICT_ROLLBACK, BLACK_BAG_ALLOW_ROLLBACK (see docs for details).
  • Features: default mlock, pq; optional tui, agent-keychain, clipboard, fuzzing.

Troubleshooting

  • “vault not initialized” → run init or set BLACK_BAG_VAULT_PATH.
  • “header integrity check failed” → stop; header was altered (rollback/tamper). Restore last known good.
  • Windows “insecure vault directory permissions” → restrict ACL to current user only.
  • TOTP QR warn → requires --confirm-qr.
  • Clipboard unavailable → not compiled or --unsafe-clipboard not set.

Mission‑Ready Checklist

  • Argon2id + ML‑KEM‑1024 + XChaCha20‑Poly1305 enabled by default
  • TTY‑only reveals; no stdout secrets by default
  • Strict input caps; atomic writes; zeroized buffers
  • Cross‑platform (macOS/Linux/Windows)
  • Comprehensive record families; search/tagging
  • Tests green; warnings denied
  • Operator docs + threat model

For production roll‑out, schedule an independent audit and set up long‑run fuzzing (see docs/FURTHER_HARDENING.md).

Recent Security Changes

  • Removed CLI secret parameters (prompt/stdin/file only)
  • Constant‑time Shamir GF operations; sanitized errors
  • Migrated to ML‑KEM‑1024; runtime size checks
  • Input bounds added (pre/post parse caps)
  • Argon2 defaults increased (time=10; lanes auto≥4)