RBAC Improvements

Caching improvements
Maker-Checker Implementation
This commit is contained in:
2026-10-21 07:27:47 +02:00
parent dee9098379
commit 5d7e2f74ce
25 changed files with 1269 additions and 309 deletions
+14 -1
View File
@@ -116,7 +116,7 @@ PostFundManagement/
### 2.3 Infrastructure, Storage & Security Topology
* **Database**: PostgreSQL 14+ (Separate connection strings for primary transactional store `pfm` and scheduler store `pfm-scheduler`).
* **Object / Evidence Store**: S3-compatible storage (e.g., Garage S3 / AWS S3) with pre-signed upload URLs and CDN acceleration.
* **Cache**: Redis (`StackExchange.Redis` + ASP.NET HybridCache) for dashboard KPIs and taxonomy lookup caching.
* **Cache**: Redis (`StackExchange.Redis` + ASP.NET Core `OutputCaching` 2-minute base policy on Minimal API GET endpoints + HybridCache). Paired with TanStack React Query in `ConsoleUI` and Axios mutation versioning (`_v` parameter) to guarantee instant reads and zero stale data after mutations.
* **Authentication / STS**: Duende IdentityServer / Skoruba Administration (`https://sts.security.khongisa.co.za`).
* **Observability**: OpenTelemetry exporters streaming traces, metrics, and logs to Aspire Dashboard / OTLP collectors.
@@ -554,6 +554,19 @@ The following baseline mappings define the claims assigned to system roles:
* Endpoints inspect JWT claims (`role_claim:<claim_name>` or array claims) to enforce authorization before executing command/query handlers.
* Violations immediately return `403 Forbidden` and log an audit security event (`NFR-004`, `AT-13`).
### 10.5 Maker-Checker Segregation of Duties Pattern
In addition to RBAC role and claim constraints, the platform enforces the **Maker-Checker Pattern** across all operational lifecycle modules:
* **Separation of Duty Rule**: **The user who creates or drafts a record (the "Maker") is strictly barred from verifying or approving that record (the "Checker"), regardless of their role or administrative privileges.**
* **Attribution**: Every domain entity immutably captures the creator's user identifier in `createdBy` (Guid/Subject ID resolved from `context.GetUserId()`).
* **Evaluation Formula**:
$$\text{Can Approve} = \text{Has 'update' claim permission} \land (\text{Authenticated User ID} \neq \text{Record createdBy})$$
* **Client UI Enforcement**:
* Components use `const { canApproveRecord, isMaker, getApprovalRestrictionReason } = useRbac()`.
* Status transition dropdowns disable the `Approved` / `Active` option when `!canApproveRecord(claim, record.createdBy)` with contextual indicator `(Maker-Checker: Cannot approve own record)`.
* Fast-track approval buttons (budget lines, disbursement tranches, evidence submissions, change requests) are hidden or marked with a Maker-Checker warning badge when inspected by the creator.
---
## 11. Functional API Surface & Endpoint Catalog