Reference

Undoing a change

Every write keeps the last 5 versions, and rm keeps the file too.

passbox restore github/token            # list versions
passbox restore github/token --index 0  # put the newest one back

What is on disk

~/.passbox/
  store/<random-id>.age     one self describing secret per file
  store/<random-id>.tomb    deletion marker
  store/.versions/<id>/     earlier versions, kept local
  wraps/recipient           the store public key, no secret in it
  wraps/recovery.age        the store key under your passphrase, only once sync is on
  wraps/se-<host>.json      the store key under that Mac's Secure Enclave
  audit-<host>.log          one encrypted record per line
  broker.sock               the approval socket

The filename is a random id. Names live inside the ciphertext, so nothing on disk says what a secret is called. What still leaks: how many secrets exist, their sizes, and their modification times.

Environment

VariableEffect
PASSBOX_DIRWhere the store lives, default ~/.passbox
PASSBOX_REMOTEOverrides the destination for one run, ahead of the one sync --enable recorded
PASSBOX_AGENTName shown in the prompt beside the secret
PASSBOX_NO_AUTOSYNCSet to stop a write copying to the configured directory
PASSBOX_PASSPHRASESupplies the passphrase for CI and headless use, and turns off the Enclave path

Building

cargo test
cargo test -- --ignored   # the Secure Enclave round trip, needs a finger

build.rs compiles the Swift helper with swiftc from the Command Line Tools.

Fields in one entry

An entry can hold more than a password. The first line is the secret, later key: value lines are fields, which is the layout pass uses and import-pass keeps.

passbox get db/prod                  # the whole thing
passbox get db/prod --field username # just that one

Reading one field hands a caller the password without the note beside it.

Using it from a program

In Rust, add the crate without its default features. They build the CLI's Secure Enclave helper, which the library does not use:

cargo add passbox --no-default-features
use passbox::Passbox;

// One approval covers both secrets for 24 hours
let mut pb = Passbox::new(Some("acme"), Some("my-job"), &["api", "db"]);

// Preferred: the value goes from the broker into the child
let out = pb.run_with("API_KEY", "api", &["./deploy"])?;

// When a library needs the value in-process
let db = pb.fields("db")?;
let password = &db["password"];

The library runs the passbox binary on PATH, so it works on a Mac and on a Linux machine that asks one. examples/rust is a small project that depends on it.

examples/ also holds Python and TypeScript clients, each with a runnable self-check. The same shape works in any language: shell out to passbox exec to hand a secret to a child process, and mint one grant per process rather than one per read.

For agents specifically, see AGENTS.md, and the SKILL.md that teaches a coding agent to use passbox correctly.