railiance-platform/docs/credential-lane-designs/state-hub-preflight-signing.md
codex 5d6d8724b4
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Complete live State Hub signing activation and rotation acceptance
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
2026-09-05 18:12:37 +02:00

7.6 KiB

State Hub repository-rename preflight signing lane

Status: active; accepted 2026-09-05. Owner: railiance-platform, RPF-WP-0035-T04. CCR-2026-0015 is active at key version 2. See state-hub-preflight-activation.md for the accepted implementation and evidence. Demand: State Hub message cd52ba10-de41-46ce-aa8b-9b44050da8f7, STATE-WP-0085-T09. Provisioning this lane does not authorize any repository rename.

Current consumer contract

../state-hub/api/config.py loads REPOSITORY_RENAME_PREFLIGHT_SECRET once through module-level settings; token TTL defaults to 900 seconds. api/services/repository_rename.py signs canonical payloads with HMAC-SHA256 and verifies with the same single key plus an expiry check. Missing configuration denies mutation-token issuance while the read-only report remains available. There is no multi-key verification or live secret reload in this implementation.

The source chart is ../state-hub/deploy/railiance/apps/charts/state-hub: API container state-hub, service account state-hub, existing env Secret state-hub-env. Namespace/release and live primary/railiance01 binding must be confirmed against deployed metadata before apply. The sibling chart is source evidence, not a claim that every live value matches its defaults.

Proposed custody and delivery

Object Proposed contract
KV mount / CLI path platform / platform/workloads/state-hub/repository-rename-preflight
KV field REPOSITORY_RENAME_PREFLIGHT_SECRET
Generation At least 32 random bytes from a CSPRNG, encoded as 64 lowercase hex characters; generate in the approved protected writer, never print
Read policy workload-kv-read-state-hub-rename-preflight: read only on the one exact data path
Kubernetes auth Existing reviewed mount kubernetes; new role state-hub-rename-preflight-eso
Auth identity Proposed dedicated service account state-hub-preflight-eso in state-hub; exact audience openbao subject to TokenReview/ESO compatibility proof
Token bounds TTL/max/explicit max 15m, no default or periodic policy; no write/admin policy
ESO scope Namespace-scoped SecretStore openbao-state-hub-rename-preflight, dedicated ExternalSecret of the same workload scope
K8s target Separate Secret state-hub-rename-preflight, field mapped to the exact environment name
Runtime binding Explicit secretKeyRef in API Deployment only; required/non-optional

Use the native OpenBao data GET for delivery. If the ESO version requires metadata read, prove that need and review an exact metadata-path addition; never grant parent list. ESO TokenRequest/RBAC and the OpenBao Kubernetes role must agree on service account, namespace and audience. Do not change a shared mount or borrow the existing Forge-derivation role, AppRole SecretID, admin PAT, API token, webhook HMAC or database password.

The new Secret avoids having two controllers own state-hub-env. Its key must not be added to ConfigMaps, general envFrom, Helm values containing plaintext, migration Jobs, MCP containers, or the workstation/fallback Hub. Scope the SecretStore to this namespace and restrict who can create ExternalSecrets or TokenRequests for the delivery identity. Verify the API's explicit env entry takes precedence and remove any stale same-name setting under its original owner's control. Do not overwrite the whole existing shared Secret.

Governed implementation

Create a proposed workload-kv-read CCR through the existing schema once exact deployment bindings are confirmed. Keep the writer separate: the read CCR does not authorize key generation or KV writes. The writer's one-time approved scope is the exact data path with initial CAS zero or current-version CAS for rotation. The API and ESO never get write access. Add coding-agent high-risk boundary denies for data and metadata before provisioning.

Stage and review the policy, auth role, service account/RBAC, SecretStore, ExternalSecret and API chart env entry together. The dedicated Secret should retain its last value if the external source is unavailable; document the ESO target ownership/deletion policy explicitly. A stalled ESO update does not automatically invalidate a key already loaded in a running process. Require green custody/version/rollout evidence before permitting rename operations.

Activation and evidence

State Hub owner confirms the exact primary deployment, TTL and authorized fixture preflight request; platform approves path/field and protected writer; cluster owner accepts ESO bindings and API-only exposure. Record these owner receipts and pinned source revisions before any live mutation.

Create a fresh key in protected custody, project it, verify SecretSynced and safe version metadata, then roll every API replica. Check /state/health and read-only rename preflight against an approved fixture. Any issued preflight token remains in protected memory and must be redacted from evidence. Prove local-fixture signing/verification, tamper rejection, expiry, wrong-key rejection, and no-key denial; the live probe stops before the rename mutation endpoint. Check wrong-SA/namespace/audience, sibling KV and coding-agent denial. Retain only deployment revisions, KV version, boolean outcomes and safe timestamps.

Rotation, revocation and rollback

Fence new preflight issuance AND rename mutation operations at the API's approved operational admission boundary, across all replicas, before switching keys. The current application has no documented rotation fence: the State Hub owner must supply a concrete ingress/admission or controlled-outage procedure before rotation is executable. Merely waiting 900 seconds while issuance continues does not drain old tokens. With issuance stopped, drain the configured maximum token lifetime, or explicitly invalidate outstanding tokens during a coordinated cutover. Generate a new KV version, wait for ESO, restart all API replicas, then verify they use one version and only then reopen operations. A rolling mixture of old/new single-key processes can reject valid preflights unpredictably.

For compromise, invalidate outstanding preflights immediately and remove old key-bearing processes; waiting for natural expiry is not revocation. Disabling ESO alone leaves process memory and K8s copies usable. Forward recovery is preferred: restoring a compromised old key can revalidate still-live tokens. For a non-compromise failed deployment, keep operations fenced and restore the prior chart/key version only with owner approval, then verify all replicas. Keep protected historical KV versions until the retention decision; no automatic destroy, provider rename, or weakening of preflight checks is part of this lane.

Demand review — 2026-09-05

STATE-WP-0085-T09 completed its adoption-plan deliverable on 2026-08-31. The still-proposed FLEX-WP-0020-T05 cutover carries the signing prerequisite. State Hub is now explicitly transitional in its INTENT; State Hub/repo-manager and the migration owner must confirm the target runtime and continued need before provisioning this design. RPF-WP-0035-T04 is the current platform task; RPF-WP-0034 is the archived design record. No demand withdrawal or activation is inferred from retirement planning alone.

Implementation preparation — 2026-09-05

CCR-2026-0015, the exact data-only policy and bounded role, namespace-scoped ESO manifests, silent CAS writer and API-only chart binding are staged. The fresh live fixture has only the signing-unavailable blocker. state-hub-preflight-activation.md supplies the controlled-outage rotation fence and recovery sequence. Live acceptance still requires attended OIDC/MFA; the existing operator session returned 403.