Document credential lane designs and adopt fast projection sync
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
This commit is contained in:
parent
4c70fa83c5
commit
193b1276f3
9 changed files with 486 additions and 18 deletions
104
docs/credential-lane-designs/state-hub-preflight-signing.md
Normal file
104
docs/credential-lane-designs/state-hub-preflight-signing.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# State Hub repository-rename preflight signing lane
|
||||
|
||||
Status: proposed, not provisioned. Owner: railiance-platform, RPF-WP-0034.
|
||||
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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue