Silence the runtime-lease remint for contained warden --exec
Warden fails closed on any child stdout or stderr, even on success. The previous helper echoed status and prompted for BAO_TOKEN after the login envelope had already unset it. Use the contained .vault-token helper, write Kubernetes Secret from a file, and persist only metadata evidence. Assistant: grok Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
This commit is contained in:
parent
802356efae
commit
aad5a75ca6
1 changed files with 116 additions and 12 deletions
|
|
@ -1,23 +1,127 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Attended remint of the ESO orphan token, then force-sync the runtime lease.
|
# Contained remint of the ESO orphan token, then force-sync the runtime lease.
|
||||||
# Never prints secret values. Run inside:
|
#
|
||||||
|
# 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 -- \
|
# warden access openbao-platform-admin-login --exec -- \
|
||||||
# env RAILIANCE01_KUBECONFIG="$HOME/.kube/config-railiance01" \
|
# env RAILIANCE01_KUBECONFIG="$HOME/.kube/config-railiance01" \
|
||||||
# "$PWD/scripts/renew-runtime-lease.sh"
|
# BAO_ADDR="${BAO_ADDR:-https://bao.coulomb.social}" \
|
||||||
|
# /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/.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}"
|
export BAO_ADDR="${BAO_ADDR:-https://bao.coulomb.social}"
|
||||||
|
# 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
|
||||||
|
|
||||||
"$ROOT/scripts/openbao-eso-token-apply.sh"
|
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}"
|
||||||
|
EVIDENCE="$ROOT/docs/evidence/$(date -u +%Y-%m-%d)-eso-token-remint.json"
|
||||||
|
WORKDIR="${HOME:-/tmp}/audit-core-remint"
|
||||||
|
mkdir -p "$WORKDIR"
|
||||||
|
chmod 700 "$WORKDIR" 2>/dev/null || true
|
||||||
|
|
||||||
# One read of database/creds/audit-core-runtime = one new lease. Annotate
|
_write_evidence() {
|
||||||
# only the runtime ExternalSecret; migrate/senders follow on their own
|
python3 - "$EVIDENCE" "$@" <<'PY' >/dev/null 2>&1 || true
|
||||||
# refresh once the store is Ready.
|
import json, sys
|
||||||
kubectl -n audit-core annotate externalsecret audit-core-database \
|
from datetime import datetime, timezone
|
||||||
force-sync="$(date -u +%s)" --overwrite
|
from pathlib import Path
|
||||||
|
path, step = Path(sys.argv[1]), sys.argv[2]
|
||||||
|
extra = sys.argv[3] if len(sys.argv) > 3 else "{}"
|
||||||
|
try:
|
||||||
|
payload = json.loads(extra)
|
||||||
|
except Exception:
|
||||||
|
payload = {}
|
||||||
|
doc = {
|
||||||
|
"step": step,
|
||||||
|
"observed_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat(),
|
||||||
|
"secret": "external-secrets/openbao-audit-core-eso-token",
|
||||||
|
"lease_path": "database/creds/audit-core-runtime",
|
||||||
|
}
|
||||||
|
doc.update(payload)
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
path.write_text(json.dumps(doc, indent=2) + "\n")
|
||||||
|
PY
|
||||||
|
}
|
||||||
|
|
||||||
echo "ESO token reminted and audit-core-database force-sync requested."
|
_write_evidence started '{"kubeconfig_set": true}'
|
||||||
echo "Wait for ExternalSecret Ready=True; do not restart the receiver."
|
|
||||||
|
if ! command -v bao >/dev/null 2>&1; then
|
||||||
|
_write_evidence failed '{"reason": "bao_missing"}'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! command -v kubectl >/dev/null 2>&1; then
|
||||||
|
_write_evidence failed '{"reason": "kubectl_missing"}'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ ! -f "$RAILIANCE01_KUBECONFIG" ]]; then
|
||||||
|
_write_evidence failed '{"reason": "kubeconfig_missing"}'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! kubectl get ns audit-core >/dev/null 2>&1; then
|
||||||
|
_write_evidence failed '{"reason": "not_railiance01"}'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if kubectl get ns core-hub-staging >/dev/null 2>&1; then
|
||||||
|
_write_evidence failed '{"reason": "coulombcore_kubeconfig"}'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
health="$(curl -fsS "$BAO_ADDR/v1/sys/health" 2>/dev/null || true)"
|
||||||
|
if printf '%s' "$health" | grep -q '"sealed":true'; then
|
||||||
|
_write_evidence failed '{"reason": "openbao_sealed"}'
|
||||||
|
exit 1
|
||||||
|
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 \
|
||||||
|
>"$token_json_file" 2>/dev/null; then
|
||||||
|
_write_evidence failed '{"reason": "token_create_failed"}'
|
||||||
|
rm -f "$token_json_file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
child_file="$WORKDIR/eso.token"
|
||||||
|
python3 - "$token_json_file" "$child_file" <<'PY' >/dev/null 2>&1
|
||||||
|
import json, sys
|
||||||
|
from pathlib import Path
|
||||||
|
raw = json.loads(Path(sys.argv[1]).read_text())
|
||||||
|
token = (raw.get("auth") or {}).get("client_token") or ""
|
||||||
|
if len(token) < 8:
|
||||||
|
raise SystemExit(1)
|
||||||
|
Path(sys.argv[2]).write_text(token)
|
||||||
|
Path(sys.argv[2]).chmod(0o600)
|
||||||
|
PY
|
||||||
|
create_status=$?
|
||||||
|
rm -f "$token_json_file"
|
||||||
|
if [[ $create_status -ne 0 || ! -s "$child_file" ]]; then
|
||||||
|
_write_evidence failed '{"reason": "token_parse_failed"}'
|
||||||
|
rm -f "$child_file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
_write_evidence token_created '{"ttl": "768h", "orphan": true, "renewable": 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" \
|
||||||
|
--from-file=token="$child_file" >/dev/null 2>&1; then
|
||||||
|
_write_evidence failed '{"reason": "secret_create_failed"}'
|
||||||
|
rm -f "$child_file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
rm -f "$child_file"
|
||||||
|
_write_evidence secret_replaced '{"namespace": "external-secrets"}'
|
||||||
|
|
||||||
|
if ! kubectl -n audit-core annotate externalsecret audit-core-database \
|
||||||
|
force-sync="$(date -u +%s)" --overwrite >/dev/null 2>&1; then
|
||||||
|
_write_evidence failed '{"reason": "annotate_failed"}'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
_write_evidence annotated '{"externalsecret": "audit-core/audit-core-database"}'
|
||||||
|
exit 0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue