vault + teams: filter secrets by category, export to CSV, simpler help (#195)

Every secret now has a category derived from its name (db, social, server,
api, cloud, finance, crypto, ai, email, messaging, storage, dns, analytics,
devtools, auth, config, other). One rule table in @logicsrc/opencreds serves
both vaults; services win over generic words, so STRIPE_WEBHOOK_SECRET is
finance, not auth. Checked against the 1,208 distinct key names in the
profullstack team: 74 fall to "other".

Team vaults (where the shared .env secrets live):
- teams categories [team]    the filter words, with per-category counts
- teams secrets <team> [project] [env] --category/-c --search/-s
                             names + categories, never decrypts; --format csv
- teams export  <team> [project] [env] --category -o file.csv [--yes]
                             decrypts into team,project,env,category,key,
                             value,updated_at (0600); skips vaults without a
                             grant and names them

Personal vault (OpenCreds):
- vault list --category, and the category column in list output
- vault export --format csv: one flat row per item, keeps key/account
  secrets that a Bitwarden CSV drops; --category on every export format

DX:
- examples in `logicsrc vault help` / -h / --help that start by saying which
  of the two vaults you want, plus examples on teams and each subcommand
- password prompts go to stderr, so eval "$(logicsrc vault unlock)" works
- hints name the command you actually ran (logicsrc vault init, not
  opencreds init)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Anthony Ettinger 2026-09-23 21:08:08 -07:00 • committed by GitHub
parent 156c9164a9
commit 3d155af970
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 846 additions and 19 deletions

View file

@ -56,7 +56,7 @@ why it is instant on a vault of any size.
```bash
opencreds add <type> --name <name> [type flags…]
opencreds list [--type <type>] [--folder <name>] [--search <text>] [--json]
opencreds list [--type <type>] [--category <names>] [--folder <name>] [--search <text>] [--json]
opencreds get <id|name> [--field <path>] [--reveal]
opencreds edit <id|name> [flags…]
opencreds rm <id|name> [--purge]
@ -68,6 +68,13 @@ with every secret field masked; `--reveal` prints one field named by `--field`,
so revealing is always a deliberate act naming a single value. `--json` output is
masked identically — a pipeline is not an authorization.
`list` prints one line per item: short id, type, category, name. The category
(`db`, `social`, `server`, `api`, `finance`, … and `other`) is derived from the
item type, name, account provider and login hosts, and is never stored, so it
cannot disagree between implementations that share the rule table.
`--category db,social` filters on it and accepts aliases (`database`,
`payments`); an unknown word exits 1 and names the valid ones.
Type flags follow the field group names, kebab-cased:
`--username`, `--password`, `--totp`, `--url`,
`--cardholder-name`, `--number`, `--exp-month`, `--exp-year`, `--code`,
@ -83,7 +90,9 @@ secret need not appear in the shell history or the process list.
```bash
opencreds export [--out vault.opencreds] [--passphrase-stdin]
opencreds export --plaintext --out vault.json --yes
opencreds export --format csv --out vault.csv --yes
opencreds export --format bitwarden-csv --out vault.csv --yes
opencreds export --format csv --category db --out db.csv --yes
opencreds import <file> [--dry-run] [--merge skip|replace|duplicate]
opencreds import <file> --source bitwarden|onepassword|chrome|lastpass|keepass
@ -92,6 +101,13 @@ opencreds import <file> --source bitwarden|onepassword|chrome|lastpass|keepass
`export` writes the encrypted form. `--plaintext` prints what it is about to do
and exits 4 without `--yes`.
`--format csv` writes one flat row per item —
`folder,category,type,name,username,password,url,value,totp,notes` — where
`value` is the single opaque secret of a key, account or card. It keeps the key
and account items a Bitwarden CSV has no column for, and is meant for people and
scripts, not re-import. `--format bitwarden-csv` is the one to hand another
password manager. `--category` limits any export format to those categories.
`import` with `--dry-run` reports counts by type, folders to be created,
duplicates detected and rows that could not be mapped, and writes nothing. A
manifest mismatch exits 3 and writes nothing regardless of flags.