Align ESO token scripts with the periodic token (RPF-WP-0046)

renew-runtime-lease.sh is recovery-only now: it mints with -period
instead of -ttl=768h, so a recovery no longer undoes the platform's
periodic token, and defaults BAO_ADDR to the tunnel rather than the
retired bao.coulomb.social. The old openbao-eso-token-apply.sh is
retired for the same two reasons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 151986@bnt-lap001
Assistant-Session: ccd02b6b-80ae-48e5-8cad-9c8f74d21a67
This commit is contained in:
tegwick 2026-09-24 02:22:49 +02:00
parent 4a0e5aa53d
commit 21e8ce9b72
3 changed files with 51 additions and 110 deletions

View file

@ -1,104 +0,0 @@
#!/usr/bin/env bash
# Mint a read-limited OpenBao token and store it on railiance01 for
# ClusterSecretStore openbao-audit-core and the VaultDynamicSecret generators.
#
# Policy: railiance-platform/openbao/policies/external-secrets-audit-core.hcl
#
# Does not print secret values. Requires an attended operator OpenBao token
# that can write policies and create child tokens.
set -euo pipefail
DEFAULT_POLICIES="external-secrets-audit-core"
POLICIES="${OPENBAO_AUDIT_CORE_POLICIES:-$DEFAULT_POLICIES}"
POLICY_DIR="${OPENBAO_POLICY_DIR:-$HOME/railiance-platform/openbao/policies}"
BAO_ADDR="${BAO_ADDR:-https://bao.coulomb.social}"
# ~/.kube/config-hosteurope currently targets 16443 (coulombcore). railiance01
# is the k3s-api-railiance01 tunnel on 16444. Always pass this explicitly
# unless you have a dedicated railiance01 kubeconfig.
RAILIANCE01_KUBECONFIG="${RAILIANCE01_KUBECONFIG:-}"
SECRET_NAME="${OPENBAO_AUDIT_CORE_ESO_SECRET:-openbao-audit-core-eso-token}"
SECRET_NS="${OPENBAO_AUDIT_CORE_ESO_NAMESPACE:-external-secrets}"
TTL="${OPENBAO_AUDIT_CORE_ESO_TTL:-768h}"
if ! command -v bao >/dev/null 2>&1; then
echo "ERROR: bao CLI not found" >&2
exit 1
fi
if ! command -v kubectl >/dev/null 2>&1; then
echo "ERROR: kubectl not found" >&2
exit 1
fi
if [[ -z "$RAILIANCE01_KUBECONFIG" ]]; then
echo "ERROR: set RAILIANCE01_KUBECONFIG to a kubeconfig whose server is https://127.0.0.1:16444 (railiance01)." >&2
echo "Do not use ~/.kube/config or ~/.kube/config-hosteurope — those currently hit 16443 (coulombcore)." >&2
exit 1
fi
echo "OpenBao addr: $BAO_ADDR"
echo "Policies: $POLICIES"
echo "K8s secret: $SECRET_NS/$SECRET_NAME (railiance01)"
echo "Kubeconfig: $RAILIANCE01_KUBECONFIG"
if [[ -n "${BAO_TOKEN:-}" ]]; then
:
elif [[ -n "${OPENBAO_TOKEN_FILE:-}" && -f "${OPENBAO_TOKEN_FILE}" ]]; then
BAO_TOKEN="$(head -n 1 "${OPENBAO_TOKEN_FILE}")"
else
read -r -s -p "OpenBao operator token: " BAO_TOKEN
echo >&2
fi
if [[ -z "${BAO_TOKEN:-}" ]]; then
echo "ERROR: empty OpenBao token" >&2
exit 1
fi
export BAO_ADDR BAO_TOKEN
health="$(curl -fsS "$BAO_ADDR/v1/sys/health")"
if echo "$health" | grep -q '"sealed":true'; then
echo "ERROR: OpenBao at $BAO_ADDR reports sealed" >&2
exit 1
fi
for policy in $POLICIES; do
policy_file="$POLICY_DIR/${policy}.hcl"
if [[ -f "$policy_file" ]]; then
bao policy write "$policy" "$policy_file"
echo "policy written: $policy"
else
echo "WARN: policy file missing ($policy_file); using existing OpenBao policy '$policy'" >&2
fi
done
# Child token: renewable, orphan so operator logout does not revoke delivery.
# shellcheck disable=SC2086
token_json="$(bao token create -policy="$(echo $POLICIES | tr ' ' ',')" -ttl="$TTL" -renewable=true -orphan -format=json)"
child_token="$(printf '%s' "$token_json" | python3 -c 'import json,sys; print(json.load(sys.stdin)["auth"]["client_token"])')"
if [[ -z "$child_token" || ${#child_token} -lt 8 ]]; then
echo "ERROR: failed to mint child token" >&2
exit 1
fi
echo "minted child token length=${#child_token} (value not printed)"
export KUBECONFIG="$RAILIANCE01_KUBECONFIG"
# Fail closed if this kubeconfig is not railiance01. coulombcore has
# core-hub-staging and no audit-core namespace.
if ! kubectl get ns audit-core >/dev/null 2>&1; then
echo "ERROR: kubeconfig does not see namespace audit-core; refusing to write the ESO token." >&2
echo "Expected railiance01 via https://127.0.0.1:16444 (ops-bridge tunnel k3s-api-railiance01)." >&2
exit 1
fi
if kubectl get ns core-hub-staging >/dev/null 2>&1; then
echo "ERROR: kubeconfig looks like coulombcore (namespace core-hub-staging present)." >&2
exit 1
fi
# Recreate rather than kubectl-apply: apply writes the token into
# last-applied-configuration, which is readable as Secret metadata.
kubectl -n "$SECRET_NS" delete secret "$SECRET_NAME" --ignore-not-found
kubectl -n "$SECRET_NS" create secret generic "$SECRET_NAME" \
--from-literal=token="$child_token"
unset child_token BAO_TOKEN
echo "Secret $SECRET_NS/$SECRET_NAME applied on railiance01."
echo "Next: force-sync ExternalSecret audit-core-database; do not bounce the pod."

View file

@ -1,19 +1,27 @@
#!/usr/bin/env bash
# Contained remint of the ESO orphan token, then force-sync the runtime lease.
# RECOVERY ONLY: contained remint of the ESO token, then force-sync the runtime lease.
#
# Routine renewal is not this script's job. Since 2026-09-23 (railiance-platform
# RPF-WP-0046) external-secrets/openbao-audit-core-eso-token is a periodic 168h
# token renewed daily by the CronJob external-secrets/eso-token-renewer. Run
# this only when that token is lost or revoked and the platform has not
# re-minted it. It mints the same shape (-period, not -ttl), so a recovery
# does not undo the periodic lifecycle.
#
# Must be silent: `warden access --exec` fails closed on any child stdout/stderr
# even when the command succeeds. Persist metadata only. Never print a token.
#
# warden access openbao-platform-admin-login --exec -- \
# env RAILIANCE01_KUBECONFIG="$HOME/.kube/config-railiance01" \
# BAO_ADDR="${BAO_ADDR:-https://bao.coulomb.social}" \
# BAO_ADDR=http://127.0.0.1:18200 \
# /home/worsch/audit-core/scripts/renew-runtime-lease.sh
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
export RAILIANCE01_KUBECONFIG="${RAILIANCE01_KUBECONFIG:-/home/worsch/.kube/config-railiance01}"
export KUBECONFIG="$RAILIANCE01_KUBECONFIG"
export BAO_ADDR="${BAO_ADDR:-https://bao.coulomb.social}"
# bao.coulomb.social is retired (2026-09-15); the tunnel is the operator path.
export BAO_ADDR="${BAO_ADDR:-http://127.0.0.1:18200}"
# Contained login persists the session in $HOME/.vault-token and unsets
# BAO_TOKEN/VAULT_TOKEN. Do not prompt; do not re-export a token.
unset BAO_TOKEN VAULT_TOKEN OPENBAO_TOKEN || true
@ -21,7 +29,7 @@ unset BAO_TOKEN VAULT_TOKEN OPENBAO_TOKEN || true
SECRET_NAME="${OPENBAO_AUDIT_CORE_ESO_SECRET:-openbao-audit-core-eso-token}"
SECRET_NS="${OPENBAO_AUDIT_CORE_ESO_NAMESPACE:-external-secrets}"
POLICY="${OPENBAO_AUDIT_CORE_POLICIES:-external-secrets-audit-core}"
TTL="${OPENBAO_AUDIT_CORE_ESO_TTL:-768h}"
PERIOD="${OPENBAO_AUDIT_CORE_ESO_PERIOD:-168h}"
EVIDENCE="$ROOT/docs/evidence/$(date -u +%Y-%m-%d)-eso-token-remint.json"
WORKDIR="${HOME:-/tmp}/audit-core-remint"
mkdir -p "$WORKDIR"
@ -81,7 +89,7 @@ fi
token_json_file="$WORKDIR/token-create.json"
rm -f "$token_json_file"
if ! bao token create -policy="$POLICY" -ttl="$TTL" -renewable=true -orphan -format=json \
if ! bao token create -policy="$POLICY" -period="$PERIOD" -orphan -format=json \
>"$token_json_file" 2>/dev/null; then
_write_evidence failed '{"reason": "token_create_failed"}'
rm -f "$token_json_file"
@ -106,7 +114,7 @@ if [[ $create_status -ne 0 || ! -s "$child_file" ]]; then
rm -f "$child_file"
exit 1
fi
_write_evidence token_created '{"ttl": "768h", "orphan": true, "renewable": true}'
_write_evidence token_created "{\"period\": \"$PERIOD\", \"orphan\": true}"
kubectl -n "$SECRET_NS" delete secret "$SECRET_NAME" --ignore-not-found >/dev/null 2>&1 || true
if ! kubectl -n "$SECRET_NS" create secret generic "$SECRET_NAME" \

View file

@ -0,0 +1,37 @@
---
id: ADHOC-2026-09-24
type: workplan
title: "Ad hoc tasks 2026-09-24"
domain: infotech
repo: audit-core
status: finished
flavor: implementation
owner: claude
topic_slug: railiance
created: "2026-09-24"
updated: "2026-09-24"
---
# Ad hoc tasks 2026-09-24
## Align the ESO token scripts with the periodic token (RPF-WP-0046)
```task
id: ADHOC-2026-09-24-T01
status: done
priority: medium
```
Inbox from railiance-platform (`1847edae`): on 2026-09-23
`external-secrets/openbao-audit-core-eso-token` was re-minted as a periodic
168h token, renewed daily by the CronJob `external-secrets/eso-token-renewer`.
`scripts/renew-runtime-lease.sh` re-minted with `-ttl=768h`, which would undo
that, and defaulted `BAO_ADDR` to the retired `https://bao.coulomb.social`.
Done: `renew-runtime-lease.sh` is now marked recovery-only, mints with
`-period` (default 168h, `OPENBAO_AUDIT_CORE_ESO_PERIOD`), and defaults
`BAO_ADDR` to the tunnel `http://127.0.0.1:18200`. The first-mint script
`scripts/openbao-eso-token-apply.sh` is retired (deleted): it carried the same
768h TTL and retired address, and the agent environment orientation §6 says not
to re-run the old `*-eso-token-apply` scripts. Nothing was run against the
cluster or OpenBao.