From 3a850beb06bd1e753dd44f084e4b383983113706 Mon Sep 17 00:00:00 2001 From: codex Date: Tue, 13 Oct 2026 21:58:13 +0200 Subject: [PATCH] security: record verified key recovery and accept Playwright delivery coordination --- .../privacyidea-key-custody.json | 140 ++++++++++++++++++ infra/security-flow/playwright-delivery.json | 138 +++++++++++++++++ ...gdom-security-blueprint-and-gap-closure.md | 50 +++++++ 3 files changed, 328 insertions(+) create mode 100644 docs/evidence/2026-10-13-netkingdom-security/privacyidea-key-custody.json create mode 100644 infra/security-flow/playwright-delivery.json diff --git a/docs/evidence/2026-10-13-netkingdom-security/privacyidea-key-custody.json b/docs/evidence/2026-10-13-netkingdom-security/privacyidea-key-custody.json new file mode 100644 index 00000000..dd0a1439 --- /dev/null +++ b/docs/evidence/2026-10-13-netkingdom-security/privacyidea-key-custody.json @@ -0,0 +1,140 @@ +{ + "observed_at": "2026-10-13", + "workplan_id": "NK-WP-0049", + "task_id": "NK-WP-0049-T02", + "custodian_task_id": "CUST-WP-0080-T03", + "source_repo": "net-kingdom", + "source_commit": "1cbe00fd78e60ac70f2ea7957a0e1d7477388dcf", + "source_base": "16021d3953f8435449f63dbb25442702a9f45e76", + "result": "source repair verified; native estate acceptance pending", + "changes": [ + "Private no-overwrite export of the 96-byte encryption key and matching audit RSA pair; no generation of missing historical encryption keys.", + "Captured Kubernetes transport with deployment/pod/PVC identity checks and create-or-verify DR Secrets; conditional annotation cleanup.", + "Explicit first-bootstrap audit initialization only when local and cluster custody copies are absent.", + "Restore the actual data PVC through an independently reviewed maintenance pod while the application is stopped; retain partial writes and refuse differing keys.", + "Correct DR field names and withdraw the Secret-only and unmounted helper restore instructions." + ], + "files": [ + { + "path": "sso-mfa/bootstrap/apply-service-secrets.py", + "sha256": "ea9c3418ed00527b9019ab9893f1f3c9fe29d0697f1f0c879e28fdbae373889b" + }, + { + "path": "sso-mfa/k8s/privacyidea/key-custody.py", + "sha256": "e43d21694cb9c99bd02257a4f225973e992c9af4b0e71788929f949b9752f08a" + }, + { + "path": "sso-mfa/k8s/privacyidea/key-custody-remote.py", + "sha256": "27b2b885c81923d85054e3999c5613e104fe627779b2b50398ed9bed5088f47e" + }, + { + "path": "sso-mfa/k8s/privacyidea/enckey-bootstrap.sh", + "sha256": "e47b86ae422f043145525b3deaa4c57ce6ee92974db090695be7fafbe7b61a2e" + }, + { + "path": "sso-mfa/k8s/privacyidea/enckey-restore.sh", + "sha256": "fb31831c1492006ad5f32e16f2ce47baf6e20d0cb56a592432da0698052bf362" + }, + { + "path": "sso-mfa/k8s/privacyidea/KEY-RECOVERY.md", + "sha256": "784e0e40b542a451c67b4ee31ef4fb396ddf9744965afa7e09f3d23b8209c066" + }, + { + "path": "tests/test_privacyidea_key_custody.py", + "sha256": "7bec8051ca346c8517315d70d382e928b4670363c36fce84f234692931c366b5" + }, + { + "path": "sso-mfa/bootstrap/creds-bootstrap-agent.sh", + "sha256": "e36ecdd65debb1b46f0a10025a38a7ca8d824cf7ee4d75d1b9922a9a4c5d0675" + }, + { + "path": "sso-mfa/bootstrap/creds-apply.sh", + "sha256": "a70dba396484b2a353a39349c3d3719f7b6695b9f0e35025ef79e3db0ec2ff53" + }, + { + "path": "sso-mfa/bootstrap/gen-secrets.sh", + "sha256": "cde043ff94d78889dd8ed784f73fa464d8ee1486de97d2894c58e9a0e37752f5" + }, + { + "path": "sso-mfa/k8s/verify-t04.sh", + "sha256": "74128536919f79f17bffc107678718848c4ca095de06140cdc453e68953aabd1" + }, + { + "path": "sso-mfa/WORKPLAN.md", + "sha256": "b1f1944280e861978026e9d87f9084ae9735fae2864bfe052a645c2fa5cd469b" + }, + { + "path": "sso-mfa/k8s/privacyidea/README.md", + "sha256": "b5010a87a6e8ca73fa11d0a2013d0da3a0de959f6533c14481cee6feaeb6ff07" + }, + { + "path": "sso-mfa/k8s/backup/DR-RUNBOOK.md", + "sha256": "d55275636bc274e22cda5b6ae461c0244c22984b6de95588caa357eaed75864d" + }, + { + "path": "workplans/NK-WP-0049-bootstrap-secret-free-recovery-handoff.md", + "sha256": "7fd7fe3cec27770ac186aeb148ae48a9addc9d5da104880f635dc339bdf5edc4" + } + ], + "verification": { + "full_suite": { + "passed": 631, + "skipped": 0, + "warnings": 4, + "exit_code": 0, + "elapsed_seconds": 170.46, + "command": [ + "/tmp/nk-pi-key-native/bin/python", + "-m", + "pytest", + "-q", + "tests", + "tools", + "sso-mfa/k8s/keycape", + "--tb=short", + "-rs" + ], + "source_unchanged_during_run": true, + "binding_sha256": "c28e33176338a209ffc0c25be442d060548544aa23dbd35731f7659303bad517", + "log_sha256": "2264c389835205b731694a52922aaf8793688341b6f08434bea773510f7a6947" + }, + "focused_initial": { + "passed": 35 + }, + "native_test_preparation_failure": { + "failed": 1, + "passed": 4, + "cause": "Test passed filenames to privacyIDEA Sign, whose API requires PEM bytes; corrected test input, no implementation change." + }, + "native_corrected_subset": { + "passed": 5 + }, + "old_source_regression_subset": { + "failed": 6, + "scope": "Export roundtrip and bad local copy checks against baseline source; includes old FIFO timeout. Limited interface/path baseline, not a full native comparison." + }, + "native_package": "privacyidea==3.12.2 in disposable /tmp/nk-pi-key-native; not a deployment promotion", + "native_behaviors": [ + "DefaultSecurityModule decrypts pre-recovery PIN/configuration password after filesystem restore.", + "Restored audit key verifies pre-recovery signature; original verifier accepts signature made with restored key." + ], + "applied_files_match_test_binding": true, + "shell_syntax": "passed for changed shell callers", + "git_diff_check": "passed" + }, + "limits": [ + "No live keys, Secrets, PVC or workload were read or changed in this verification.", + "Kubernetes API behavior is synthetic; native filesystem, cryptography and privacyIDEA package checks do not establish pinned deployed-image or cluster acceptance.", + "Format validity does not establish database backup lineage or independent off-host custody.", + "Multiple files and two Secrets are not a transaction; failed or unknown outcomes require reconciliation.", + "Same-UID hostile interference and UID-atomic Kubernetes exec are not guaranteed; an exclusive owner maintenance window is required.", + "Crash or SIGKILL can retain temporary or partial files.", + "The declared root:999 runtime profile needs native readability proof; first-audit flag grants no authority.", + "Full caller inventory, remaining LDAP/realm/MFA diagnostic callers and native recovery acceptance remain open." + ], + "knowledge_orientation": { + "version": "0.2.6", + "digest": "8d1d6a9d4d07fec7b619618de7dfe2be2254c1790f85f4198c7fe19db9751c02", + "status": "withheld/source-changed; reviewed owner sources directly" + } +} diff --git a/infra/security-flow/playwright-delivery.json b/infra/security-flow/playwright-delivery.json new file mode 100644 index 00000000..bd296298 --- /dev/null +++ b/infra/security-flow/playwright-delivery.json @@ -0,0 +1,138 @@ +{ + "case_id": "case:cross-owner:CUST-WP-0080-T05:playwright-delivery", + "scenario_type": "cross_owner_wait", + "observed_at": "2026-10-13", + "coordinating_owner": "the-custodian / custodian-codex", + "beneficiary_workplan_id": "CUST-WP-0080", + "beneficiary_task_id": "CUST-WP-0080-T05", + "obligor_repo": "railiance-platform", + "obligor_workplan_id": "RPF-WP-0056", + "obligor_task_id": "RPF-WP-0056-T03", + "state": "waiting", + "reason": "Coordinator accepts delivery tracking. Pilot and scoped RBAC delivered; owner registration/custody/transport/authenticator implementation returns and real consumer acceptance remain pending.", + "request_message_id": "1b279bad-a159-43da-8709-1167882e62f8", + "driver_lookup": { + "local_project_workplans_scanned": 10, + "matching_driver": null + }, + "source_records": [ + { + "repo": "railiance-platform", + "path": "docs/playwright-identity-handoff.md", + "commit": "d303c99e3be993ffa989bc9ba3d7b471903858ce", + "sha256": "9ddd4303c11182b62fdb45c737d5cd9457dcb83f47503cf9e0ef476f45016623" + }, + { + "repo": "railiance-platform", + "path": "workplans/RPF-WP-0056-playwright-consumer-admission.md", + "commit": "d303c99e3be993ffa989bc9ba3d7b471903858ce", + "sha256": "8c4da42a929a7016df535bd40cfa724f308777c8a4822c6f4ca9868dad8eefdc" + }, + { + "repo": "rapp-playwright", + "path": "workplans/RAPP-PLAYWRIGHT-WP-0004-consumer-verification.md", + "commit": "3a30ef159ae680da9e03179fcbe4dac9cdcc9cc3", + "sha256": "14ddd47537fe25964ed4df02c71a9d78dda74c4e2fb39c427b119de5f18e504e" + } + ], + "linked_existing_tasks": [ + { + "repo": "railiance-platform", + "task_id": "RPF-WP-0056-T03", + "hub_task_id": "a82762eb-bb6d-5600-89ca-a81ada2eba9f", + "status_observed": "wait", + "responsibility": "Integrated supported consumer flow and live consumer acceptance." + }, + { + "repo": "railiance-platform", + "task_id": "RPF-WP-0056-T06", + "hub_task_id": "ef6c21bc-0048-5b73-976e-130cd9af538d", + "status_observed": "wait", + "responsibility": "Accept Custodian coordinating owner and source task return." + }, + { + "repo": "rapp-playwright", + "task_id": "RAPP-PLAYWRIGHT-WP-0004-T01", + "hub_task_id": "09f87694-8832-5ae8-9d0b-b66834ffcfcc", + "status_observed": "wait", + "responsibility": "Accept native consumer and remaining interruption/recovery evidence." + }, + { + "repo": "rapp-playwright", + "task_id": "RAPP-PLAYWRIGHT-WP-0004-T03", + "hub_task_id": "c8642437-27c5-5e58-b0f8-847c285fb4e6", + "status_observed": "wait", + "responsibility": "Publish supported managed availability with reuse-surface." + } + ], + "owner_requests": [ + { + "repo": "railiance-cluster", + "message_id": "0c1023ce-86ac-404a-842e-2f7e1a6d90f1", + "responsibility": "Native JWT authenticator integration, version-specific validation, preserved existing authentication, rollback and API allow/deny receipts.", + "accepted_task_id": null, + "acceptance": "Not observed; exact owner source task and revision must be returned." + }, + { + "repo": "key-cape", + "message_id": "85bf4765-35cc-418f-903b-2dba64e8a06b", + "responsibility": "Public PKCE and distinct agent registration contract, claims/audience/scope, issuance/expiry and client disablement.", + "accepted_task_id": null, + "acceptance": "Not observed; exact owner source task and revision must be returned." + }, + { + "repo": "net-kingdom", + "message_id": "c6b4dfb0-44d5-4f12-8854-2c38ab6dc454", + "responsibility": "Supported loopback/custom-scope registration outside current browser-RP type; registration and governed per-agent custody with Platform.", + "accepted_task_id": null, + "acceptance": "Not observed; exact owner source task and revision must be returned." + }, + { + "repo": "ops-bridge", + "message_id": "c367f3a2-ceba-4ec9-b241-b917c47ba11e", + "responsibility": "Supported per-caller TLS API transport, individual identity, renewal, cleanup and active connection termination.", + "accepted_task_id": null, + "acceptance": "Not observed; exact owner source task and revision must be returned." + } + ], + "dependency_order": [ + { + "milestone": "M1", + "requires": [], + "deliverable": "Collect reviewed owner source tasks, exact registration/claim contract, governed per-agent custody route, supported per-caller transport and authenticator rollback proposal. Reviews can proceed independently; do not infer rollout authority." + }, + { + "milestone": "M2", + "requires": [ + "M1" + ], + "deliverable": "Owners activate reviewed issuer/registration, API authenticator and per-caller transport in dependency order. Platform integrates one-command login/connect/trial with renewal, actionable failures and cleanup." + }, + { + "milestone": "M3", + "requires": [ + "M2" + ], + "deliverable": "Real human and registered agent independently prove API-returned identity, least-privilege permissions and responsive/keyboard browser trials. Native wrong-audience, missing-scope, expired/tampered and ineligible-identity attempts fail. Prove revocation/active connection termination and retain remaining JWT lifetime limits." + }, + { + "milestone": "M4", + "requires": [ + "M3" + ], + "deliverable": "Platform and provider accept receipts including remaining abrupt-interruption recovery; publish supported docs and update existing capability.infotech.headless-browser managed availability; read back discovery." + } + ], + "first_executable_milestone": "M1: prepared config/playwright candidates and existing owner requests are immediately reviewable; exact source task/acceptance returns are missing.", + "unresolved_user_policy_decision": null, + "eligibility": "All identified platform humans and coding agents already admitted; no repeat membership approval.", + "constraints": [ + "First delivery uses scoped port-forward and supported per-caller API transport; no new gateway required.", + "No shared admin kubeconfig/workstation SSH identity; no Secrets/exec/workload writes/other namespaces or new targets.", + "Human platform login and distinct registered governed agent identities.", + "No synthetic token/admin impersonation acceptance substitute.", + "Client disablement stops issuance; existing JWTs persist to expiry and active connections require termination.", + "No foreign task statuses changed or owner approvals invented; no workers injected." + ], + "availability_observed": "Managed pilot running; conditional consumer access. Local provider discovery published via finished REUSE-WP-0024; final managed availability pending." +} diff --git a/workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md b/workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md index e47aeea3..2f7d8413 100644 --- a/workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md +++ b/workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md @@ -409,6 +409,18 @@ No production custody key was retrieved and no live decryption, Secret write or deployment change was performed. Evidence: `docs/evidence/2026-10-13-netkingdom-security/sops-write-callers.json`. +2026-10-13 continuation: privacyIDEA key export/recovery source repaired in +NetKingdom commit 1cbe00fd78e60ac70f2ea7957a0e1d7477388dcf. Export preserves the existing encryption/audit +keys, validates private custody and exact pod/PVC ownership, and conditionally +creates or verifies DR Secrets. Recovery now restores the actual stopped +application PVC; old Secret-only and unmounted-helper instructions are withdrawn. +The unchanged tested source passed 631 tests, zero skips; actual privacyIDEA +3.12.2 decryption and audit-signature continuity passed in a disposable local +environment. All 15 applied paths match the test binding. This is not live cluster +or off-host recovery acceptance. NK-WP-0049-T02 remains progress for remaining +callers/inventory; T03 remains wait for owner-approved native recovery. Receipt: +`docs/evidence/2026-10-13-netkingdom-security/privacyidea-key-custody.json`. + ## Verify native closure against every requirement ```task @@ -424,3 +436,41 @@ requirement ledger. Existing owner integration, attendance, residual-promotion and recovery gates remain effective. Mark finished only when all required gaps are verified closed or covered by complete actually approved exceptions; plans, source-only tests and owner handoffs are not closure evidence. + +## Coordinate self-service Playwright identity delivery + +```task +id: CUST-WP-0080-T05 +status: progress +priority: high +depends_on: [RPF-WP-0056, RAPP-PLAYWRIGHT-WP-0004] +``` + +User-requested addition on 2026-10-13. Accountable coordinating owner: +**the-custodian / custodian-codex**. Accept incoming request +`1b279bad-a159-43da-8709-1167882e62f8`; retain Platform's RPF-WP-0056-T03 +live acceptance and RAPP-PLAYWRIGHT-WP-0004-T01/T03 provider acceptance. +Delivery tracking: `infra/security-flow/playwright-delivery.json`, a cross-owner +case attached to these existing plans; no duplicate implementation plan. + +The pilot and namespace RBAC are delivered. Real human/agent authentication, +per-caller API transport, one-command trial, renewal/revocation and native +acceptance remain. All identified platform humans and coding agents already +qualify; no further membership decision is requested. The coordinator owns +collecting exact owner task/revision returns, resolving dependency gaps and +checking delivery evidence, not approving another owner's implementation. + +First executable milestone: review the prepared registration/authenticator +candidates with their existing owners, obtain their source task/revision and +rollback references, and document a supported transport for one real human and +one registered agent. Registration and governed custody (KeyCape/NetKingdom/ +Platform), native JWT authenticator (railiance-cluster), and per-caller transport +(ops-bridge/cluster) converge before Platform's integrated consumer command and +real human/agent trials. Existing request IDs and unaccepted owner returns are +preserved in the case; missing task IDs are explicit gaps, not invented commitments. + +Close only after Platform and provider accept native positive/negative identity, +permission, browser, lifecycle and recovery receipts, supported consumer docs, +and the maintained managed-availability discovery update. Message delivery alone +does not close this task. No new access gateway, shared administrator kubeconfig, +shared workstation SSH identity, or broader target/permission grant is required.