docs: close live approval service registration gate

Assistant: codex
Assistant-Model: gpt-5.6-luna
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
tegwick 2026-09-09 02:18:12 +02:00
parent cf23469ead
commit 3a4fd38c00
3 changed files with 275 additions and 83 deletions

View file

@ -1,89 +1,42 @@
# Approval service clients: prepared rollout
# Approval service clients: live rollout accepted
`KEY-WP-0013-T02/T06`, 2026-09-08. Prepared candidate; **not deployed**.
KEY-WP-0013-T02 is complete on 2026-09-09. Both verifier-side credential requests,
CCR-2026-0017 and CCR-2026-0018, have explicit user approval as platform operator
and KeyCape owner and are now verified. [Live receipt](evidence/2026-09-09-keycape-verifier-admission.json).
The implementation and verification correction are published at `dcebd46`.
Forgejo's image is `main-dcebd46`, with immutable manifest digest
`sha256:7ff54c54e63ee172ae9e6e7fd2da96e427352f712343d74626ee6fe0f6f82611`.
The complete Go suite and `go vet ./...` passed. The registry image was pulled
by digest and its `/keycape verify-client --help` command enumerated the expected
verification options (the Go flag help path exits 1). The verifier is a keycape
subcommand, not a separate `/verify-client` executable. No live credential was
used in these checks.
Both clients run on one ready KeyCape replica using the immutable image
`forgejo.coulomb.social/coulomb/key-cape@sha256:7ff54c54e63ee172ae9e6e7fd2da96e427352f712343d74626ee6fe0f6f82611`.
NetKingdom owns the deployed manifest, `Recreate` strategy, `/readyz` readiness,
and exact client registrations. Both ESO-owned Secrets are synchronized from
OpenBao version 1. The signing key and unrelated configuration bytes are preserved.
Negative evidence now requires the exact token endpoint, issuer error and
feature: scope rejection is HTTP 400 / `invalid_profile_usage` / `scope`;
predecessor rejection is HTTP 401 / `invalid_profile_usage` / `Authorization`.
A timeout, server error, invalid token, JWKS failure or unrelated refusal fails
verification. Provider response bodies and tokens are never printed.
Both clients passed the native verifier from that pinned image and independent
RS256/JWKS verification with exact issuer, audience, subject, tenant, roles,
scopes and a 900-second lifetime. Wrong secrets and excess scopes were refused;
the human OpenBao client was refused `approval:consume`. Existing human OpenBao
login passed before and after cutover, with attended sessions self-revoked.
## Admission inputs
The deployment owner exercised compatible rollback and version-preserving
resume. Its executable procedure and reproducible synthetic HTTPS exercise live
in `net-kingdom:sso-mfa/k8s/keycape/`, documented in
`net-kingdom:docs/keycape-approval-clients-rollout.md`. The verifier runs inside
the existing attended owner process; credentials stay in memory and a child
environment. The pod's internal-only egress policy remains unchanged.
1. Platform `CCR-2026-0017` and `CCR-2026-0018` remain proposed. Their named
platform-operator and key-cape-owner reviews precede any activation.
[provisioning request](approval-engine-provisioning-request.yaml) records the
exact paths, `CLIENT_SECRET` field and Kubernetes/env mappings.
2. The actual signed upstream issuer is now proved as
**`https://auth.coulomb.social`** by the admitted one-shot probe on 2026-09-08
at 21:44:44 UTC. Signature, audience, validity window and nonce passed; the
Job exited 0 and every temporary resource was removed. See
[the live receipt](evidence/2026-09-08-upstream-issuer-live-proof.json).
NetKingdom pinned that exact value in `authelia.issuer` on 2026-09-09
through its exercised issuer-only helper; Secret revision `58713343`.
[Pin receipt](evidence/2026-09-09-upstream-issuer-pin.json) proves all other
config bytes and Secret data unchanged. The running Deployment was unchanged. Prove an existing
human login before and after cutover; the probe established upstream identity
only, while this image also changes redirect and grant binding.
3. The platform-owned attended first-provision command uses only
`warden access openbao-platform-admin-login --exec -- <reviewed-command>`
with its unique metadata-only receipt. It must follow the two CCRs and the
platform rollout document. Do not execute the child directly. The unrelated
interim credential proxy's explicit policy 403 remains WARDEN-WP-0039-T03;
an outage fallback is not permission to get credentials for this rollout.
Containerd readiness matches the manifest in `imageID`. Independent JWT checks
use the native contract's 30-second future-iat bound while retaining strict
not-before and expiry. Natural JWT expiry and actual predecessor rotation were
not exercised by this initial provision and remain required for their relevant
subsequent owner acceptance.
## Prepared deployment change
The original [candidate patch](approval-clients-deployment.patch.yaml) remains a
preparation reference; NetKingdom's manifest is deployment authority. Candidate
Go tests and vet passed previously; this window added eight real local OpenBao
checks, ten configuration/recovery/clock checks, 53 credential-change regressions,
and a complete pinned-image HTTPS/native-verifier exercise with synthetic keys.
[approval-clients-deployment.patch.yaml](approval-clients-deployment.patch.yaml)
is a strategic merge patch for `sso/keycape`, whose deployment source remains
`net-kingdom/sso-mfa/k8s/keycape/deployment.yaml`. Transfer the reviewed changes
into that owning source at the admitted cutover; this file is a preparation,
not a second deployment authority.
It pins the image, adds the two exact Secret references and uses `/readyz` for
traffic readiness while retaining `/healthz` for liveness. `Recreate` ensures
one issuer instance during replacement: [operations.md](operations.md) states
that login sessions and authorization codes are process-local. The old manifest's
default rolling surge can briefly create two instances. Expect a short login
interruption and loss of in-flight login sessions during replacement.
Apply the platform policies/roles, CAS=0 initial custody, two stores and two
ExternalSecrets in their owner-prescribed order; require Valid/SecretSynced
before deploying the reading image and updated client config together. Do not
pre-create ESO-owned Secrets. A dry-run of this patch proves API acceptance of
the object shape only; it cannot prove the referenced Secrets or configuration.
## Acceptance and rollback
Run the two `verify-client` commands from the provisioning request through the
admitted protected delivery. In addition to the tool's checked signature,
issuer, audience, subject, tenant, scopes and required roles, record independent
verification of the exact role set and `exp - iat = 900`: the tool's
`expect-roles` checks inclusion and does not itself establish the 15-minute
lifetime. Initial provisioning has no real predecessor to revoke; test a wrong
secret and retain predecessor rejection for an actual subsequent rotation.
Retain expiry/revocation and excessive-scope evidence, and platform cross-path,
wrong-service-account, outside-namespace and parent-listing denials.
Before mutation the deployment/configuration owner retains the previous image,
configuration revision and Secret metadata through its protected recovery path.
On failed readiness or existing-human-login regression, restore that compatible
configuration/image pair (`main-153258b` is the observed prior image), then
follow the platform document's ExternalSecret/policy rollback. An image-only
revert does not restore the changed client configuration. Keep custody versions
until registrations are explicitly disabled; never destroy as incidental cleanup.
These CCRs supply **verifier-side copies only**. Client-side read lanes, the
approval audit sender credential and live claim/consume proof remain open in
RPF-WP-0035-T05, AUDIT-WP-0009-T09, APPROVAL-WP-0002 and GLAS-WP-0015's
existing coordination chain. The human UI's real callback and MFA proof remain
KEY-WP-0013-T05; they do not block these independent service registrations.
KEY-WP-0013-T05 retains the real approval UI callback and MFA/PKCE proof.
RPF-WP-0035-T05 retains separate client-side credential delivery; AUDIT-WP-0009-T09
retains audit custody. APPROVAL-WP-0002 and SECRETS-WP-0009-T03 retain deployed
claim/consume, expiry/revocation and native credential delivery. These verifier
copies do not grant client retrieval or factory execution/spending.

View 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
}