diff --git a/scripts/openbao-eso-token-apply.sh b/scripts/openbao-eso-token-apply.sh deleted file mode 100755 index 5fad508..0000000 --- a/scripts/openbao-eso-token-apply.sh +++ /dev/null @@ -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." diff --git a/scripts/renew-runtime-lease.sh b/scripts/renew-runtime-lease.sh index 559e068..34f309f 100755 --- a/scripts/renew-runtime-lease.sh +++ b/scripts/renew-runtime-lease.sh @@ -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" \ diff --git a/workplans/ADHOC-2026-09-24.md b/workplans/ADHOC-2026-09-24.md new file mode 100644 index 0000000..78cd982 --- /dev/null +++ b/workplans/ADHOC-2026-09-24.md @@ -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.