feat: accept KeyCape approval clients with tested recovery
Assistant: codex Assistant-Model: gpt-5.6-luna Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
parent
ce826cfa8d
commit
303a584bd0
8 changed files with 810 additions and 20 deletions
316
docs/evidence/2026-09-09-keycape-activation-attempts.json
Normal file
316
docs/evidence/2026-09-09-keycape-activation-attempts.json
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
{
|
||||
"attempts": [
|
||||
{
|
||||
"schema": "platform.keycape-approval-custody.v1",
|
||||
"status": "failed",
|
||||
"lanes": [],
|
||||
"started_at": "2026-09-08T23:34:28.315053+00:00",
|
||||
"credential_values_emitted": false,
|
||||
"client_side_read_admitted": false,
|
||||
"keycape_rollout_completed": false,
|
||||
"error": "command_failed",
|
||||
"finished_at": "2026-09-08T23:34:28.559853+00:00"
|
||||
},
|
||||
{
|
||||
"schema": "platform.keycape-approval-custody.v1",
|
||||
"status": "failed",
|
||||
"lanes": [
|
||||
{
|
||||
"ccr": "CCR-2026-0017",
|
||||
"source_sha256": "dc2bbd86e213edecc2f2f91a99d0f51136e9a0853a90e55f65dda2b942305416",
|
||||
"policy_applied": true,
|
||||
"role_applied": true,
|
||||
"custody_seeded": true,
|
||||
"kv_version": 1,
|
||||
"request_id": "94c98373-33fa-591d-c201-d36dddf9879b",
|
||||
"native_reader_verified": true,
|
||||
"cross_path_denied": true,
|
||||
"parent_listing_denied": true,
|
||||
"auth_ttl": 900,
|
||||
"reader_revocation_verified": true,
|
||||
"wrong_service_account_denied": true,
|
||||
"coding_agent_deny_wins": true,
|
||||
"store_ready": true,
|
||||
"external_secret_ready": true,
|
||||
"delivery_matches": true,
|
||||
"secret_uid": "34502b48-ed5d-4a1d-bc43-aa282392775e",
|
||||
"secret_resource_version": "58736028",
|
||||
"wrong_namespace_denied": true,
|
||||
"outside_namespace_store_denied": true
|
||||
},
|
||||
{
|
||||
"ccr": "CCR-2026-0018",
|
||||
"source_sha256": "99148133ddf1eb15dce3c03862b51dc001818ca3121045035a0b0e5897c55dad",
|
||||
"policy_applied": true,
|
||||
"role_applied": true,
|
||||
"custody_seeded": true,
|
||||
"kv_version": 1,
|
||||
"request_id": "a62ee5c5-b5ba-b7dc-0f51-e6fd8a6dde32",
|
||||
"native_reader_verified": true,
|
||||
"cross_path_denied": true,
|
||||
"parent_listing_denied": true,
|
||||
"auth_ttl": 900,
|
||||
"reader_revocation_verified": true,
|
||||
"wrong_service_account_denied": true,
|
||||
"coding_agent_deny_wins": true,
|
||||
"store_ready": true,
|
||||
"external_secret_ready": true,
|
||||
"delivery_matches": true,
|
||||
"secret_uid": "e6f42c4b-dbca-480d-96a4-c475f1298e7f",
|
||||
"secret_resource_version": "58736036",
|
||||
"wrong_namespace_denied": true,
|
||||
"outside_namespace_store_denied": true
|
||||
}
|
||||
],
|
||||
"started_at": "2026-09-08T23:36:01.727953+00:00",
|
||||
"credential_values_emitted": false,
|
||||
"client_side_read_admitted": false,
|
||||
"keycape_rollout_completed": false,
|
||||
"issuer_pin_revision": "58713343",
|
||||
"phase": "keycape_rollout",
|
||||
"coding_agent_boundary_extended_only_to_new_paths": true,
|
||||
"initial_values_generation": "independent CSPRNG 48-byte values; memory-to-OpenBao stdin only; CAS=0",
|
||||
"namespace_probe_cleanup_requested": true,
|
||||
"keycape": {
|
||||
"existing_human_login_before": true,
|
||||
"protected_recovery_retained": true,
|
||||
"compatible_pair_restored": true
|
||||
},
|
||||
"verifier_delivery_disabled_custody_versions_retained": true,
|
||||
"error": "keycape_readiness_timeout",
|
||||
"finished_at": "2026-09-08T23:39:24.210112+00:00"
|
||||
},
|
||||
{
|
||||
"schema": "platform.keycape-approval-custody.v1",
|
||||
"status": "failed",
|
||||
"lanes": [
|
||||
{
|
||||
"ccr": "CCR-2026-0017",
|
||||
"source_sha256": "dc2bbd86e213edecc2f2f91a99d0f51136e9a0853a90e55f65dda2b942305416",
|
||||
"custody_seeded": false,
|
||||
"existing_version_reused": true,
|
||||
"kv_version": 1,
|
||||
"initial_request_id": "94c98373-33fa-591d-c201-d36dddf9879b",
|
||||
"policy_applied": false,
|
||||
"role_applied": true,
|
||||
"native_reader_verified": true,
|
||||
"cross_path_denied": true,
|
||||
"parent_listing_denied": true,
|
||||
"auth_ttl": 900,
|
||||
"reader_revocation_verified": true,
|
||||
"wrong_service_account_denied": true,
|
||||
"coding_agent_deny_wins": true,
|
||||
"store_ready": true,
|
||||
"external_secret_ready": true,
|
||||
"delivery_matches": true,
|
||||
"secret_uid": "b85ce6bb-45c4-49ab-81c9-e92f001500b2",
|
||||
"secret_resource_version": "58741915",
|
||||
"wrong_namespace_denied": true,
|
||||
"outside_namespace_store_denied": true
|
||||
},
|
||||
{
|
||||
"ccr": "CCR-2026-0018",
|
||||
"source_sha256": "99148133ddf1eb15dce3c03862b51dc001818ca3121045035a0b0e5897c55dad",
|
||||
"custody_seeded": false,
|
||||
"existing_version_reused": true,
|
||||
"kv_version": 1,
|
||||
"initial_request_id": "a62ee5c5-b5ba-b7dc-0f51-e6fd8a6dde32",
|
||||
"policy_applied": false,
|
||||
"role_applied": true,
|
||||
"native_reader_verified": true,
|
||||
"cross_path_denied": true,
|
||||
"parent_listing_denied": true,
|
||||
"auth_ttl": 900,
|
||||
"reader_revocation_verified": true,
|
||||
"wrong_service_account_denied": true,
|
||||
"coding_agent_deny_wins": true,
|
||||
"store_ready": true,
|
||||
"external_secret_ready": true,
|
||||
"delivery_matches": true,
|
||||
"secret_uid": "faad6d54-a6b1-4a3d-9102-4e35aeea67a5",
|
||||
"secret_resource_version": "58741919",
|
||||
"wrong_namespace_denied": true,
|
||||
"outside_namespace_store_denied": true
|
||||
}
|
||||
],
|
||||
"started_at": "2026-09-08T23:54:16.437123+00:00",
|
||||
"credential_values_emitted": false,
|
||||
"client_side_read_admitted": false,
|
||||
"keycape_rollout_completed": false,
|
||||
"issuer_pin_revision": "58737048",
|
||||
"phase": "keycape_rollout",
|
||||
"custody_versions_unchanged": true,
|
||||
"namespace_probe_cleanup_requested": true,
|
||||
"keycape": {
|
||||
"existing_human_login_before": true,
|
||||
"protected_recovery_retained": true,
|
||||
"deployment_uid": "99ddd83c-cb3f-4847-bcf8-35f1aa87627f",
|
||||
"generation": 32,
|
||||
"pod_uid": "28a62a5a-1ac6-4d6c-a1e1-4a414a621559",
|
||||
"single_ready_replica": true,
|
||||
"clients": [],
|
||||
"compatible_pair_restored": true
|
||||
},
|
||||
"verifier_delivery_disabled_custody_versions_retained": true,
|
||||
"error": "contained_operation_failed",
|
||||
"finished_at": "2026-09-08T23:55:02.310001+00:00"
|
||||
},
|
||||
{
|
||||
"schema": "platform.keycape-approval-custody.v1",
|
||||
"status": "failed",
|
||||
"lanes": [
|
||||
{
|
||||
"ccr": "CCR-2026-0017",
|
||||
"source_sha256": "dc2bbd86e213edecc2f2f91a99d0f51136e9a0853a90e55f65dda2b942305416",
|
||||
"custody_seeded": false,
|
||||
"existing_version_reused": true,
|
||||
"kv_version": 1,
|
||||
"initial_request_id": "94c98373-33fa-591d-c201-d36dddf9879b",
|
||||
"policy_applied": false,
|
||||
"role_applied": true,
|
||||
"native_reader_verified": true,
|
||||
"cross_path_denied": true,
|
||||
"parent_listing_denied": true,
|
||||
"auth_ttl": 900,
|
||||
"reader_revocation_verified": true,
|
||||
"wrong_service_account_denied": true,
|
||||
"coding_agent_deny_wins": true,
|
||||
"store_ready": true,
|
||||
"external_secret_ready": true,
|
||||
"delivery_matches": true,
|
||||
"secret_uid": "827b4e04-6727-4dd4-9cdb-2554ecc84441",
|
||||
"secret_resource_version": "58743272",
|
||||
"wrong_namespace_denied": true,
|
||||
"outside_namespace_store_denied": true
|
||||
},
|
||||
{
|
||||
"ccr": "CCR-2026-0018",
|
||||
"source_sha256": "99148133ddf1eb15dce3c03862b51dc001818ca3121045035a0b0e5897c55dad",
|
||||
"custody_seeded": false,
|
||||
"existing_version_reused": true,
|
||||
"kv_version": 1,
|
||||
"initial_request_id": "a62ee5c5-b5ba-b7dc-0f51-e6fd8a6dde32",
|
||||
"policy_applied": false,
|
||||
"role_applied": true,
|
||||
"native_reader_verified": true,
|
||||
"cross_path_denied": true,
|
||||
"parent_listing_denied": true,
|
||||
"auth_ttl": 900,
|
||||
"reader_revocation_verified": true,
|
||||
"wrong_service_account_denied": true,
|
||||
"coding_agent_deny_wins": true,
|
||||
"store_ready": true,
|
||||
"external_secret_ready": true,
|
||||
"delivery_matches": true,
|
||||
"secret_uid": "ca949cda-6a4f-4c24-9a06-6a9c7e00e4aa",
|
||||
"secret_resource_version": "58743276",
|
||||
"wrong_namespace_denied": true,
|
||||
"outside_namespace_store_denied": true
|
||||
}
|
||||
],
|
||||
"started_at": "2026-09-08T23:58:13.955525+00:00",
|
||||
"credential_values_emitted": false,
|
||||
"client_side_read_admitted": false,
|
||||
"keycape_rollout_completed": false,
|
||||
"issuer_pin_revision": "58742089",
|
||||
"phase": "keycape_rollout",
|
||||
"custody_versions_unchanged": true,
|
||||
"namespace_probe_cleanup_requested": true,
|
||||
"keycape": {
|
||||
"existing_human_login_before": true,
|
||||
"protected_recovery_retained": true,
|
||||
"deployment_uid": "99ddd83c-cb3f-4847-bcf8-35f1aa87627f",
|
||||
"generation": 34,
|
||||
"pod_uid": "dabd15a0-f9c3-47f2-82ee-e53590754558",
|
||||
"single_ready_replica": true,
|
||||
"acceptance_phase": "in_pod_verifier",
|
||||
"clients": [],
|
||||
"acceptance_client": "secrets-engine-approval",
|
||||
"failure_class": "LaneError",
|
||||
"compatible_pair_restored": true
|
||||
},
|
||||
"verifier_delivery_disabled_custody_versions_retained": true,
|
||||
"error": "command_failed",
|
||||
"finished_at": "2026-09-08T23:59:06.395926+00:00"
|
||||
},
|
||||
{
|
||||
"schema": "platform.keycape-approval-custody.v1",
|
||||
"status": "failed",
|
||||
"lanes": [
|
||||
{
|
||||
"ccr": "CCR-2026-0017",
|
||||
"source_sha256": "dc2bbd86e213edecc2f2f91a99d0f51136e9a0853a90e55f65dda2b942305416",
|
||||
"custody_seeded": false,
|
||||
"existing_version_reused": true,
|
||||
"kv_version": 1,
|
||||
"initial_request_id": "94c98373-33fa-591d-c201-d36dddf9879b",
|
||||
"policy_applied": false,
|
||||
"role_applied": true,
|
||||
"native_reader_verified": true,
|
||||
"cross_path_denied": true,
|
||||
"parent_listing_denied": true,
|
||||
"auth_ttl": 900,
|
||||
"reader_revocation_verified": true,
|
||||
"wrong_service_account_denied": true,
|
||||
"coding_agent_deny_wins": true,
|
||||
"store_ready": true,
|
||||
"external_secret_ready": true,
|
||||
"delivery_matches": true,
|
||||
"secret_uid": "1e0c888a-c35b-4fe2-8fc5-c510256c19df",
|
||||
"secret_resource_version": "58745995",
|
||||
"wrong_namespace_denied": true,
|
||||
"outside_namespace_store_denied": true
|
||||
},
|
||||
{
|
||||
"ccr": "CCR-2026-0018",
|
||||
"source_sha256": "99148133ddf1eb15dce3c03862b51dc001818ca3121045035a0b0e5897c55dad",
|
||||
"custody_seeded": false,
|
||||
"existing_version_reused": true,
|
||||
"kv_version": 1,
|
||||
"initial_request_id": "a62ee5c5-b5ba-b7dc-0f51-e6fd8a6dde32",
|
||||
"policy_applied": false,
|
||||
"role_applied": true,
|
||||
"native_reader_verified": true,
|
||||
"cross_path_denied": true,
|
||||
"parent_listing_denied": true,
|
||||
"auth_ttl": 900,
|
||||
"reader_revocation_verified": true,
|
||||
"wrong_service_account_denied": true,
|
||||
"coding_agent_deny_wins": true,
|
||||
"store_ready": true,
|
||||
"external_secret_ready": true,
|
||||
"delivery_matches": true,
|
||||
"secret_uid": "50b18e82-6187-47d1-9b07-199f9b999f47",
|
||||
"secret_resource_version": "58745999",
|
||||
"wrong_namespace_denied": true,
|
||||
"outside_namespace_store_denied": true
|
||||
}
|
||||
],
|
||||
"started_at": "2026-09-09T00:06:30.650774+00:00",
|
||||
"credential_values_emitted": false,
|
||||
"client_side_read_admitted": false,
|
||||
"keycape_rollout_completed": false,
|
||||
"issuer_pin_revision": "58743475",
|
||||
"phase": "keycape_rollout",
|
||||
"custody_versions_unchanged": true,
|
||||
"namespace_probe_cleanup_requested": true,
|
||||
"keycape": {
|
||||
"existing_human_login_before": true,
|
||||
"protected_recovery_retained": true,
|
||||
"deployment_uid": "99ddd83c-cb3f-4847-bcf8-35f1aa87627f",
|
||||
"generation": 36,
|
||||
"pod_uid": "011de4b4-c2cd-429d-ba04-e7c72b2f1f9e",
|
||||
"single_ready_replica": true,
|
||||
"acceptance_phase": "signature_and_claims",
|
||||
"clients": [],
|
||||
"acceptance_client": "secrets-engine-approval",
|
||||
"failure_class": "ImmatureSignatureError",
|
||||
"compatible_pair_restored": true
|
||||
},
|
||||
"verifier_delivery_disabled_custody_versions_retained": true,
|
||||
"error": "contained_operation_failed",
|
||||
"finished_at": "2026-09-09T00:07:25.670140+00:00"
|
||||
}
|
||||
],
|
||||
"all_sessions_revoked": true
|
||||
}
|
||||
|
|
@ -1,13 +1,18 @@
|
|||
{
|
||||
"acceptance_phase": "passed",
|
||||
"clients": [
|
||||
{
|
||||
"client_id": "secrets-engine-approval",
|
||||
"live_jwks_signature_verified": true,
|
||||
"exact_claims_verified": true,
|
||||
"lifetime_seconds": 900,
|
||||
"maximum_future_iat_seconds": 30,
|
||||
"expiry_leeway_seconds": 0,
|
||||
"excess_scope_denied": true,
|
||||
"wrong_secret_denied": true,
|
||||
"pod_verify_client_passed": false,
|
||||
"pinned_artifact_verifier_passed": true,
|
||||
"verifier_location": "attended owner process",
|
||||
"verifier_sha256": "4bf93bbe9afe0bf2e21d51c03373a7e2b4be6864586bcc2d472eeb9abc913d92",
|
||||
"real_predecessor_rotation_tested": false,
|
||||
"observed_wall_clock_expiry": false
|
||||
},
|
||||
|
|
@ -16,15 +21,20 @@
|
|||
"live_jwks_signature_verified": true,
|
||||
"exact_claims_verified": true,
|
||||
"lifetime_seconds": 900,
|
||||
"maximum_future_iat_seconds": 30,
|
||||
"expiry_leeway_seconds": 0,
|
||||
"excess_scope_denied": true,
|
||||
"wrong_secret_denied": true,
|
||||
"pod_verify_client_passed": false,
|
||||
"pinned_artifact_verifier_passed": true,
|
||||
"verifier_location": "attended owner process",
|
||||
"verifier_sha256": "4bf93bbe9afe0bf2e21d51c03373a7e2b4be6864586bcc2d472eeb9abc913d92",
|
||||
"real_predecessor_rotation_tested": false,
|
||||
"observed_wall_clock_expiry": false
|
||||
}
|
||||
],
|
||||
"acceptance_client": "approval-engine-operator",
|
||||
"human_client_consume_denied": true,
|
||||
"target": "disposable pinned KeyCape image; synthetic keys and clients only",
|
||||
"pod_cli_verification": "deferred to live in-pod check",
|
||||
"pinned_native_cli_verification": "passed against loopback HTTPS with synthetic credentials",
|
||||
"cleanup_complete": true
|
||||
}
|
||||
|
|
|
|||
220
docs/evidence/2026-09-09-keycape-verifier-admission.json
Normal file
220
docs/evidence/2026-09-09-keycape-verifier-admission.json
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
{
|
||||
"schema": "helixforge.keycape-verifier-admission.v1",
|
||||
"recorded_at": "2026-09-09T00:14:27.155338+00:00",
|
||||
"approval": {
|
||||
"schema": "railiance.keycape-custody-user-approval.v1",
|
||||
"recorded_at": "2026-09-08T23:05:19.886216+00:00",
|
||||
"user_response": "I approve, go on.",
|
||||
"approved_question": "Do you approve CCR-2026-0017 and CCR-2026-0018, as platform operator and KeyCape owner, for the verifier-side credential delivery described in the review packet?",
|
||||
"review_packet_revision": "52b24eab9a8aff3396e71b2296d0240a44f3b0db",
|
||||
"roles": [
|
||||
"platform-operator",
|
||||
"key-cape-owner"
|
||||
],
|
||||
"scope": "Two verifier-side KeyCape client credential custody requests, including their governed attended provisioning and compatible rollout sequence.",
|
||||
"client_side_read_authorized": false,
|
||||
"factory_spending_authorized": false,
|
||||
"requests": [
|
||||
{
|
||||
"id": "CCR-2026-0017",
|
||||
"decision_id": "b533a271-b704-4c5c-98a2-9a5951aadfb6",
|
||||
"status": "approved",
|
||||
"decision_status": "resolved",
|
||||
"reviewed_roles": [
|
||||
"platform-operator",
|
||||
"key-cape-owner"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "CCR-2026-0018",
|
||||
"decision_id": "efa90517-0cae-4eb6-a68d-5b0489c84d65",
|
||||
"status": "approved",
|
||||
"decision_status": "resolved",
|
||||
"reviewed_roles": [
|
||||
"platform-operator",
|
||||
"key-cape-owner"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"activation": {
|
||||
"schema": "platform.keycape-approval-custody.v1",
|
||||
"status": "custody_and_service_acceptance_passed_pending_fresh_human_login",
|
||||
"lanes": [
|
||||
{
|
||||
"ccr": "CCR-2026-0017",
|
||||
"source_sha256": "dc2bbd86e213edecc2f2f91a99d0f51136e9a0853a90e55f65dda2b942305416",
|
||||
"custody_seeded": false,
|
||||
"existing_version_reused": true,
|
||||
"kv_version": 1,
|
||||
"initial_request_id": "94c98373-33fa-591d-c201-d36dddf9879b",
|
||||
"policy_applied": false,
|
||||
"role_applied": true,
|
||||
"native_reader_verified": true,
|
||||
"cross_path_denied": true,
|
||||
"parent_listing_denied": true,
|
||||
"auth_ttl": 900,
|
||||
"reader_revocation_verified": true,
|
||||
"wrong_service_account_denied": true,
|
||||
"coding_agent_deny_wins": true,
|
||||
"store_ready": true,
|
||||
"external_secret_ready": true,
|
||||
"delivery_matches": true,
|
||||
"secret_uid": "eaa28bdf-04af-4e4e-a1fc-fe395c7689a7",
|
||||
"secret_resource_version": "58747058",
|
||||
"wrong_namespace_denied": true,
|
||||
"outside_namespace_store_denied": true
|
||||
},
|
||||
{
|
||||
"ccr": "CCR-2026-0018",
|
||||
"source_sha256": "99148133ddf1eb15dce3c03862b51dc001818ca3121045035a0b0e5897c55dad",
|
||||
"custody_seeded": false,
|
||||
"existing_version_reused": true,
|
||||
"kv_version": 1,
|
||||
"initial_request_id": "a62ee5c5-b5ba-b7dc-0f51-e6fd8a6dde32",
|
||||
"policy_applied": false,
|
||||
"role_applied": true,
|
||||
"native_reader_verified": true,
|
||||
"cross_path_denied": true,
|
||||
"parent_listing_denied": true,
|
||||
"auth_ttl": 900,
|
||||
"reader_revocation_verified": true,
|
||||
"wrong_service_account_denied": true,
|
||||
"coding_agent_deny_wins": true,
|
||||
"store_ready": true,
|
||||
"external_secret_ready": true,
|
||||
"delivery_matches": true,
|
||||
"secret_uid": "599a61a7-8244-4618-8c44-6473195bbe4e",
|
||||
"secret_resource_version": "58747062",
|
||||
"wrong_namespace_denied": true,
|
||||
"outside_namespace_store_denied": true
|
||||
}
|
||||
],
|
||||
"started_at": "2026-09-09T00:09:28.852280+00:00",
|
||||
"credential_values_emitted": false,
|
||||
"client_side_read_admitted": false,
|
||||
"keycape_rollout_completed": true,
|
||||
"issuer_pin_revision": "58746187",
|
||||
"phase": "awaiting_fresh_human_login",
|
||||
"custody_versions_unchanged": true,
|
||||
"namespace_probe_cleanup_requested": true,
|
||||
"keycape": {
|
||||
"existing_human_login_before": true,
|
||||
"protected_recovery_retained": true,
|
||||
"deployment_uid": "99ddd83c-cb3f-4847-bcf8-35f1aa87627f",
|
||||
"generation": 38,
|
||||
"pod_uid": "8d62e972-d466-413e-a2e4-08b9a08016bc",
|
||||
"single_ready_replica": true,
|
||||
"acceptance_phase": "passed",
|
||||
"clients": [
|
||||
{
|
||||
"client_id": "secrets-engine-approval",
|
||||
"live_jwks_signature_verified": true,
|
||||
"exact_claims_verified": true,
|
||||
"lifetime_seconds": 900,
|
||||
"maximum_future_iat_seconds": 30,
|
||||
"expiry_leeway_seconds": 0,
|
||||
"excess_scope_denied": true,
|
||||
"wrong_secret_denied": true,
|
||||
"pinned_artifact_verifier_passed": true,
|
||||
"verifier_location": "attended owner process",
|
||||
"verifier_sha256": "4bf93bbe9afe0bf2e21d51c03373a7e2b4be6864586bcc2d472eeb9abc913d92",
|
||||
"real_predecessor_rotation_tested": false,
|
||||
"observed_wall_clock_expiry": false
|
||||
},
|
||||
{
|
||||
"client_id": "approval-engine-operator",
|
||||
"live_jwks_signature_verified": true,
|
||||
"exact_claims_verified": true,
|
||||
"lifetime_seconds": 900,
|
||||
"maximum_future_iat_seconds": 30,
|
||||
"expiry_leeway_seconds": 0,
|
||||
"excess_scope_denied": true,
|
||||
"wrong_secret_denied": true,
|
||||
"pinned_artifact_verifier_passed": true,
|
||||
"verifier_location": "attended owner process",
|
||||
"verifier_sha256": "4bf93bbe9afe0bf2e21d51c03373a7e2b4be6864586bcc2d472eeb9abc913d92",
|
||||
"real_predecessor_rotation_tested": false,
|
||||
"observed_wall_clock_expiry": false
|
||||
}
|
||||
],
|
||||
"acceptance_client": "approval-engine-operator",
|
||||
"human_client_consume_denied": true,
|
||||
"status": "service_acceptance_passed_pending_fresh_human_login",
|
||||
"image": "forgejo.coulomb.social/coulomb/key-cape@sha256:7ff54c54e63ee172ae9e6e7fd2da96e427352f712343d74626ee6fe0f6f82611",
|
||||
"config_resource_version": "58747126",
|
||||
"signing_key_unchanged": true,
|
||||
"unrelated_config_bytes_preserved": true,
|
||||
"existing_human_login_after": false
|
||||
},
|
||||
"finished_at": "2026-09-09T00:10:09.099481+00:00"
|
||||
},
|
||||
"post_rollout_login": {
|
||||
"schema": "netkingdom.keycape-approval-rollout.v1",
|
||||
"status": "service_and_existing_human_login_acceptance_passed",
|
||||
"values_emitted": false,
|
||||
"deployment_uid": "99ddd83c-cb3f-4847-bcf8-35f1aa87627f",
|
||||
"generation": 38,
|
||||
"pod_uid": "8d62e972-d466-413e-a2e4-08b9a08016bc",
|
||||
"single_ready_replica": true,
|
||||
"acceptance_phase": "passed",
|
||||
"clients": [
|
||||
{
|
||||
"client_id": "secrets-engine-approval",
|
||||
"live_jwks_signature_verified": true,
|
||||
"exact_claims_verified": true,
|
||||
"lifetime_seconds": 900,
|
||||
"maximum_future_iat_seconds": 30,
|
||||
"expiry_leeway_seconds": 0,
|
||||
"excess_scope_denied": true,
|
||||
"wrong_secret_denied": true,
|
||||
"pinned_artifact_verifier_passed": true,
|
||||
"verifier_location": "attended owner process",
|
||||
"verifier_sha256": "4bf93bbe9afe0bf2e21d51c03373a7e2b4be6864586bcc2d472eeb9abc913d92",
|
||||
"real_predecessor_rotation_tested": false,
|
||||
"observed_wall_clock_expiry": false
|
||||
},
|
||||
{
|
||||
"client_id": "approval-engine-operator",
|
||||
"live_jwks_signature_verified": true,
|
||||
"exact_claims_verified": true,
|
||||
"lifetime_seconds": 900,
|
||||
"maximum_future_iat_seconds": 30,
|
||||
"expiry_leeway_seconds": 0,
|
||||
"excess_scope_denied": true,
|
||||
"wrong_secret_denied": true,
|
||||
"pinned_artifact_verifier_passed": true,
|
||||
"verifier_location": "attended owner process",
|
||||
"verifier_sha256": "4bf93bbe9afe0bf2e21d51c03373a7e2b4be6864586bcc2d472eeb9abc913d92",
|
||||
"real_predecessor_rotation_tested": false,
|
||||
"observed_wall_clock_expiry": false
|
||||
}
|
||||
],
|
||||
"acceptance_client": "approval-engine-operator",
|
||||
"human_client_consume_denied": true,
|
||||
"existing_human_login_after": true,
|
||||
"receipt_written_at": "2026-09-09T00:11:59.113549+00:00"
|
||||
},
|
||||
"attended_envelope": {
|
||||
"all_attempted_sessions_revoked": true,
|
||||
"successful_activation_exit_code": 0,
|
||||
"post_rollout_login_exit_code": 0
|
||||
},
|
||||
"validation": {
|
||||
"local_openbao_tests": 8,
|
||||
"configuration_and_recovery_tests": 10,
|
||||
"credential_change_tests": 53,
|
||||
"pinned_image_synthetic_https_and_native_verifier": "passed"
|
||||
},
|
||||
"failed_attempt_receipts": [
|
||||
"net-kingdom:docs/evidence/2026-09-09-keycape-activation-attempts.json"
|
||||
],
|
||||
"limits": {
|
||||
"client_side_read_admitted": false,
|
||||
"factory_spending_admitted": false,
|
||||
"wall_clock_jwt_expiry_observed": false,
|
||||
"actual_predecessor_rotation_observed": false
|
||||
},
|
||||
"temporary_probe_namespaces_remaining": 0,
|
||||
"owner_manifest_api_defaults_match_live": true
|
||||
}
|
||||
78
docs/keycape-approval-clients-rollout.md
Normal file
78
docs/keycape-approval-clients-rollout.md
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
# KeyCape approval-client rollout and recovery
|
||||
|
||||
Accepted 2026-09-09 under CCR-2026-0017 and CCR-2026-0018. Both service
|
||||
registrations are live on one ready KeyCape replica. The existing human OpenBao
|
||||
login passed after replacement. [Live receipt](evidence/2026-09-09-keycape-verifier-admission.json).
|
||||
The [attempt receipts](evidence/2026-09-09-keycape-activation-attempts.json) retain
|
||||
failed checks and confirmed compatible rollback; no failed attempt is counted
|
||||
as activation. Both OpenBao values remain at their initial version 1.
|
||||
|
||||
The source image is the immutable manifest
|
||||
`forgejo.coulomb.social/coulomb/key-cape@sha256:7ff54c54e63ee172ae9e6e7fd2da96e427352f712343d74626ee6fe0f6f82611`.
|
||||
Deployment authority is `sso-mfa/k8s/keycape/deployment.yaml`; the live config
|
||||
remains in `sso/keycape-config`. The contained helper appends only the two
|
||||
reviewed client registrations and preserves the signing key and every unrelated
|
||||
configuration byte. It uses UID/resourceVersion tests for config and deployment
|
||||
mutations, and retains the previous compatible pair in protected owner storage.
|
||||
|
||||
The platform command `scripts/keycape_approval_custody.py` opens through
|
||||
`openbao-attended-exec.py` and the governed Warden `openbao-platform-admin-login`
|
||||
envelope. It owns approved policies/roles, CAS=0 first provision, ESO delivery,
|
||||
native scope/auth/namespace denials and reader revocation. It invokes this
|
||||
repository's `sso-mfa/k8s/keycape/approval-clients-rollout.py` for image/config
|
||||
replacement and service acceptance. Do not run the platform child directly.
|
||||
On this workstation the verified Railiance kubeconfig is
|
||||
`/home/worsch/.kube/config-railiance01`; the default config targets another endpoint.
|
||||
|
||||
Use `activate` only for a first provision with absent custody and delivery.
|
||||
`resume-activate --prior-receipt <metadata receipt>` requires a completed compatible
|
||||
rollback, unchanged version-1 custody, unchanged policies and detached reader roles.
|
||||
It reattaches the same readers without writing any value. Both actions require a
|
||||
unique `--receipt` and `--recovery` path. Successful service acceptance is followed
|
||||
by a fresh attended login running the owner helper's `verify-after-login` action.
|
||||
Existing active custody can be rechecked with the platform helper's `verify`
|
||||
action. Repeating first provision against active custody is deliberately refused.
|
||||
|
||||
The verifier binary comes from the pinned image, without starting its extraction
|
||||
container. Install it in the owner-protected path
|
||||
`~/.local/share/key-cape/verified-bin/dcebd46/keycape` with mode 0700. Its SHA-256
|
||||
must be `4bf93bbe9afe0bf2e21d51c03373a7e2b4be6864586bcc2d472eeb9abc913d92`;
|
||||
the helper checks this before custody mutation and before each verifier run.
|
||||
Extraction needs only `docker create`, `docker cp <container>:/keycape <private path>`,
|
||||
and removal of that never-started container. No credential enters that container.
|
||||
|
||||
Run the native verifier in the existing attended owner process. It receives the
|
||||
same verifier-side credential already read privately for independent JWT checks,
|
||||
through a child environment that is never printed or written to a file. The
|
||||
KeyCape pod's internal-only egress policy does not admit its public HTTPS issuer;
|
||||
this rollout makes no network-policy change. Container readiness checks the
|
||||
manifest digest in `imageID`, since containerd's `image` field can hold a different
|
||||
runtime configuration digest.
|
||||
|
||||
Independent JWT checks match the existing native contract: at most 30 seconds
|
||||
of future issued-at time, strict not-before and expiry, exact audience/subject/
|
||||
tenant/role/scope and a 900-second lifetime. Global JWT leeway is not used.
|
||||
Wrong secrets and excess scopes require the exact issuer HTTP status/error/feature.
|
||||
The public human OpenBao client is also denied `approval:consume`.
|
||||
|
||||
Reproducible preparation checks:
|
||||
|
||||
```sh
|
||||
python3 -B sso-mfa/k8s/keycape/test_approval_clients_rollout.py
|
||||
python3 -B sso-mfa/k8s/keycape/exercise-approval-clients.py --receipt /tmp/<unique-scratch-receipt>.json
|
||||
```
|
||||
|
||||
The second command requires Docker, the installed pinned verifier, PyYAML,
|
||||
PyJWT and cryptography. It runs the pinned image behind loopback HTTPS with
|
||||
synthetic signing keys and client credentials, including the native verifier.
|
||||
It removes its container, TLS server and temporary credential files. It neither
|
||||
reads production config nor opens an attended login. The platform's
|
||||
`tests/test_keycape_approval_custody.py` separately exercises real ACLs, CAS=0,
|
||||
revocation and version-preserving resume against disposable local OpenBao.
|
||||
|
||||
KEY-WP-0013-T02 is complete. KEY-WP-0013-T05 retains the approval UI's callback
|
||||
and MFA/PKCE acceptance. Separate client-side delivery remains RPF-WP-0035-T05;
|
||||
audit custody remains AUDIT-WP-0009-T09; claim/consume and native execution proof
|
||||
remain APPROVAL-WP-0002 and SECRETS-WP-0009-T03. Initial provisioning did not
|
||||
exercise natural JWT expiry or actual predecessor rotation. HFACT-WP-0001 retains
|
||||
factory execution/grant/spend admission and Railiance worker acceptance.
|
||||
Loading…
Add table
Add a link
Reference in a new issue