diff --git a/Makefile b/Makefile index d23af46..97eece7 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ OPENBAO_UI_OVERLAY_DIR ?= helm/openbao-ui-overlay OPENBAO_UI_OVERLAY_K8S ?= helm/openbao-ui-overlay-k8s.yaml OPENBAO_PUBLIC_INGRESS_ROLLBACK ?= helm/openbao-public-ingress.rollback.yaml OPENBAO_VERIFY_AUTH_ARGS ?= +SESSION_QUESTIONS ?= Q1,Q2,Q3,Q4,Q5 OPENBAO_RESTORE_EVIDENCE ?= /tmp/netkingdom-openbao-restore-drill/evidence.json OPENBAO_EMERGENCY_EVIDENCE ?= /tmp/netkingdom-openbao-emergency-drill/evidence.json EXTERNAL_SECRETS_NAMESPACE ?= external-secrets @@ -338,6 +339,15 @@ credential-change-status-json: ## Render credential change request readiness sta credential-change-sync-decision: ## Sync resolved State Hub decision back into a CCR scripts/credential-change.py sync-decision $(CREDENTIAL_CHANGE) --state-hub-url $(STATE_HUB_URL) +.PHONY: openbao-open-questions +openbao-open-questions: ## Attended read-only session for the open custody questions (SESSION_RECEIPT=) + @test -n "$(SESSION_RECEIPT)" || { echo "SESSION_RECEIPT= is required" >&2; exit 2; } + @test ! -e "$(SESSION_RECEIPT)" || { echo "SESSION_RECEIPT already exists: $(SESSION_RECEIPT)" >&2; exit 2; } + env -u OPENBAO_TOKEN -u VAULT_TOKEN -u BAO_TOKEN \ + scripts/openbao-attended-exec.py -- /usr/bin/python3 \ + scripts/openbao_open_questions_session.py \ + --questions $(SESSION_QUESTIONS) --receipt $(SESSION_RECEIPT) + credential-change-apply-plan: ## Render approved-only operator apply plan scripts/credential-change.py apply-plan $(CREDENTIAL_CHANGE) diff --git a/docs/openbao-open-questions-session.md b/docs/openbao-open-questions-session.md index caf0f7f..1554efd 100644 --- a/docs/openbao-open-questions-session.md +++ b/docs/openbao-open-questions-session.md @@ -26,11 +26,14 @@ attended OIDC through `bao login -method=oidc -path=netkingdom role=platform-adm The owner command is never run directly. ```sh -scripts/openbao-attended-exec.py -- \ - /usr/bin/python3 /home/worsch/railiance-platform/scripts/openbao_open_questions_session.py \ - --receipt /tmp/.json +make openbao-open-questions SESSION_RECEIPT=/tmp/.json ``` +Use the Make target rather than typing the underlying command: it is short enough +not to be broken by terminal wrapping, it refuses a `SESSION_RECEIPT` that already +exists or is missing, and it clears any ambient token before invoking the +envelope. + `scripts/openbao-attended-exec.py` supplies the WSL browser launcher and then `exec`s into `warden access openbao-platform-admin-login --exec`, so Warden keeps the envelope: it captures both streams, owns the temporary token helper and @@ -42,15 +45,14 @@ The runner prints nothing. Its entire output is the receipt. **To settle the npm field alone**, run only the two questions that bear on it: ```sh -scripts/openbao-attended-exec.py -- \ - /usr/bin/python3 /home/worsch/railiance-platform/scripts/openbao_open_questions_session.py \ - --questions Q1,Q2 --receipt /tmp/.json +make openbao-open-questions SESSION_QUESTIONS=Q1,Q2 SESSION_RECEIPT=/tmp/.json ``` `--questions` defaults to all five. Q5 is the only step that reads the backup lane, so naming a subset is also how to exclude it. -**Ambient-token guard.** The runner refuses to start if `OPENBAO_TOKEN`, +**Ambient-token guard.** The Make target clears these before invoking the +envelope; the runner independently refuses to start if `OPENBAO_TOKEN`, `BAO_TOKEN` or `VAULT_TOKEN` is set in the environment. A standing token would let these reads succeed without the attended login, producing a receipt that looks attended and is not. Unset it first; the envelope supplies the identity. diff --git a/scripts/openbao_open_questions_session.py b/scripts/openbao_open_questions_session.py index b8ea8df..0565aa0 100755 --- a/scripts/openbao_open_questions_session.py +++ b/scripts/openbao_open_questions_session.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 """Read-only, silent owner session for the four open custody questions. Runs inside Warden's attended login envelope. Reads no secret value into the