vault provision: daemon needs login→unlock→fetch→lock per call (no standing session) #89
Labels
No labels
first-proof blocker
hardening
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: clawdie/colibri#89
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
colibri-vault::provision()assumes the caller already holds an unlocked vault session (BW_SESSION), but the caller is now the long-runningcolibri-daemon, which has none (bw status = unauthenticated). So provisioning can't authenticate today — and the only way to make a standing session work would be to keep the daemon's vault unlocked indefinitely, which is a security smell and conflicts with the host-holds-bootstrap invariant.The proven shell helper (
clawdie-vault-fetch) did this correctly:login --apikey → unlock --passwordenv → fetch → lockper run, with atrapthat locks on every exit.Fix (recommended)
Mirror the shell helper inside the crate (or the hook): per provision call —
bw config server+bw login --apikey(tolerate already-logged-in)bw unlock --raw --passwordenvto get a short-lived sessionbw lockon completion (incl. error paths)Read bootstrap creds (
BW_CLIENTID/BW_CLIENTSECRET/BW_PASSWORD) from the daemon's provider env file. Never hold a standing unlocked session.Acceptance
The daemon provisions a tenant with no pre-existing session, and the vault is left locked afterward (verify
bw status). Bootstrap creds stay host-side; only the resolved.enventers the jail.See docs/HIVE-ONBOARDING.md (layered-soul) — "security invariant".
🤖 Generated with Claude Code
Trade-offs for the fix
Option A — unlock-per-call (
login→unlock→fetch→lockeach provision; mirrors the proven shell helper)bwis process-global → concurrent provisions race, needs a mutex.Option B — standing session (unlock once at startup, hold
BW_SESSION)Option C — org service-account / scoped API key (no master password; the design doc's "operator's one key")
Recommendation: A + serialization mutex for the MVP (proven, least-exposure at-rest). Treat C as the destination once multi-tenant is real and you want the master password off the host. Avoid B.
🤖 Generated with Claude Code
Resolved by #94 (
fix(vault): use tenant collection names with per-call unlock) — verified: tenant id is now passed as the Vaultwarden collection name (#88), andcolibri-vaultdoes per-call login→unlock→fetch→lock from the daemon's provider env, locking on both success and error paths (#89). Closing.🤖 Generated with Claude Code