vault: distinguish Vaultwarden vs HashiCorp Vault, add vault kv
`homelab vault` only spoke to Vaultwarden (the password manager), but the name reads as HashiCorp Vault (the infra secrets store — actually OpenBao here). Make the two unmistakable and support both. Distinction (no breakage — the existing Vaultwarden verbs are unchanged): - bare `homelab vault` help now LEADS with the two-stores split; - every verb summary is tagged `[vaultwarden]` or `[hashicorp-vault]`; - HashiCorp Vault/OpenBao lives under a clearly-named `vault kv` group. New `vault kv` (HashiCorp Vault / OpenBao, the secret/… KV store): - `kv get <path> [--field K]` — read; --field → one value (TTY-aware clipboard/stdout), no field → full secret JSON (refuses a bare TTY). - `kv list <path>` — list sub-paths (no values). - `kv put <path> <key>` — write one key; value via stdin (piped or no-echo prompt, never argv); creates the path or merges (never clobbers siblings; uses kv patch -method=rw so no `patch` cap needed). Critical: `kv` uses the caller's OWN Vault token (OIDC ~/.vault-token / $VAULT_TOKEN), NOT the per-user scoped Vaultwarden token (bound only to claude-users/<user>, which would 403 elsewhere) — handlers set VAULT_ADDR but never inject the scoped token. Access is whatever the policy grants. Logic in cmd_vault_kv.go (pure cores extractKVData/parseKVList/arg builders/kvGet/List/Put; file header documents the credential split). CLI v0.11.0. Tests: no value in put argv, create-then-merge, KV-v2 envelope strip, help names both systems. Verified e2e against live Vault (read key-names-only + a scratch put/merge/cleanup). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a1cf7ccaf6
commit
e03e4719ad
6 changed files with 492 additions and 21 deletions
|
|
@ -18,31 +18,41 @@ import (
|
|||
// decryption is done by the official `bw` CLI. See
|
||||
// docs/runbooks/homelab-vault-onboarding.md.
|
||||
func vaultCommands() []Command {
|
||||
return []Command{
|
||||
cmds := []Command{
|
||||
// Vaultwarden — your personal password manager (logins/passwords/TOTP).
|
||||
{Path: []string{"vault", "setup"}, Tier: TierWrite,
|
||||
Summary: "one-time: store your Vaultwarden master password + API key in your Vault path", Run: vaultSetup},
|
||||
Summary: "[vaultwarden] one-time: store your master password + API key in your Vault path", Run: vaultSetup},
|
||||
{Path: []string{"vault", "status"}, Tier: TierRead,
|
||||
Summary: "show whether your vault is configured/reachable (no secrets)", Run: vaultStatus},
|
||||
Summary: "[vaultwarden] show whether your vault is configured/reachable (no secrets)", Run: vaultStatus},
|
||||
{Path: []string{"vault", "list"}, Tier: TierRead,
|
||||
Summary: "list your item names: vault list [--search Q]", Run: vaultList},
|
||||
Summary: "[vaultwarden] list your item names: vault list [--search Q]", Run: vaultList},
|
||||
{Path: []string{"vault", "get"}, Tier: TierRead,
|
||||
Summary: "fetch one item: vault get <name> [--field password|username|uri|notes|totp] [--json] [--all]", Run: vaultGet},
|
||||
Summary: "[vaultwarden] fetch one login: vault get <name> [--field password|username|uri|notes|totp] [--json] [--all]", Run: vaultGet},
|
||||
{Path: []string{"vault", "search"}, Tier: TierRead,
|
||||
Summary: "search your item names: vault search <query>", Run: vaultSearch},
|
||||
Summary: "[vaultwarden] search your item names: vault search <query>", Run: vaultSearch},
|
||||
{Path: []string{"vault", "code"}, Tier: TierRead,
|
||||
Summary: "current TOTP code for an item: vault code <name>", Run: vaultCode},
|
||||
Summary: "[vaultwarden] current TOTP code for an item: vault code <name>", Run: vaultCode},
|
||||
{Path: []string{"vault", "lock"}, Tier: TierWrite,
|
||||
Summary: "lock/log out the local bw session", Run: vaultLock},
|
||||
Summary: "[vaultwarden] lock/log out the local bw session", Run: vaultLock},
|
||||
{Path: []string{"vault"}, Tier: TierRead,
|
||||
Summary: "Vaultwarden access for your own vault (run `homelab vault` for help)",
|
||||
Summary: "two stores: Vaultwarden (logins) + HashiCorp Vault/OpenBao kv (infra secrets) — run `homelab vault` for help",
|
||||
Run: func([]string) error { fmt.Print(vaultHelp()); return nil }},
|
||||
}
|
||||
// HashiCorp Vault / OpenBao — homelab INFRA secrets (the secret/… KV store).
|
||||
return append(cmds, vaultKVCommands()...)
|
||||
}
|
||||
|
||||
// vaultHelp is shown for bare `homelab vault`.
|
||||
// vaultHelp is shown for bare `homelab vault`. It LEADS with the distinction
|
||||
// between the two unrelated "vaults" this command fronts, because the name
|
||||
// collides: Vaultwarden (a password manager) vs HashiCorp Vault / OpenBao (the
|
||||
// infra secrets store).
|
||||
func vaultHelp() string {
|
||||
return `homelab vault — read YOUR OWN Vaultwarden logins (no-HITL after one-time setup)
|
||||
return `homelab vault — two different secret stores under one command:
|
||||
|
||||
• Vaultwarden your personal PASSWORD MANAGER (logins / passwords / TOTP)
|
||||
• HashiCorp Vault / OpenBao homelab INFRA secrets (the secret/… KV store) → 'vault kv …'
|
||||
|
||||
── Vaultwarden (reads YOUR OWN vault; no-HITL after one-time setup) ──
|
||||
homelab vault setup one-time: store your master password + API key in your Vault path
|
||||
homelab vault status configured / unlocked / reachable (no secrets)
|
||||
homelab vault list [--search Q] list your item names (no secrets)
|
||||
|
|
@ -53,8 +63,13 @@ func vaultHelp() string {
|
|||
homelab vault code <name> current TOTP code
|
||||
homelab vault lock lock / log out the local bw session
|
||||
|
||||
Creds live only in your own Vault path; the admin never sees them. Identity is
|
||||
your unix UID. Security model: docs/runbooks/homelab-vault-onboarding.md
|
||||
── HashiCorp Vault / OpenBao (infra secrets; uses your own OIDC vault token) ──
|
||||
homelab vault kv get <path> [--field K] read an infra KV secret
|
||||
homelab vault kv list <path> list sub-paths
|
||||
homelab vault kv put <path> <key> write one key (value via stdin)
|
||||
|
||||
Vaultwarden creds live only in your own Vault path; the admin never sees them.
|
||||
Security model: docs/runbooks/homelab-vault-onboarding.md
|
||||
(note: anything running as your user can decrypt your vault — the accepted no-HITL trade).
|
||||
`
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue