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
|
#!/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
|
# 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.
|
# even when the command succeeds. Persist metadata only. Never print a token.
|
||||||
#
|
#
|
||||||
# warden access openbao-platform-admin-login --exec -- \
|
# warden access openbao-platform-admin-login --exec -- \
|
||||||
# env RAILIANCE01_KUBECONFIG="$HOME/.kube/config-railiance01" \
|
# 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
|
# /home/worsch/audit-core/scripts/renew-runtime-lease.sh
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
export RAILIANCE01_KUBECONFIG="${RAILIANCE01_KUBECONFIG:-/home/worsch/.kube/config-railiance01}"
|
export RAILIANCE01_KUBECONFIG="${RAILIANCE01_KUBECONFIG:-/home/worsch/.kube/config-railiance01}"
|
||||||
export KUBECONFIG="$RAILIANCE01_KUBECONFIG"
|
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
|
# Contained login persists the session in $HOME/.vault-token and unsets
|
||||||
# BAO_TOKEN/VAULT_TOKEN. Do not prompt; do not re-export a token.
|
# BAO_TOKEN/VAULT_TOKEN. Do not prompt; do not re-export a token.
|
||||||
unset BAO_TOKEN VAULT_TOKEN OPENBAO_TOKEN || true
|
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_NAME="${OPENBAO_AUDIT_CORE_ESO_SECRET:-openbao-audit-core-eso-token}"
|
||||||
SECRET_NS="${OPENBAO_AUDIT_CORE_ESO_NAMESPACE:-external-secrets}"
|
SECRET_NS="${OPENBAO_AUDIT_CORE_ESO_NAMESPACE:-external-secrets}"
|
||||||
POLICY="${OPENBAO_AUDIT_CORE_POLICIES:-external-secrets-audit-core}"
|
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"
|
EVIDENCE="$ROOT/docs/evidence/$(date -u +%Y-%m-%d)-eso-token-remint.json"
|
||||||
WORKDIR="${HOME:-/tmp}/audit-core-remint"
|
WORKDIR="${HOME:-/tmp}/audit-core-remint"
|
||||||
mkdir -p "$WORKDIR"
|
mkdir -p "$WORKDIR"
|
||||||
|
|
@ -81,7 +89,7 @@ fi
|
||||||
|
|
||||||
token_json_file="$WORKDIR/token-create.json"
|
token_json_file="$WORKDIR/token-create.json"
|
||||||
rm -f "$token_json_file"
|
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
|
>"$token_json_file" 2>/dev/null; then
|
||||||
_write_evidence failed '{"reason": "token_create_failed"}'
|
_write_evidence failed '{"reason": "token_create_failed"}'
|
||||||
rm -f "$token_json_file"
|
rm -f "$token_json_file"
|
||||||
|
|
@ -106,7 +114,7 @@ if [[ $create_status -ne 0 || ! -s "$child_file" ]]; then
|
||||||
rm -f "$child_file"
|
rm -f "$child_file"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
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" \
|
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