Renew the transit seal token so auto-unseal survives a reboot
The main node's transit seal token (config/seal.hcl) lives on the unsealer and was never renewed. It lapsed, and after the 2026-09-17 reboot main crash-looped with 403 on transit/encrypt/autounseal even once the unsealer was unsealed. renew-app-tokens.sh now parses it out of seal.hcl and renews it via the same docker-exec path as the unsealer backup token. Also widen .gitignore to config/seal.hcl* so timestamped backups of the file (which contain the token) cannot be committed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,7 +3,7 @@ unseal-keys.json
|
||||
init-output.json
|
||||
unsealer-init.json
|
||||
admin-credentials.txt
|
||||
config/seal.hcl
|
||||
config/seal.hcl*
|
||||
*.token
|
||||
config/tls/
|
||||
data/
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
# which publishes no host port, so it is renewed via `docker compose exec`
|
||||
# rather than curl. Renewing it against main would 403.
|
||||
#
|
||||
# The main node's transit SEAL token (config/seal.hcl) also lives on the
|
||||
# unsealer and was NOT covered until 2026-09-18 — it lapsed, and after the next
|
||||
# reboot main could not auto-unseal (403 on transit/encrypt/autounseal). It is
|
||||
# renewed via the same exec path, parsed out of seal.hcl.
|
||||
#
|
||||
# Best-effort: a dead token logs a failure but never aborts the rest. No secrets
|
||||
# are printed.
|
||||
set -uo pipefail
|
||||
@@ -21,6 +26,7 @@ ADDR="${BAO_ADDR:-http://127.0.0.1:8200}"
|
||||
PROJECT_DIR="/home/lutz/Projects/OpenBAO"
|
||||
USER_DIR="${TOKEN_DIR:-/home/lutz/.config/openbao}" # explicit: $HOME is /root under the timer
|
||||
UNSEALER_TOKEN="/etc/openbao-unsealer-backup.token"
|
||||
SEAL_HCL="$PROJECT_DIR/config/seal.hcl"
|
||||
LOG="$USER_DIR/token-renew.log"
|
||||
ts="$(date '+%F %T %Z')"
|
||||
shopt -s nullglob
|
||||
@@ -42,11 +48,9 @@ renew_via_api() {
|
||||
else bad "$name" "$(printf '%s' "$resp" | jq -c '.errors // .' 2>/dev/null)"; fi
|
||||
}
|
||||
|
||||
# renew_via_exec <token-file> — for the unsealer instance (no published port)
|
||||
# renew_via_exec <name> <token> — for the unsealer instance (no published port)
|
||||
renew_via_exec() {
|
||||
local tf="$1" name tok resp ttl
|
||||
name="$(basename "$tf")"
|
||||
tok="$(cat "$tf" 2>/dev/null)"
|
||||
local name="$1" tok="$2" resp ttl
|
||||
[ -n "$tok" ] || { bad "$name" "EMPTY"; return; }
|
||||
# Bare `bao token renew` (no TOKEN arg) is the renew-self form; there is no
|
||||
# -self flag in OpenBao's CLI.
|
||||
@@ -63,9 +67,12 @@ for tf in "$USER_DIR"/*.token; do renew_via_api "$tf"; done
|
||||
# 2. root-owned infra tokens; the unsealer one needs the exec path
|
||||
for tf in /etc/openbao-*.token; do
|
||||
[ -r "$tf" ] || { bad "$(basename "$tf")" "not readable (run as root)"; continue; }
|
||||
if [ "$tf" = "$UNSEALER_TOKEN" ]; then renew_via_exec "$tf"; else renew_via_api "$tf"; fi
|
||||
if [ "$tf" = "$UNSEALER_TOKEN" ]; then renew_via_exec "$(basename "$tf")" "$(cat "$tf" 2>/dev/null)"; else renew_via_api "$tf"; fi
|
||||
done
|
||||
|
||||
# 3. main's transit seal token (on the unsealer)
|
||||
renew_via_exec "seal.hcl" "$(sed -nE 's/^[[:space:]]*token[[:space:]]*=[[:space:]]*"([^"]+)".*/\1/p' "$SEAL_HCL" 2>/dev/null)"
|
||||
|
||||
echo "$ts summary: renewed=$renewed failed=$failed" >> "$LOG"
|
||||
# Running as root must not leave the log root-owned for the next user-context read.
|
||||
chown lutz:lutz "$LOG" 2>/dev/null || true
|
||||
|
||||
Reference in New Issue
Block a user