Implement Control Plane backend: rights enforcement + audit log (WP-0009-T03)
migrations/0006_control_plane.sql: control_plane_audit_log (append-only, no UPDATE/DELETE for trf_app) and control_plane_proposed_entries (the Contributor tier's "propose, don't append" workflow from concept §2) - review decisions go through a review_proposed_entry() SECURITY DEFINER function, same governance-action pattern as set_extension_status/revoke_credential, not a direct UPDATE. src/target_revenue/control_plane.py is the enforcement layer concept §2 called for: register_phase/append_development_credit require Operator+; propose_ledger_entry requires Contributor+ and stores a pending proposal without touching the real Ledger; approve_proposed_entry (Operator+) appends it under the *reviewer's own* credential/attribution (not the original proposer's - the reviewer is who's authorizing it into the real Ledger, while the proposer stays on record in the proposal row and audit log); reject_proposed_entry (Operator+) discards it. issue_/ revoke_user_credential (Admin+) wrap registry.py's T02 functions with the same rights check and audit logging. Every action funnels through record_audit_event, independent of the Trust Service's own signed records. tests/test_control_plane.py (12 tests): rights enforcement at each tier boundary, the full propose -> approve -> appended-under-reviewer flow, propose -> reject -> nothing appended, double-review rejection, audit log content/attribution, DB-level UPDATE rejection on both new tables. Full suite: 84 offline (unchanged), 53 with Docker (up from 41); no stray containers left running.
This commit is contained in:
parent
d29447fcff
commit
885da0a1cb
6 changed files with 756 additions and 2 deletions
|
|
@ -143,7 +143,7 @@ suite: 84 passing offline (unchanged), 41 passing with Docker (up from
|
|||
|
||||
```task
|
||||
id: TREV-WP-0009-T03
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "86a58e61-dccd-4678-b694-22a9eaea2b3c"
|
||||
```
|
||||
|
|
@ -156,6 +156,37 @@ the Trust Service's own signed record id for that action. This is the
|
|||
piece that must exist before any write-capable UI flow (T04) can be built
|
||||
responsibly.
|
||||
|
||||
**Result:** `migrations/0006_control_plane.sql` adds
|
||||
`control_plane_audit_log` (append-only, no UPDATE/DELETE grant for
|
||||
`trf_app`) and `control_plane_proposed_entries` (the Contributor tier's
|
||||
"propose, don't append" workflow from concept §2 — review decisions go
|
||||
through a `review_proposed_entry()` SECURITY DEFINER function, same
|
||||
governance-action pattern as `set_extension_status`/`revoke_credential`,
|
||||
not a direct UPDATE). `src/target_revenue/control_plane.py` is the
|
||||
enforcement layer concept §2 called for: `register_phase`/
|
||||
`append_development_credit` require Operator+; `propose_ledger_entry`
|
||||
requires Contributor+ and stores a pending proposal rather than touching
|
||||
the real Ledger; `approve_proposed_entry` (Operator+) appends it — under
|
||||
the *reviewer's own* credential/attribution, not the original proposer's,
|
||||
since the reviewer is the one authorizing it into the real Ledger, while
|
||||
the proposer stays on record in the proposal row and audit log;
|
||||
`reject_proposed_entry` (Operator+) discards it with nothing appended.
|
||||
`issue_user_credential`/`revoke_user_credential` (Admin+) wrap
|
||||
`registry.py`'s T02 functions with the same rights check and audit
|
||||
logging. Every action funnels through `record_audit_event` — actor
|
||||
credential label, action, Phase, and (where applicable) the resulting
|
||||
Trust Service record id, independent of the Trust Service's own signed
|
||||
records.
|
||||
|
||||
`tests/test_control_plane.py` (12 tests): rights enforcement at each
|
||||
tier boundary (Viewer can't register, Contributor can't append directly
|
||||
or review, non-Admin can't issue credentials), the full propose → approve
|
||||
→ appended-under-reviewer's-credential flow, propose → reject → nothing
|
||||
appended, double-review rejection, audit log content and attribution, and
|
||||
DB-level UPDATE rejection on both new tables. Full suite: 84 passing
|
||||
offline (unchanged), 53 passing with Docker (up from 41); no stray
|
||||
containers left running.
|
||||
|
||||
## Control Plane interactive UI: Phase registration and Development Credit entry
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue