RPF-WP-0061: option A recorded, client guide (T05), fixture independent of live CCR state
All checks were successful
CCR intake gate / gate (push) Successful in 1m11s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 306568@bnt-lap001
Assistant-Session: 8bdf8150-ea56-41e7-9132-13f04f6b0b91
This commit is contained in:
codex 2026-10-18 12:48:35 +02:00
parent 45c8d9370e
commit 04f18c8c73
4 changed files with 86 additions and 6 deletions

View file

@ -303,3 +303,61 @@ Use the whynot-design npm token lane as the pilot:
Once that path feels good, reuse it for the sibling workload-KV lanes and the
credential broker's OpenBao token-role gates.
## Self-Service Intake (RPF-WP-0061)
Clients file standard CCRs without a railiance-platform worker session. The
platform's judgement is in [`registry/ccr-standard-profile.yaml`](../registry/ccr-standard-profile.yaml);
`review-standard` applies it, and `.forgejo/workflows/ccr-intake.yaml` re-checks
it in CI. Allowed submitters: **ops-mason** only (profile `submitters`).
**In profile** means: a `workload-kv-read` lane on mount `platform`; one exact path
`platform/workloads/<a>/<b>[/<c>]` or `platform/suppliers/<supplier>/<account>`;
`metadata_read: false`; a policy file equal to the generated HCL; Kubernetes auth
with role `external-secrets-*`, audience `openbao`, all ttls 15m or less,
`token_no_default_policy: true`; one service account in one non-platform
namespace; risk `low` or `medium`; and no other live CCR reading the path.
Everything else (OIDC roles, AppRole, token roles, second readers, high risk)
still goes to the `railiance-platform` inbox.
### Client steps
Run these in a railiance-platform checkout that is up to date with `main`:
```bash
# 1. File the draft. Allocates the CCR id, copies the policy, runs the review.
python3 scripts/credential-change.py submit \
--ccr <draft.yaml> --policy <policy.hcl> --slug <slug> \
--requester ops-mason --push --notify
# [NEEDS-PLATFORM] lines mean out of profile: stop. --notify messaged
# railiance-platform. Do not edit the review comment to get past it.
# 2. Wait for the "CCR intake gate" run on ccr/<id>-<slug> to pass, then
# fast-forward main to it. Never merge a red or unchecked ccr/* branch.
git switch main && git merge --ff-only ccr/<id>-<slug> && git push origin main
# 3. Open the founder decision and commit the decision id.
python3 scripts/credential-change.py request-decision <id>
git commit -m "<id>: request founder decision" -- credential-change-requests/<id>-<slug>.yaml
git push origin main
```
After step 3, the client waits. The **founder** resolves the State Hub decision.
Then a **platform session or the founder** runs `sync-decision <id>`. Clients do
not run `sync-decision` on their own CCRs. State Hub does not authenticate who
resolved a decision (`decided_by` is free text). Until founder approval can be
verified (RPF-WP-0061 follow-up B), the sync must come from someone other than
the requester. After the CCR is `approved`, the usual steps apply:
`confirm-binding` against native state, apply (ops-mason under
ops-mason-construct for in-profile lanes, otherwise the applier), then
`record-evidence`.
### Known limits
- All workstation agents push to Forgejo as the same account, so `ccr/*`
cannot yet be restricted to ops-mason. The submitter list and the
merge-only-green rule are enforced by tooling and convention, not by Forgejo.
The main-branch `check-ids` job and `check-branch` detect violations after the
fact (follow-up C).
- The automated review is a source review only. It never sets `approved` and
never touches OpenBao.