Answer who presents approval-engine-operator: nobody
railiance-platform asked and declined to guess, which was right — this registration carries the widest scope set of the pair. Nothing in this repo obtains an OAuth token; it only verifies them. Scope by scope the bundle describes no single actor: approve now belongs to informed-decision's human client, emit is redundant against the server's own heartbeat, and no requester identity was ever settled for create. Cancel CCR-2026-0020 as an owner decision rather than leave it in_flight, keep verifier custody CCR-2026-0018, and record that a future presenter gets a narrowed registration — approve must not travel with the operational scopes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe Assistant: claude-code Assistant-Model: opus Assistant-Process: 1275879@bnt-lap001 Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
This commit is contained in:
parent
fec4eaeb1b
commit
849c75bb09
2 changed files with 68 additions and 1 deletions
|
|
@ -116,7 +116,54 @@ clients:
|
|||
|
||||
Human approvers use the existing KeyCape human flow with `approval:approve`
|
||||
only, still with `aud=approval-engine`. They must not receive
|
||||
`approval:consume`.
|
||||
`approval:consume`. As of 2026-09-09 that flow is `informed-decision`'s
|
||||
(`INFD-WP-0001`); see `docs/approver-surface-requirements.md`.
|
||||
|
||||
## `approval-engine-operator` — requested, unpresented, do not provision
|
||||
|
||||
Answering `railiance-platform` (`RPF-WP-0035-T06`, `CCR-2026-0020`) 2026-09-09.
|
||||
Their question was the right one and we could not answer it from this source
|
||||
either, because the answer is *nobody*.
|
||||
|
||||
**Nothing in this repository presents this client, and nothing is deployed that
|
||||
could.** This engine only *verifies* bearer tokens; it never obtains one. The
|
||||
sole outbound credential it holds is the mounted `audit-token` used for
|
||||
audit-core delivery (`approval_engine/audit.py`), which is not an OAuth client.
|
||||
`approval_engine/pep.py` is a consumer-side helper for PEPs such as
|
||||
`secrets-engine`, which present their own tokens. There is no client-credentials
|
||||
grant anywhere in the package, and `deploy/approval-engine.yaml` is unapplied.
|
||||
|
||||
Scope by scope, the bundle we originally requested does not describe one actor:
|
||||
|
||||
| Scope | Who would present it |
|
||||
| --- | --- |
|
||||
| `approval:create` | whoever *requests* an approval. Not named anywhere in the estate today; `gate-house` doctrine says which acts need one, but no requester identity has been settled |
|
||||
| `approval:approve` | `informed-decision`'s **human** client, per its own registration. A service principal holding this is exactly the question `gate-house` has not ruled on — see the `principal_type` note below |
|
||||
| `approval:read` | anything rendering or inspecting an approval |
|
||||
| `approval:revoke`, `approval:supersede` | attended lifecycle operations |
|
||||
| `approval:observe` | monitoring and operations |
|
||||
| `approval:emit` | **redundant in normal operation** — the running server emits its own heartbeat on `--heartbeat-seconds` with no token; the route exists only to force one |
|
||||
|
||||
So this was a convenience bundle written when this repo assumed a single
|
||||
"lifecycle operator" would exist, and it aged badly: it now carries the widest
|
||||
scope set in the pair, including `approval:approve`, for an identity nobody has
|
||||
named.
|
||||
|
||||
**Decision, option (b): cancel `CCR-2026-0020`.** No client-side reader is
|
||||
wanted, because there is no presenter. This is an owner decision and not a
|
||||
deferral — recorded here so the request does not rot `in_flight`. Verifier
|
||||
custody (`CCR-2026-0018`) is unaffected and remains correct: KeyCape must be
|
||||
able to *authenticate* this client if it is ever presented.
|
||||
|
||||
When a presenter is actually named, the registration should be re-requested
|
||||
**narrowed to that presenter's scopes**, not reinstated as this bundle. In
|
||||
particular `approval:approve` should not travel with the operational scopes:
|
||||
schema v4 records `entries.principal_type` so a service bind is legible, but
|
||||
legibility is not permission, and whether a non-human may supply approver
|
||||
evidence at all is `gate-house`'s to rule on.
|
||||
|
||||
`secrets-engine-approval` above is unaffected — it has a real presenter, a
|
||||
narrow scope pair, and is the client that unblocks `T05`.
|
||||
|
||||
## Human approver client — not supplied (2026-09-08)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue