---
title: lockbox
description: >-
  A minimal, secure CLI password manager in Go: one encrypted file, Argon2id key
  derivation, and an in-memory session agent.
url: 'https://stroops.tech/lockbox'
last_updated: '2026-06-28'
---
# lockbox: A Minimal, Secure CLI Password Manager in Go: Setup & Usage Guide

Most password managers want to live in your browser, sync to someone's cloud, and
ask you to trust a service you can't audit. **lockbox** takes the opposite stance:
it's a single Go binary that keeps your credentials in **one encrypted file** on
your own machine. No database. No network. No telemetry. Just a local, encrypted
blob and a master password only you know.

In this guide I'll walk through what makes lockbox different, how to install it,
and how to use it day to day — including multiple vaults, built-in 2FA codes, and
a clever in-memory session model that means you only type your master password
once every 15 minutes instead of on every command.

---

## Why another password manager?

A few design decisions set lockbox apart:

- **One file, one blob.** Your whole vault is encrypted as a *single*
  AES-256-GCM blob. There's no per-item encryption, no SQLite file to leak
  metadata, no sync server. The on-disk file lives at `~/.lockbox/store.vault`
  and is mode `0600` (only you can read it).
- **Strong key derivation.** Your master password is stretched into an encryption
  key with **Argon2id** (64 MiB of memory, 3 passes, 4 lanes) — the modern,
  memory-hard standard that makes brute-forcing painful.
- **Plaintext never touches disk.** The decrypted vault only ever exists in memory.
- **No recovery, by design.** If you forget your master password, your data is
  gone. That's the point — there's no backdoor for anyone, including you.
- **Tiny dependency footprint.** Standard library plus `golang.org/x/crypto`
  (Argon2id) and `golang.org/x/term` (no-echo password input). That's it.

---

## The clever bit: in-memory sessions

A CLI process exits after every command. So how do you avoid retyping your master
password for every single `get` or `add`?

lockbox solves this with a **background agent**:

1. `lockbox unlock` prompts for your master password, derives the key, and starts
   a small detached daemon.
2. That daemon holds the **key in memory** — never on disk, never on the command
   line — and listens on a per-vault Unix-domain socket (`~/.lockbox/agent.sock`,
   mode `0600`).
3. Commands like `add`, `get`, and `list` send *raw blobs* to the agent for
   encryption/decryption. The key itself never leaves the daemon.
4. The session **auto-locks after 15 minutes** of inactivity (each command resets
   the timer), with a hard cap of 24 hours. When it expires, the agent wipes the
   key and exits.
5. For extra safety, the agent only accepts requests from another process running
   the *same* lockbox binary — so even other processes under your user account
   can't ask it to decrypt your vault.

The result: type your password once, work freely for a while, and let it lock
itself automatically.

---

## Installation

### Homebrew (macOS)

```sh
brew install triforge0/tap/lockbox
```

### Pre-built binaries

Grab an archive for your OS/arch from the
[releases page](https://github.com/triforge0/lockbox/releases), then drop the
`lockbox` binary somewhere on your `PATH`. Linux and Windows builds are published
too.

### From source

If you have Go installed:

```sh
go install ./cmd/lockbox        # installs `lockbox` to $GOBIN
```

Or build a standalone binary:

```sh
go build -o lockbox ./cmd/lockbox
```

Cross-compiling for Windows is a one-liner:

```sh
GOOS=windows GOARCH=amd64 go build -o lockbox.exe ./cmd/lockbox
```

---

## Your first vault

Let's go from zero to a working, locked-down vault.

### 1. Create the vault

```sh
lockbox init
```

This creates a new empty encrypted vault and asks you to set a master password.
There's no overwrite if a vault already exists — and no way to recover this
password later, so choose something strong and memorable.

### 2. Start a session

```sh
lockbox unlock
```

Enter your master password once. Behind the scenes, the agent spins up and holds
your key in memory.

### 3. Add a credential

```sh
lockbox add github
```

You'll be prompted for a username, a password, and an optional 2FA secret. Need a
strong password on the spot? Generate one:

```sh
lockbox gen 24       # 24-character random password (default is 20)
```

### 4. Read it back

```sh
lockbox get github           # show username + password
lockbox get github -p         # print ONLY the password, no trailing newline
```

That `-p` flag is pipe-friendly. On macOS you can copy a password straight to the
clipboard without it ever appearing on screen:

```sh
lockbox get github -p | pbcopy
```

### 5. Lock when you're done

```sh
lockbox lock
```

This ends the session immediately and wipes the in-memory key.

---

## Everyday commands

Here's the full toolbox:

```sh
lockbox init                # create a new empty encrypted vault
lockbox unlock              # start a session (prompts for master password)
lockbox add <service>       # add credentials (username, password, optional 2FA)
lockbox edit <service>      # update a service (blank input keeps current value)
lockbox get <service>       # print credentials for a service
lockbox get <service> -p    # print only the password (pipe-friendly)
lockbox list                # list all stored service names
lockbox list -l             # list services with usernames and a 2FA column
lockbox search <query>      # find services by name or username
lockbox totp <service>      # print the current 2FA code for a service
lockbox delete <service>    # remove a service (confirms; -f to skip)
lockbox change-password     # change the master password (re-encrypts the vault)
lockbox status              # show whether the vault is unlocked
lockbox lock                # end the session immediately
lockbox vaults              # list all vaults and whether each is unlocked
lockbox export -o out.json  # export the vault as plaintext JSON (confirms)
lockbox import in.json      # merge items from a JSON file (--overwrite to replace)
lockbox gen [length]        # generate a random password (default length 20)
```

### Built-in 2FA (TOTP)

lockbox can also be your authenticator app. When you add or edit a service, you
can store a base32 TOTP seed alongside the password. Then:

```sh
lockbox totp github          # prints the current 6-digit code
```

It implements RFC 6238 (HMAC-SHA1, 30-second window, 6 digits) with nothing but
the standard library. The seed is stored inside the same encrypted vault, so your
second factor is protected by the same master password.

### Checking session state

```sh
lockbox status
```

This tells you whether the vault is currently unlocked and when it will auto-lock.

---

## Multiple vaults

Want to keep work and personal credentials completely separate? Use the global
`--vault` (or `-V`) flag. Each named vault is its own file with its own master
password and its own session — unlocking one never decrypts another.

```sh
lockbox --vault work init
lockbox -V work unlock
lockbox -V work add github
```

The flag can appear anywhere in the command. List all your vaults and whether each
is currently unlocked with:

```sh
lockbox vaults
```

---

## Backup, migration, and changing your password

### Export / import

You can move credentials in and out as plaintext JSON. Because export writes
*unencrypted* data, lockbox asks you to confirm:

```sh
lockbox export -o backup.json     # dump everything to a JSON file
lockbox import backup.json         # merge items from a JSON file
lockbox import backup.json --overwrite   # replace existing services on conflict
```

Treat that JSON file like a loaded weapon: it's your secrets in the clear. Encrypt
it, move it where you need it, and delete it.

### Changing the master password

```sh
lockbox change-password
```

This re-derives a fresh key, mints a new salt, and re-encrypts the entire vault.
Since the old in-memory key no longer matches, it also ends any running session —
just run `lockbox unlock` again afterward.

---

## A realistic daily workflow

```sh
lockbox unlock                       # once in the morning
lockbox get github -p | pbcopy       # grab a password when you need it
lockbox totp github                  # grab the 2FA code
lockbox add some-new-site            # store a new credential
# ...keep working; the session auto-locks after 15 min idle...
lockbox lock                         # or lock manually when you step away
```

---

## Security notes worth remembering

- **Argon2id** key derivation (64 MiB / 3 passes / 4 lanes). Older vaults written
  with 1 pass are transparently upgraded to the stronger parameters the next time
  you unlock them.
- The whole vault is a single **AES-256-GCM** blob; the salt is fixed for the life
  of the vault, and every save uses a fresh nonce.
- The master password is read **without echoing** to the terminal.
- The agent only takes orders from another process running the same `lockbox`
  binary.
- There is **no password recovery**. Forgetting your master password means losing
  the vault — that's the security guarantee, not a missing feature.

One platform caveat: the Unix-domain socket path has an OS length limit (~104
characters on macOS). The default `~/.lockbox/agent.sock` is well within it, but
an unusually long home directory could exceed it.

---

## Wrapping up

lockbox is what a password manager looks like when you strip away everything that
isn't essential: no cloud, no database, no network, no recovery backdoor. Just
strong crypto, a single encrypted file, and a slick in-memory session so you're
not constantly retyping your master password.

If you live in the terminal and want full control over where your secrets live,
it's worth a try:

```sh
lockbox init
lockbox unlock
lockbox add github
```

That's the whole onboarding. Your secrets, your machine, your key.
