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:
parent
4a0e5aa53d
commit
21e8ce9b72
3 changed files with 51 additions and 110 deletions
|
|
@ -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."
|
||||
|
|
@ -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" \
|
||||
|
|
|
|||
37
workplans/ADHOC-2026-09-24.md
Normal file
37
workplans/ADHOC-2026-09-24.md
Normal 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue