diff --git a/docs/VAULTWARDEN-SETUP.md b/docs/VAULTWARDEN-SETUP.md index 75fca1c..d2cb1e9 100644 --- a/docs/VAULTWARDEN-SETUP.md +++ b/docs/VAULTWARDEN-SETUP.md @@ -24,11 +24,13 @@ access Vaultwarden, but those credentials can't be stored in Vaultwarden itself as the only copy. **Operator's role:** + 1. Create a Vaultwarden user account for the agent. 2. Invite the user to the Clawdie organization with access to `agent-secrets`. 3. Share the master password via a secure channel (file drop, not chat). **Agent's role:** + 1. Generate personal API key: Account Settings → Security → Keys → View API Key. 2. Write `BW_CLIENTID` (starts with `user.`), `BW_CLIENTSECRET`, and `BW_PASSWORD` to a 0600 bootstrap file: `~/.config/vault-bootstrap.env`. @@ -88,6 +90,7 @@ bw config server https://vault.smilepowered.org Generate your personal API key: Account Settings → Security → Keys → View API Key. You'll receive: + - `BW_CLIENTID` (starts with `user.`) - `BW_CLIENTSECRET` @@ -132,10 +135,64 @@ bw get item --session "$BW_SESSION" bw lock ``` +## Runtime fetch: `clawdie-vault-fetch` + +The manual flow above is the operator/agent CLI path. For a host to pull its own +provider keys **out of the box**, the image ships a small language-neutral +helper, `clawdie-vault-fetch` (`/usr/local/bin/`), that the post-install setup +flow shells out to and the live USB can run directly. It depends only on `bw` — +no node module, no `jq`. + +### Item-naming convention (the contract) + +For a secret to be auto-fetchable, store it in `agent-secrets` as a **login item +whose name is exactly the env var name**, with the value in the **password +field**: + +| Item name | Field | Becomes | +| -------------------- | -------- | ---------------------- | +| `ANTHROPIC_API_KEY` | password | `ANTHROPIC_API_KEY=…` | +| `OPENAI_API_KEY` | password | `OPENAI_API_KEY=…` | +| `OPENROUTER_API_KEY` | password | `OPENROUTER_API_KEY=…` | +| `ZAI_API_KEY` | password | `ZAI_API_KEY=…` | + +The default key set mirrors clawdie-ai's `PROVIDER_KEY_BY_PROVIDER` (anthropic, +openai, openrouter, zai, deepseek, gemini, groq). `bw get password ` +returns the raw value, so no JSON parsing is involved. + +### Bootstrap drop (the one secret that can't live in the vault) + +The helper reads `~/.config/vault-bootstrap.env` (mode 0600) for the headless +credentials — exactly the file from the [Bootstrap Flow](#bootstrap-flow) above: + +```sh +BW_CLIENTID=user.... +BW_CLIENTSECRET=... +BW_PASSWORD= +``` + +**No bootstrap file → the helper exits cleanly and does nothing**, so a host with +no vault access still uses the manual setup wizard. That is the floor; the vault +fetch only ever adds. + +### Usage + +```sh +clawdie-vault-fetch # print KEY=VALUE lines to stdout +clawdie-vault-fetch --write-env FILE # upsert results into FILE (0600), keys preserved +clawdie-vault-fetch --bootstrap FILE # explicit bootstrap env file +clawdie-vault-fetch --keys "A B C" # override the key-name list +``` + +Exit codes let a caller tell "skip" from "broken": `0` ran cleanly · `1` vault +configured but login/unlock/fetch failed · `3` no bootstrap config (fall back to +manual) · `4` `bw` not installed. The helper always `bw lock`s on exit and never +logs secret values. + ## Current items in agent-secrets -| Name | Type | Purpose | -|------|------|---------| +| Name | Type | Purpose | +| -------------------- | ----- | -------------------------------------------------------- | | hermes-debby Forgejo | login | Hermes's code.smilepowered.org password (browser access) | ## Rules