feat(openbao): add baoctl, a session wrapper for running bao commands

This host has no `bao` CLI, only Docker, so every authenticated command is a
`docker compose exec` -- and every obvious way to get a token in there leaks it.
`-e BAO_TOKEN=<value>` puts it in the docker process's argv, which
/proc/<pid>/cmdline exposes to every user on the box. An inline
`BAO_TOKEN=<value> cmd` adds shell history on top.

The stdin trick 0eb7f26 uses cannot be the general answer, and the reason is
capability rather than ergonomics: bao's kvbuilder consumes stdin exactly once,
and the operator needs it for `policy write NAME -`, `write PATH -` (a JSON
body) and `key=-` (a single secret value). Spend stdin on the token and an OIDC
client secret has nowhere left to go but argv, reintroducing the leak that was
just closed. update.sh keeps piping because it runs one unattended command that
needs no stdin of its own; interactive work needs something else.

So baoctl is a SESSION wrapper. `baoctl login` prompts once with echo off --
verified against v2.6.2 that bao reads it through termios and requires a TTY --
and afterwards commands are typed verbatim with stdin free.

Three details that are load-bearing, all source-verified at v2.6.2:

- `bao login` prints the token in its success table. Without -no-print the
  interactive path dumps the root token into the exec session's scrollback,
  which is worse than what it replaces.
- The token you type is not what the session keeps. baoctl immediately mints a
  short-lived child and swaps it in via `bao token create -field=token |
  bao login -no-print -`, so the value never reaches an argv or a stdout, the
  session expires on its own, and logout can revoke it without killing the root
  token. A failed mint discards the login rather than leaving the typed token
  sitting in the session.
- logout both revokes AND removes the file. `bao token revoke -self` does not
  delete it and there is no `bao logout` in 2.6.x, so revoking alone leaves a
  stale file that fails with permission errors instead of "not logged in".

The session lives at /dev/shm/.bao-session in the container, pointed at by
BAO_TOKEN_PATH (new in 2.6.0). /dev/shm is already a per-container tmpfs, so the
token never touches disk and dies with the container -- and arranging that
needed no compose change, which matters because recreating this container means
a seal cycle and three unseal keys typed by a human.

It verifies TLS instead of reaching for -tls-skip-verify: ./tls is already
mounted read-only into the container and the generated cert carries
IP:127.0.0.1 in its SANs, so BAO_CACERT validates against the real listener.
-tls-skip-verify would have been the lazy default and is strictly worse.

Also warns when BAO_TOKEN is set in the caller's shell: baoctl never forwards
it, but an operator who set one will assume it is in play and debug the wrong
credential.

Caught while testing: `--ttl` with no value exited SILENTLY, because `shift 2`
with one argument left fails and set -e takes the script down before the
validation ran. Now the argument count is checked first -- another member of
this repo's set -e trap family.

Verified without a live host: help works with no stack present and touches no
docker; the missing-stack path errors cleanly; all four option-validation paths
report rather than exiting silently; the payload carries baoctl.
Not verified: login, the mint-and-swap and logout against a running vault.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-22 10:12:01 -05:00
co-authored by Claude Opus 5
parent f8022379e5
commit 393223dead
4 changed files with 423 additions and 101 deletions
+35
View File
@@ -173,6 +173,41 @@ ssh -L 8200:<bind-addr>:8200 root@<host>
This is also the better way to do the first `operator init`: the unseal keys and
root token are shown in your browser instead of a root shell's scrollback.
## Running bao commands
The host has no `bao` CLI, only Docker, so every authenticated command is a
`docker compose exec`. Getting a token in there naively leaks it: `-e
BAO_TOKEN=<value>` puts it in the docker process's argv, which
`/proc/<pid>/cmdline` exposes to every user on the box.
`baoctl` is installed alongside the stack for this. It is a **session** wrapper:
one hidden prompt, then your commands are typed verbatim.
```bash
cd /srv/openbao
bash baoctl login # prompts with echo off; nothing is echoed or stored on the host
bash baoctl secrets enable pki
bash baoctl write pki/root/generate/internal common_name="Example Root CA" key_bits=4096
bash baoctl policy write my-policy - < my-policy.hcl
bash baoctl logout
```
The token you type is **not** what the session holds. After login `baoctl` mints
a short-lived child token and swaps it in, so the session expires by itself and
`logout` revokes it without touching your root token. The session lives on the
container's `/dev/shm` (already a tmpfs), so it never reaches disk and dies with
the container.
Why a session rather than piping the token per command: `bao` needs stdin for
`policy write NAME -`, `write PATH -` and `key=-`. Spend stdin on the token and
a secret value like an OIDC client secret has nowhere left to go but argv —
reintroducing the leak. `update.sh` still pipes, because it runs one command
unattended and needs no stdin of its own.
`baoctl` verifies TLS rather than skipping it: `./tls` is mounted into the
container and the generated cert carries `IP:127.0.0.1` in its SANs, so
`BAO_CACERT` validates against the real listener cert.
## Updating
`update.sh` is installed alongside the stack. It is **not** run by `deploy.sh`,
+224
View File
@@ -0,0 +1,224 @@
#!/usr/bin/env bash
#
# baoctl -- run `bao` commands against the containerised vault without leaking
# credentials. Companion to deploy.sh, installed alongside the stack.
#
# The problem it solves: this host has no `bao` CLI, only Docker, so every
# authenticated command is a `docker compose exec`. The obvious ways to get a
# token in there all leak it:
# * `-e BAO_TOKEN=<value>` puts it in the docker process's argv, and
# /proc/<pid>/cmdline is world-readable -- every user on the box can read it.
# * `BAO_TOKEN=<value> some-command` additionally puts it in shell history.
# * piping the token to the container spends STDIN, and bao needs stdin for
# `policy write NAME -`, `write PATH -` (a JSON body) and `key=-` (a single
# secret value). Spend it on the token and an OIDC client secret has nowhere
# left to go but argv -- reintroducing the first leak.
#
# So baoctl is a SESSION wrapper, not a per-command token pump. `baoctl login`
# prompts once with echo off, stores a token inside the container, and every
# later command is typed verbatim with stdin free.
#
# The session token is NOT the one you type. After login, baoctl mints a
# short-lived child token and swaps it in, so what sits in the session expires
# on its own and `logout` can revoke it without touching your root token.
#
# The session lives at /dev/shm/.bao-session inside the container (BAO_TOKEN_PATH
# points bao's own token helper there). /dev/shm is already a per-container
# tmpfs, so the token never touches disk and dies with the container -- and no
# compose change was needed to arrange that, which matters because recreating
# this container means a seal cycle and three unseal keys typed by a human.
#
# Subcommands:
# login [--ttl 8h] [--policy NAME] prompt (hidden), then mint + store a child
# logout [--keep-token] revoke the session token AND remove it
# status seal state, and what the session can do
# <anything else> passed straight to `bao` in the container
#
# Usage:
# bash baoctl login
# bash baoctl write pki/root/generate/internal common_name="Example Root CA" ...
# bash baoctl policy write my-policy - < my-policy.hcl
# bash baoctl status
# bash baoctl logout
#
# Env:
# STACK_DIR=/srv/openbao SESSION_TTL=8h SESSION_POLICY=
set -euo pipefail
: "${STACK_DIR:=/srv/openbao}"
: "${SESSION_TTL:=8h}"
: "${SESSION_POLICY:=}"
# Inside the container. /dev/shm is tmpfs, so the session never hits disk.
TOKEN_PATH="/dev/shm/.bao-session"
ADDR_IN="https://127.0.0.1:8200"
CACERT_IN="/openbao/tls/tls.crt"
log() { printf '\033[1;32m[+]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[!]\033[0m %s\n' "$*" >&2; }
die() { printf '\033[1;31m[x]\033[0m %s\n' "$*" >&2; exit 1; }
# Before the stack check, so --help works anywhere and touches no docker.
case "${1:-}" in
-h|--help|help)
awk '/^set -euo/ { exit } NR > 1 { sub(/^# ?/, ""); print }' "$0"
exit 0 ;;
esac
[[ -d "$STACK_DIR" ]] || die "No stack at $STACK_DIR (set STACK_DIR)."
dc() { ( cd "$STACK_DIR" && docker compose "$@" ); }
# BAO_TOKEN in the environment beats the token file, always. baoctl never passes
# it through -- but if the operator has one set they will assume it is in play,
# and be debugging the wrong credential.
if [[ -n "${BAO_TOKEN:-}" ]]; then
warn "BAO_TOKEN is set in your shell. baoctl ignores it and uses its own session;"
warn "unset it to avoid confusion about which credential is being used."
fi
# Verify TLS properly rather than reaching for -tls-skip-verify: deploy.sh mounts
# ./tls read-only into the container and puts IP:127.0.0.1 in the cert's SANs, so
# pointing BAO_CACERT at it actually validates. Only fall back to skipping when
# the cert genuinely is not there.
bao_env() {
printf '%s\n' "-e" "BAO_ADDR=${ADDR_IN}" "-e" "BAO_TOKEN_PATH=${TOKEN_PATH}"
if [[ -f "$STACK_DIR/tls/tls.crt" ]]; then
printf '%s\n' "-e" "BAO_CACERT=${CACERT_IN}"
else
printf '%s\n' "-e" "BAO_SKIP_VERIFY=true"
fi
}
bao_run() { # bao_run <bao args...>
# Allocate a TTY only when our own stdin is one. An interactive command wants
# one; `baoctl write path - < body.json` must NOT have one, or stdin is not
# forwarded and the payload never arrives.
local -a envs=() tf=()
while IFS= read -r line; do envs+=("$line"); done < <(bao_env)
[[ -t 0 ]] || tf=(-T)
dc exec "${tf[@]}" "${envs[@]}" openbao bao "$@"
}
session_exists() {
local -a envs=()
while IFS= read -r line; do envs+=("$line"); done < <(bao_env)
dc exec -T "${envs[@]}" openbao sh -c '[ -s "$BAO_TOKEN_PATH" ]' >/dev/null 2>&1
}
do_login() {
local ttl="$SESSION_TTL" policy="$SESSION_POLICY"
while [[ $# -gt 0 ]]; do
case "$1" in
# `shift 2` with only one argument left FAILS, and under set -e that
# exits the script silently -- before any validation below runs.
# So check the count first rather than relying on ${2:-}.
--ttl) [[ $# -ge 2 ]] || die "login: --ttl needs a value (e.g. 8h)."
ttl="$2"; shift 2 ;;
--policy) [[ $# -ge 2 ]] || die "login: --policy needs a policy name."
policy="$2"; shift 2 ;;
*) die "login: unknown option '$1' (expected --ttl or --policy)." ;;
esac
done
[[ -n "$ttl" ]] || die "login: --ttl needs a value (e.g. 8h)."
# Checked after option parsing, so a typo'd flag is reported either way.
[[ -t 0 ]] || die "login needs a terminal: bao prompts for the token with echo off, which requires a TTY. Run it from an interactive shell."
local -a envs=()
while IFS= read -r line; do envs+=("$line"); done < <(bao_env)
# Step 1: the interactive login. -no-print is not optional -- without it bao
# prints the token in its success table, dumping whatever you just typed into
# this terminal's scrollback, which is worse than what we are replacing.
log "Logging in (the prompt is hidden; nothing is echoed or stored on the host)..."
dc exec "${envs[@]}" openbao bao login -no-print \
|| die "Login failed. The token was rejected, or the vault is sealed."
# Step 2: swap the token you typed for a short-lived child, so the session
# expires by itself and `logout` can revoke it without killing your root
# token. The child never reaches an argv or a stdout: it goes straight down a
# pipe into `bao login -`, which reads the token from stdin.
log "Minting a ${ttl} session token${policy:+ with policy '${policy}'}..."
if ! dc exec -T "${envs[@]}" openbao sh -c '
ttl="$1"; pol="$2"
if [ -n "$pol" ]; then
bao token create -ttl="$ttl" -policy="$pol" -field=token
else
bao token create -ttl="$ttl" -field=token
fi | bao login -no-print -
' sh "$ttl" "$policy"; then
# Do not leave the typed token sitting in the session: the whole point of
# the swap is that a session is disposable. Clear it and fail.
dc exec -T "${envs[@]}" openbao sh -c 'rm -f "$BAO_TOKEN_PATH"' >/dev/null 2>&1 || true
die "Could not mint a session token; the login has been discarded. If the token you used cannot create child tokens, pass --policy with one it can grant."
fi
log "Session ready. Run commands with: bash $(basename "$0") <bao args...>"
do_status || true
}
do_logout() {
local keep=0
while [[ $# -gt 0 ]]; do
case "$1" in
--keep-token) keep=1; shift ;;
*) die "logout: unknown option '$1'." ;;
esac
done
local -a envs=()
while IFS= read -r line; do envs+=("$line"); done < <(bao_env)
if ! session_exists; then
log "No session to end."
return 0
fi
# Both steps, deliberately. `bao token revoke -self` does not remove the token
# file and there is no `bao logout` in 2.6.x, so revoking alone leaves a stale
# file behind that fails with permission errors instead of "not logged in".
if [[ "$keep" == 0 ]]; then
dc exec -T "${envs[@]}" openbao bao token revoke -self >/dev/null 2>&1 \
|| warn "Could not revoke the session token (already expired?); removing it anyway."
fi
dc exec -T "${envs[@]}" openbao sh -c 'rm -f "$BAO_TOKEN_PATH"' >/dev/null 2>&1 || true
log "Session ended."
}
do_status() {
local -a envs=()
while IFS= read -r line; do envs+=("$line"); done < <(bao_env)
local rc=0
dc exec -T "${envs[@]}" openbao bao status >/dev/null 2>&1 || rc=$?
case "$rc" in
0) printf ' vault: unsealed\n' ;;
2) printf ' vault: SEALED (unseal before anything else works)\n' ;;
*) printf ' vault: unreachable (bao status rc=%s)\n' "$rc" ;;
esac
if ! session_exists; then
printf ' session: none -- run `%s login`\n' "$(basename "$0")"
return 0
fi
printf ' session: present at %s (in-container tmpfs)\n' "$TOKEN_PATH"
dc exec -T "${envs[@]}" openbao bao token lookup -format=json 2>/dev/null \
| awk -F'"' '
/"display_name"/ { printf " name: %s\n", $4 }
/"ttl"/ { gsub(/[^0-9]/, "", $0); if ($0 != "") printf " ttl: %ss\n", $0 }
' || warn "Session token present but lookup failed; it may have expired. Run logout, then login."
}
case "${1:-status}" in
login) shift; do_login "$@" ;;
logout) shift; do_logout "$@" ;;
status) shift; do_status "$@" ;;
*)
# Everything else is a bao command. Requiring a session first gives a
# clear error instead of bao's "missing client token".
session_exists || die "No session. Run: bash $(basename "$0") login"
bao_run "$@"
;;
esac
+2 -2
View File
@@ -11,11 +11,11 @@ SCRIPT="$DIR/deploy.sh"
MARKER="__ARCHIVE_BELOW__"
[[ -f "$SCRIPT" ]] || { echo "deploy.sh not found at $SCRIPT" >&2; exit 1; }
for f in docker-compose.yml config.hcl gen-tls.sh update.sh .env.example; do
for f in docker-compose.yml config.hcl gen-tls.sh update.sh baoctl .env.example; do
[[ -f "$DIR/$f" ]] || { echo "Missing $DIR/$f" >&2; exit 1; }
done
PAYLOAD=$(tar -czf - -C "$DIR" docker-compose.yml config.hcl gen-tls.sh update.sh .env.example | base64)
PAYLOAD=$(tar -czf - -C "$DIR" docker-compose.yml config.hcl gen-tls.sh update.sh baoctl .env.example | base64)
TMP=$(mktemp)
trap 'rm -f "$TMP"' EXIT
+162 -99
View File
@@ -5,7 +5,8 @@
#
# What this does:
# 1. Installs docker + compose if missing.
# 2. Lays down docker-compose.yml, config.hcl, gen-tls.sh, update.sh in $STACK_DIR.
# 2. Lays down docker-compose.yml, config.hcl, gen-tls.sh, update.sh, baoctl
# in $STACK_DIR.
# 3. Seeds .env on first run (OPENBAO_ADDR into the cert SAN); never
# overwrites an existing .env.
# 4. Generates a self-signed TLS cert (if ./tls is empty) -- drop a CA-signed
@@ -16,7 +17,7 @@
#
# Idempotent: re-run to apply config changes / pull new images.
#
# Self-contained: docker-compose.yml, config.hcl, gen-tls.sh, update.sh, .env.example are
# Self-contained: docker-compose.yml, config.hcl, gen-tls.sh, update.sh, baoctl and .env.example are
# embedded as a base64 tar.gz at the bottom. Rebuild with build.sh after edits.
#
# Usage:
@@ -199,7 +200,7 @@ extract_archive
# Fallback: run straight from the source dir (before build.sh embeds a payload).
if [[ ! -f "$SCRIPT_DIR/docker-compose.yml" ]]; then
SRC=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
for f in docker-compose.yml config.hcl gen-tls.sh update.sh .env.example; do
for f in docker-compose.yml config.hcl gen-tls.sh update.sh baoctl .env.example; do
[[ -f "$SRC/$f" ]] || die "Missing $f (no embedded payload and not in $SRC -- run build.sh)."
cp "$SRC/$f" "$SCRIPT_DIR/$f"
done
@@ -321,6 +322,8 @@ install -m 0750 "$SCRIPT_DIR/gen-tls.sh" "$STACK_DIR/gen-tls.sh"
# The updater. Deliberately NOT run by deploy.sh: upgrading a live vault seals
# it, so it is an operator-invoked step rather than part of a deploy.
install -m 0750 "$SCRIPT_DIR/update.sh" "$STACK_DIR/update.sh"
# baoctl: run bao commands without a token ever reaching an argv or history.
install -m 0750 "$SCRIPT_DIR/baoctl" "$STACK_DIR/baoctl"
ENV_FILE="$STACK_DIR/.env"
set_env() { # <KEY> <value>: update KEY in .env, or append if absent
@@ -514,6 +517,9 @@ TLS: ${STACK_DIR}/tls/tls.crt (give this to the Kanrisha daemon as
process's argv, and /proc/<pid>/cmdline is world-readable.
Manage (run these from ${STACK_DIR}):
bash baoctl login # one hidden prompt, then a session
bash baoctl <bao args...> # e.g. bash baoctl secrets enable pki
bash baoctl logout # revoke + remove the session
bash update.sh check # declared/running/latest + seal state
bash update.sh update # snapshot, then upgrade (comes back SEALED)
docker compose logs -f
@@ -632,99 +638,156 @@ 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
bgCgAAA=
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
vW6v2+v2ur1urz/49T94yipqAMgAAA==