Two isolated personal-credential backup options to evaluate, both excluded
from the admin policy (root-only break-glass):
- Scenario A: personal/ KV v2 (versioned) + personal-{put,get,list}.sh
- Scenario B: transit-personal/ key personal-backup + secret-{encrypt,decrypt}.sh
Plus an AppRole example of how a system should consume a secret:
- demo-app role/policy (read-only secret/demo-app/*), short-lived tokens
- scripts/app-get-secret.sh: login (role_id+secret_id) -> token -> read
All tokens/credentials live under ~/.config/openbao (outside the repo).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
20 lines
979 B
Bash
Executable File
20 lines
979 B
Bash
Executable File
#!/usr/bin/env bash
|
|
# Scenario A (structured KV): store a personal credential in the isolated
|
|
# `personal/` KV v2 engine (NOT readable by the day-to-day admin policy).
|
|
# personal-put.sh <name> e.g. personal-put.sh github
|
|
set -euo pipefail
|
|
ADDR="${BAO_ADDR:-http://127.0.0.1:8200}"
|
|
TOKF="$HOME/.config/openbao/personal-kv.token"
|
|
name="${1:?usage: personal-put.sh <name>}"
|
|
[ -r "$TOKF" ] || { echo "no token at $TOKF" >&2; exit 1; }
|
|
|
|
read -rp "username: " u
|
|
read -rsp "password (hidden): " p; echo
|
|
read -rp "url/notes (optional): " n
|
|
|
|
payload="$(U="$u" P="$p" N="$n" python3 -c \
|
|
'import json,os;print(json.dumps({"data":{"username":os.environ["U"],"password":os.environ["P"],"url":os.environ["N"]}}))')"
|
|
code="$(printf '%s' "$payload" | curl -sS -o /dev/null -w '%{http_code}' \
|
|
-H "X-Vault-Token: $(cat "$TOKF")" --data @- "$ADDR/v1/personal/data/$name")"
|
|
case "$code" in 200|204) echo "stored personal/$name (versioned)";; *) echo "FAILED (HTTP $code)"; exit 1;; esac
|