Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
125 lines
7.6 KiB
Markdown
125 lines
7.6 KiB
Markdown
# 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.
|