From 1267df148a1e5518f5708a362846939e2127d330 Mon Sep 17 00:00:00 2001 From: tegwick Date: Tue, 26 May 2026 02:22:24 +0200 Subject: [PATCH] Harden KeyCape OpenBao client action --- sso-mfa/k8s/keycape/README.md | 6 +++--- .../security_bootstrap_console.py | 13 +++++++++---- ...m-root-custody-and-openbao-identity-bootstrap.md | 6 ++++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/sso-mfa/k8s/keycape/README.md b/sso-mfa/k8s/keycape/README.md index 0448813..8e17bec 100644 --- a/sso-mfa/k8s/keycape/README.md +++ b/sso-mfa/k8s/keycape/README.md @@ -70,7 +70,7 @@ image: keycape:v0.1 # replace with your actual tag # If T04 is not yet done, run it now and re-run after create-pi-token.sh. cd sso-mfa/k8s/keycape chmod +x create-secrets.sh create-pi-token.sh -./create-secrets.sh +bash ./create-secrets.sh # 2. Apply manifests kubectl apply -f deployment.yaml @@ -92,7 +92,7 @@ chmod +x create-pi-token.sh ./create-pi-token.sh # 2. Re-run create-secrets.sh to update keycape-config with the real token -./create-secrets.sh +bash ./create-secrets.sh # 3. Restart KeyCape to pick up the new Secret kubectl rollout restart deployment/keycape -n sso @@ -106,7 +106,7 @@ OpenBao admin CLI clients are code-defined there; operators should not create those clients manually in a separate UI. After changing the block: ```bash -./create-secrets.sh # regenerates keycape-config Secret +bash ./create-secrets.sh # regenerates keycape-config Secret kubectl rollout restart deployment/keycape -n sso ``` diff --git a/tools/security-bootstrap-console/security_bootstrap_console.py b/tools/security-bootstrap-console/security_bootstrap_console.py index a7d955a..c317ac6 100755 --- a/tools/security-bootstrap-console/security_bootstrap_console.py +++ b/tools/security-bootstrap-console/security_bootstrap_console.py @@ -1360,13 +1360,18 @@ def admin_identity_command_payloads(data: dict[str, Any]) -> list[dict[str, str] if login_state == "blocked": login_reason = "Configure OpenBao OIDC auth before testing the login path." + keycape_dir = shlex.quote(str(KEYCAPE_OPENBAO_CLIENT_CONFIG.parent)) + k8s_dir = shlex.quote(str(REPO_ROOT / "sso-mfa/k8s")) deploy_command = ( - "cd sso-mfa/k8s/keycape\n" - "./create-secrets.sh\n" + "bash <<'NETKINGDOM_KEYCAPE_APPLY'\n" + "set -euo pipefail\n" + f"cd {keycape_dir}\n" + "bash ./create-secrets.sh\n" "kubectl rollout restart deployment/keycape -n sso\n" "kubectl rollout status deployment/keycape -n sso --timeout=60s\n" - "cd ..\n" - "./verify-t07.sh" + f"cd {k8s_dir}\n" + "bash ./verify-t07.sh\n" + "NETKINGDOM_KEYCAPE_APPLY\n" ) oidc_config_inner = """bao auth enable -path=keycape oidc >/tmp/keycape-auth-enable.out 2>/tmp/keycape-auth-enable.err || { if grep -q "path is already in use" /tmp/keycape-auth-enable.err; then diff --git a/workplans/NET-WP-0015-platform-root-custody-and-openbao-identity-bootstrap.md b/workplans/NET-WP-0015-platform-root-custody-and-openbao-identity-bootstrap.md index 977921a..c9cac0d 100644 --- a/workplans/NET-WP-0015-platform-root-custody-and-openbao-identity-bootstrap.md +++ b/workplans/NET-WP-0015-platform-root-custody-and-openbao-identity-bootstrap.md @@ -321,6 +321,12 @@ client is now code-defined in `sso-mfa/k8s/keycape/create-secrets.sh`, while the UI action cards only ask the operator to apply live KeyCape config, configure OpenBao with a protected token prompt, and verify MFA-backed login. +**2026-05-26:** Hardened the KeyCape OpenBao client deployment action after the +operator hit a non-executable `create-secrets.sh`. The action card now runs the +script through `bash`, uses absolute repo paths, and wraps the sequence in a +fail-fast heredoc so a failed config generation does not continue into a +KeyCape restart or verification. + **2026-05-24:** Stepped back from ad hoc secret rollout and added the custodian age-key bootstrap model to the control surface. The UI now records the custodian public age recipient, a derived fingerprint, and a non-secret