π‘οΈ Demo resource and PBAC boundaries
The Demo Application (packaged demo web UI, demo API, and the all-in-one reference deployment) is a stand-in resource (web app, API, data) used to showcase Control Core policy-driven PBAC. It should feel like a production system, but must not replace the Control Plane + Bouncer + Rego enforcement chain.
π What belongs in the Demo App (resource)
Use the Demo App to increase fidelity and realism without stealing decisions from policy:
- Data model and payloads β schemas, nested objects, realistic fields, seed data, migrations (when needed).
- Contract clarity β stable JSON shapes the UI can render; optional client-side mapping when the wire format is flat (presentation only).
- Workflows β pages, forms, AI flows, latency/scale simulation, feature flags for UX (not for authorization outcomes).
- Authentication substrate β login, JWT issuance, session tables (who is this subject), password hygiene.
- Observability β logs, metrics, correlation IDs (generic; no resource-specific bouncer internals).
π What must stay out of the Demo App (resource)
Do not implement authorization, entitlement, or policy outcomes in the resource:
- No resource-side access control β do not deny, filter, or hide sensitive data based on
role,department, or other attributes in application code when that outcome is meant to demonstrate PBAC. Express that in Rego and enforce at the bouncer. - No resource-side masking/redaction for showcase paths β do not add new calls to financial masking utilities from routers or middleware except the single canonical module reserved for legacy/helpers (
app/utils/data_masking.py). Prefer policy-driven response mutation at the PEP. - No parallel policy engine β do not encode βif user is HR then β¦β business rules that duplicate what a policy is supposed to prove in a demo.
Authentication vs authorization: verifying a token and attaching a User record is fine. Using role in the resource to change what data leaves the API for showcase scenarios is not (that is PBAC drift).
π Release discipline (avoid βpolicy failure by app fixβ)
Before merging Demo App changes that touch sensitive domains:
- Baseline β with policies off (or bypass path), the app behaves like an intentionally open resource (per demo design).
- Delta β with policies on, the same build shows the policy effect (allow, deny, mask) via the bouncer.
- If a bug is βfixedβ only by changing the resource to hide data or deny access, revisit β the fix likely belongs in Rego or context attributes, not app logic.
π Automated enforcement (CI)
The repository runs a drift check on every CI lint pipeline:
- Script:
quality/demo-app/scripts/check_demo_resource_enforcement_drift.py - Wrapper:
quality/demo-app/scripts/check_demo_resource_enforcement_drift.sh
It fails if new Python code under the demo API service app/ tree (including any mirrored copy in a reference deployment) imports app.utils.data_masking outside app/utils/data_masking.py (file path: utils/data_masking.py under that app/ tree), or references financial masking helpers outside that module.
Extend the checker deliberately if you add new classes of forbidden patterns (e.g. new helper modules that reintroduce resource-side masking).
π Related documentation
- Demo Application Guide
- PBAC best practices
- Internal architecture documentation β Demo App and policy independence (product engineering source of truth)
- Cursor rule:
.cursor/rules/control-core-demoapp-isolation.mdc