Vaultwarden secrets + live seed import (5 review concerns addressed) #67

Merged
clawdie merged 2 commits from feat/vault-seed-fetch-fixed into main 2026-06-19 18:36:38 +02:00
Owner

What

Vaultwarden fetch + per-agent live seed import, with the 5 review concerns from the earlier audit addressed. Brings the secrets-out-of-the-box feature onto current main (it had only existed on an unmerged feature branch).

Includes

  • clawdie-vault-fetch — language-neutral bw bridge. Reads a 0600 ~/.config/vault-bootstrap.env, pulls secrets by item name (bw get password, no jq), prints KEY=VALUE or --write-env upserts 0600. Exit codes: 0 ok / 1 broken / 3 no bootstrap (skip) / 4 no bw.
  • clawdie-live-seed — extends the CLAWDIESEED FAT32 importer from an authorized_keys allowlist to a per-agent directory convention (env, harness.toml, soul/, ssh/authorized_keys). Live USB activates the first agent dir; extras stage only.
  • build.sh + packages/npm-globals.txt — stage clawdie-vault-fetch and pin @bitwarden/cli@2026.5.0 for offline bundling.

The 5 review concerns, addressed

  1. Seed ↔ fetch path alignment_seed_split_env routes BW_* out of .env into ~/.config/vault-bootstrap.env (SEED_VAULT_BOOTSTRAP_REL), the path clawdie-vault-fetch actually reads. "Seed bootstrap → fetch out of the box" now lines up without an explicit --bootstrap arg.
  2. Unused COLLECTION_ID dropped — items fetched by name via bw get password, fail-closed on ambiguity. Documented that item names must be unique in the visible vault.
  3. Agent dir validation_seed_agent_name_ok rejects leading-dot dirs (.Spotlight-V100, .fseventsd); _seed_agent_has_payload requires a recognized payload so an empty/stray dir can't become active.
  4. No phantom homes — extra agent dirs stage under /var/db/clawdie/seed/<agent> only; _seed_stage_agent never writes a home or SSH keys.
  5. Bootstrap file mode enforcementclawdie-vault-fetch now stat-checks the bootstrap file and refuses group/world-readable unless VAULT_ALLOW_INSECURE_BOOTSTRAP is set.

Security note

Plaintext secrets on the seed is an operator decision — seeded sticks are secret-bearing media. Mitigations: 0600 landing files, optional /shred consume-and-wred, bootstrap-mode enforcement.

Checks

sh -n live/operator-session/clawdie-vault-fetch
sh -n live/operator-session/clawdie-live-seed
sh -n build.sh
git diff --check
./scripts/check-format.sh        # prettier clean

Companion

Land with clawdie-ai fix/vault-fetch-contract-docs — it rewrites VAULTWARDEN-SETUP.md to document the name-based retrieval contract this helper implements. They should merge together so the contract stays consistent across repos.

Not yet wired (intentional follow-ups)

  • Runtime consumption (soul load + harness launch): seed stages under /var/db/clawdie/seed/<agent>; nothing reads it back into a live agent workspace yet.
  • Vault postinstall auto-caller: the helper exists but no firstboot/postinstall hook invokes it automatically yet.

Co-Authored-By: Hermes & Sam <hello@clawdie.si>

## What Vaultwarden fetch + per-agent live seed import, with the 5 review concerns from the earlier audit addressed. Brings the `secrets-out-of-the-box` feature onto current `main` (it had only existed on an unmerged feature branch). ## Includes - `clawdie-vault-fetch` — language-neutral `bw` bridge. Reads a 0600 `~/.config/vault-bootstrap.env`, pulls secrets by item **name** (`bw get password`, no `jq`), prints `KEY=VALUE` or `--write-env` upserts 0600. Exit codes: `0` ok / `1` broken / `3` no bootstrap (skip) / `4` no `bw`. - `clawdie-live-seed` — extends the `CLAWDIESEED` FAT32 importer from an `authorized_keys` allowlist to a per-agent directory convention (`env`, `harness.toml`, `soul/`, `ssh/authorized_keys`). Live USB activates the first agent dir; extras stage only. - `build.sh` + `packages/npm-globals.txt` — stage `clawdie-vault-fetch` and pin `@bitwarden/cli@2026.5.0` for offline bundling. ## The 5 review concerns, addressed 1. **Seed ↔ fetch path alignment** — `_seed_split_env` routes `BW_*` out of `.env` into `~/.config/vault-bootstrap.env` (`SEED_VAULT_BOOTSTRAP_REL`), the path `clawdie-vault-fetch` actually reads. "Seed bootstrap → fetch out of the box" now lines up without an explicit `--bootstrap` arg. 2. **Unused `COLLECTION_ID` dropped** — items fetched by name via `bw get password`, fail-closed on ambiguity. Documented that item names must be unique in the visible vault. 3. **Agent dir validation** — `_seed_agent_name_ok` rejects leading-dot dirs (`.Spotlight-V100`, `.fseventsd`); `_seed_agent_has_payload` requires a recognized payload so an empty/stray dir can't become active. 4. **No phantom homes** — extra agent dirs stage under `/var/db/clawdie/seed/<agent>` only; `_seed_stage_agent` never writes a home or SSH keys. 5. **Bootstrap file mode enforcement** — `clawdie-vault-fetch` now `stat`-checks the bootstrap file and refuses group/world-readable unless `VAULT_ALLOW_INSECURE_BOOTSTRAP` is set. ## Security note Plaintext secrets on the seed is an **operator decision** — seeded sticks are secret-bearing media. Mitigations: 0600 landing files, optional `/shred` consume-and-wred, bootstrap-mode enforcement. ## Checks ```sh sh -n live/operator-session/clawdie-vault-fetch sh -n live/operator-session/clawdie-live-seed sh -n build.sh git diff --check ./scripts/check-format.sh # prettier clean ``` ## Companion Land with **clawdie-ai `fix/vault-fetch-contract-docs`** — it rewrites `VAULTWARDEN-SETUP.md` to document the name-based retrieval contract this helper implements. They should merge together so the contract stays consistent across repos. ## Not yet wired (intentional follow-ups) - Runtime consumption (soul load + harness launch): seed stages under `/var/db/clawdie/seed/<agent>`; nothing reads it back into a live agent workspace yet. - Vault postinstall auto-caller: the helper exists but no firstboot/postinstall hook invokes it automatically yet. Co-Authored-By: Hermes & Sam &lt;hello@clawdie.si&gt;
clawdie added 2 commits 2026-06-19 18:30:22 +02:00
Two parallel, additive paths so a host gets its secrets out of the box;
the manual setup wizard stays the floor (no config = no-op).

clawdie-vault-fetch (new): language-neutral bw bridge. Reads a 0600
~/.config/vault-bootstrap.env, pulls keys from the agent-secrets
collection (item name = env var name, value in password field, so no jq),
prints KEY=VALUE or --write-env upserts 0600. Exit codes distinguish
skip (3, no bootstrap) / broken (1) / no bw (4). Pinned
@bitwarden/cli@2026.5.0 for offline bundling; staged in
configure_live_operator_session.

clawdie-live-seed: extend the CLAWDIESEED FAT32 importer from the
authorized_keys allowlist to a per-agent directory convention —
/<agent>/ with env (merged 0600), harness.toml (pi|zot|local), soul/
(staged), ssh/authorized_keys. Live USB single-agent (first dir = active);
extra dirs staged + flagged for deployed multi-agent. Optional
consume-and-shred. Import core is unit-testable via CLAWDIE_SEED_TEST.

README rewritten to document the per-agent contract and the operator
decision to allow plaintext secrets on the seed (seeded sticks are
secret-bearing media; 0600 landing + shred mitigations).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address the 5 review concerns on the secrets-out-of-the-box feature:

1. Seed↔fetch path alignment: _seed_split_env routes BW_* creds out of .env
   into ~/.config/vault-bootstrap.env (SEED_VAULT_BOOTSTRAP_REL), the path
   clawdie-vault-fetch actually reads — so 'seed bootstrap → fetch out of
   the box' now lines up without an explicit --bootstrap arg.
2. Drop unused COLLECTION_ID from clawdie-vault-fetch. Items are fetched by
   name via 'bw get password', which is fail-closed on ambiguity; document
   that item names must be unique in the visible vault.
3. Agent dir validation: _seed_agent_name_ok rejects leading-dot dirs
   (.Spotlight-V100, .fseventsd) and traversal; _seed_agent_has_payload
   requires a recognized payload so an empty/stray dir can't become active.
4. No phantom homes: extra agent dirs stage under /var/db/clawdie/seed/<agent>
   only — _seed_stage_agent never writes a home or SSH keys.
5. Bootstrap file mode enforcement: clawdie-vault-fetch now stat-checks the
   bootstrap file and refuses group/world-readable unless
   VAULT_ALLOW_INSECURE_BOOTSTRAP is set.

Also renames _seed_import_env → _seed_merge_env + _seed_split_env and adds
_seed_key_ok to guard env var names.

Checks: sh -n on vault-fetch/live-seed/build.sh; git diff --check;
./scripts/check-format.sh (prettier clean); 5 concerns verified present.

Co-Authored-By: Hermes & Sam <hello@clawdie.si>
clawdie merged commit 761c9cf9bf into main 2026-06-19 18:36:38 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: clawdie/clawdie-iso#67
No description provided.