railiance-platform/docs/keycape-issuer-eso-contract.md
codex 104ed90f42
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
feat: declare proposed fixed KeyCape issuer ESO source contract
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1468b-63fa-7710-85dc-8f2e16b3ebfa
2026-10-17 20:36:52 +02:00

4.5 KiB

Proposed fixed issuer ESO contract — RPF-1.3-T4 / NK48-R5-F2

Status: proposed source; not admitted, deployed, or owner-acknowledged. This is a new Platform declaration for review, not an existing Forgejo grant discovery.

The only substitution in manifests/templates/keycape-issuer-eso.yaml (sha256:e17498bd8a4c820041a4105e4efe9c60c6a50953db8f621ff54887080065c743) is the admitted client_id. The proposed issuer store is ClusterSecretStore openbao-keycape-{client_id}-issuer, cluster scoped (no metadata namespace), restricted by conditions to ExternalSecrets in sso. For Forgejo it is openbao-keycape-forgejo-issuer. The suffix makes the issuer purpose explicit and keeps type-admitted IDs ending in - representable. The store's DNS subdomain name can exceed 63 characters; the existing adapter's 63-character target Secret reference bound is preserved (client ID at most 48). No type parameter is added or changed.

The provider is http://openbao.openbao.svc:8200, KV v2 mount platform, Kubernetes auth mount kubernetes, role external-secrets-keycape-{client_id}, serviceAccountRef external-secrets/external-secrets, audience openbao. CCR-2026-0041 already records that Forgejo role/identity/audience, not this new store name or an unrestricted client family grant. Other clients still require their own existing owner-controlled role/case admission.

The ExternalSecret is sso/keycape-{client_id}-client, references precisely that ClusterSecretStore, refreshes every 5m and targets the same name with Owner creation and Retain remote deletion. Its only data entry maps client-secret from remoteRef workloads/keycape/{client_id}, property CLIENT_SECRET. The provider mount plus mount-relative remoteRef equals custody reference platform/workloads/keycape/{client_id}; do not double-prefix platform/. This is distinct from the Apps-owned consumer namespace SecretStore openbao-keycape-{client_id}-consumer and its dedicated consumer identity.

Store provisioning belongs to Platform's separate owner-controlled path. The proposed platform-secret-delivery lane retains ONLY create/get/watch/delete on the exact ExternalSecret in sso; this source does not delegate store creation or Secret read/list. Never apply the multi-document template through that lane. The pure scripts/keycape_issuer_eso.py module exposes only the ExternalSecret document through external_secret() and validates fixed public observations through require_fixed_store() and require_ready_delivery(). It performs no API call and issues no evidence/receipt. It is not a real capability or admission boundary; a caller-supplied observation alone establishes no authenticity.

The existing RPF-1.3-T4 delivery binding must validate the case/client binding, verify this exact preexisting store's public identity/spec/Ready state, apply or compare the exact ExternalSecret, and wait for matching spec plus Ready=True. The proposed helper accepts extra controller metadata but deliberately refuses spec drift. Actual API defaulting/normalization and installed ESO schema support must be checked in that implementation; these fixtures establish no native compatibility or credential isolation. ESO's shared controller remains trusted. No Secret bodies, values, arbitrary remoteRefs, or raw errors may enter receipts.

Existing owner requirements remain: closed netkingdom.deliver-secret.v1 metadata receipt with authenticated before/after UID/resourceVersion provenance, unchanged objects reported NO_CHANGE, attempt-session revocation, and created-only rollback guarded by exact UID/resourceVersion (drift or uncertain ownership goes to owner reconciliation). The helper neither deletes a target Secret nor creates an OpenBao role/policy nor changes CCR-0041. These capabilities and catalog routing remain unimplemented/unaccepted under RPF-1.3-T4. Independent Platform source review of this declaration precedes adopting the conditional NetKingdom type text; no descriptor acceptance, acknowledgment, pin, grant, catalog or native permission is inferred.

Grounding: CCR-2026-0041 exact role/identity; the approved historical docs/provisioning-windows/2026-10-04-1000/keycape/eso.draft.yaml issuer ClusterSecretStore and target pattern; scripts/catalog_lane_scaffold.py ClusterSecretStore/namespace restriction and mount-relative remoteRef model; RPF-1.3-C1 and RPF-1.3-T4 in the frozen owner review. The scaffold's historical audience field placement differs from the issuer draft; this candidate uses the issuer draft's serviceAccountRef.audiences, not a claim of installed support.