homelab vault: self-default VAULT_ADDR + prefer scoped token over ~/.vault-token
Setting up emo's Bitwarden access via `homelab vault`, his one-time `homelab vault setup` failed with an opaque "exit status 2". Two latent CLI bugs, both of which any non-admin AFK invocation can hit: 1. The CLI set VAULT_TOKEN but never VAULT_ADDR, relying on the ambient value. It IS in /etc/environment (login shells), but emo runs his agents from long-lived tmux / non-login shells that never sourced it, so every `vault` child hit the 127.0.0.1:8200 default -> connection refused. claude-auth-sync already self-defaults VAULT_ADDR; the CLI now does the same. 2. Token precedence was env > ~/.vault-token > scoped. A power-user who ran `vault login -method=oidc` carries a read-only ~/.vault-token (policy `default`, capability `deny` on their workstation path), which shadowed the purpose-built scoped token -> 403 permission denied on the user's OWN path. This tool only ever touches secret/workstation/claude-users/<user>, which the scoped token covers exactly, so precedence is now env > scoped > ~/.vault-token. Verified the scoped tokens for both emo and wizard hold create/read/update on their own paths, so admins are unaffected. Also stop swallowing the shelled `vault`/`bw` stderr: errors now carry the real message (connection refused / permission denied) instead of a bare "exit status N" — without that, (1) and (2) were indistinguishable. Verified end-to-end as emo (VAULT_ADDR unset + his read-only ~/.vault-token present): writeCreds now succeeds. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c70810a51b
commit
0525f0b12d
3 changed files with 199 additions and 23 deletions
|
|
@ -23,18 +23,28 @@ homelab vault lock lock / log out the local bw session
|
|||
`homelab vault` runs `vault` as the calling user. It resolves a Vault token in
|
||||
this order (`ensureVaultToken`, `cli/cmd_vault.go`):
|
||||
|
||||
1. an explicit `$VAULT_TOKEN`, then
|
||||
2. a native `~/.vault-token` (what admins carry), then
|
||||
3. the per-user **scoped token** that `claude-auth-sync` maintains at
|
||||
`~/.config/claude-auth-sync/vault-token` (policy `workstation-claude-<user>`).
|
||||
1. an explicit `$VAULT_TOKEN` (a deliberate override), then
|
||||
2. the per-user **scoped token** that `claude-auth-sync` maintains at
|
||||
`~/.config/claude-auth-sync/vault-token` (policy `workstation-claude-<user>`), then
|
||||
3. a native `~/.vault-token` (admins who carry one; non-admins usually don't).
|
||||
|
||||
**The scoped token deliberately beats `~/.vault-token`.** This tool only touches
|
||||
your own `secret/workstation/claude-users/<user>` path, and a power-user who ran
|
||||
`vault login -method=oidc` carries a read-only `~/.vault-token` (capability
|
||||
`deny` on that path); letting it win would shadow the scoped token and fail every
|
||||
op with `403 permission denied` (this is exactly what bit emo, 2026-06-28). The
|
||||
CLI also **self-defaults `VAULT_ADDR`** to `https://vault.viktorbarzin.me` when
|
||||
unset, so it works from non-login shells (tmux panes, AFK agent subprocesses)
|
||||
that never sourced `/etc/environment` — otherwise every `vault` child hits the
|
||||
`127.0.0.1:8200` default and fails `connection refused` (exit 2).
|
||||
|
||||
That scoped policy grants exactly `create`/`read`/`update` on the user's own
|
||||
`secret/workstation/claude-users/<user>` path — no `patch` capability — so the
|
||||
tool writes with `vault kv patch -method=rw` (read-modify-write), falling back to
|
||||
`kv put` only when the path does not exist yet. This preserves the
|
||||
`claude_ai_oauth_json` key that [claude-auth-sync](claude-auth-renew-workstation.md)
|
||||
co-locates there. (Both bugs that previously made this admin-only were fixed
|
||||
2026-06-27.)
|
||||
co-locates there. (The admin-only bugs were fixed 2026-06-27; the
|
||||
`VAULT_ADDR`/token-precedence bugs above were fixed 2026-06-28.)
|
||||
|
||||
## Prerequisites (per user)
|
||||
|
||||
|
|
@ -119,3 +129,20 @@ VAULT_TOKEN="$(sudo cat /home/<user>/.config/claude-auth-sync/vault-token)" \
|
|||
sudo -u <user> -i bw --version # /usr/bin/bw resolves for the user
|
||||
sudo -u <user> -i homelab vault status
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**`homelab vault setup` (or any verb) fails with `exit status 2`** — older
|
||||
binaries swallowed the underlying `vault` error; the message now includes it.
|
||||
Two historical causes (both fixed in-CLI 2026-06-28, kept here for diagnosis):
|
||||
|
||||
- `... connection refused` to `127.0.0.1:8200` → `VAULT_ADDR` wasn't set in the
|
||||
caller's shell. The CLI now self-defaults it, but if you see this on an old
|
||||
binary: `export VAULT_ADDR=https://vault.viktorbarzin.me`.
|
||||
- `403 permission denied` on `PUT .../secret/data/workstation/claude-users/<user>`
|
||||
→ a stale read-only `~/.vault-token` (e.g. from `vault login -method=oidc`,
|
||||
policy `default`, capability `deny` on that path) was shadowing the scoped
|
||||
token. The CLI now prefers the scoped token; on an old binary, `rm
|
||||
~/.vault-token` (or `unset VAULT_TOKEN`) and retry. Confirm with
|
||||
`VAULT_TOKEN="$(sudo cat /home/<user>/.config/claude-auth-sync/vault-token)" vault token capabilities secret/data/workstation/claude-users/<user>`
|
||||
→ must be `create, read, update`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue