Enforce policy where the operation executes#
Matrix provides resource/action permissions, authorized catalog projection and module execution boundaries. The Consumer still implements relevant tenant, record and field policies. A role that can open a page does not automatically have permission to read every row, export every field or mutate every related record.
Record each resource/action/endpoint against anonymous, limited and operator roles in the Product definition. Include queries, lookups, relationships, exports and commands. Keep this table independent of the navigation design and collect direct-call evidence rather than relying only on visible buttons.
| Presentation choice | Security consequence |
|---|---|
| Hide a navigation node | Removes discoverability, not endpoint access |
| Omit a field from a form or grid | Changes presentation, not a universal write allowlist |
| Select a named query scope | Narrows that experience, not every access path |
| Restore preferences or URL filters | Supplies permitted suggestions, not tenant or actor authority |
| Register a module page | Requires separate authorization of its data and operations |
Apply mandatory data scope before filtering, count, aggregate, sort and paging. Reapply it when resolving an entity for editing, a relationship target, a command selection or a report drill. A correct query scope provider cannot compensate for a handler that ignores the supplied scope.
Preserve the authoritative domain boundary#
Determine whether generated EF CRUD is permitted to write the chosen data. When the business requires a domain service, expose a custom handler, command or page over that service. Do not introduce a parallel generic write path that bypasses validation, transactions or history.
Trusted identity comes from authenticated execution context, not a browser-supplied user or tenant value. Sensitive row/field values must be excluded from transport models as well as presentation. Reporting serializes its typed row and totals objects; omitting a column alone does not remove a property from the response.
Record the identity provider, issuer, API audience, Web client, accepted role sources and session/callback requirements. Keep runtime credentials separate from administrative provisioning authority. Product deployment also needs deliberate TLS/proxy trust and persistent cookie/Data Protection keys.
Choose an audit destination and failure policy#
IMatrixAuditSink is an integration boundary. The default null sink persists nothing. Select durable storage, access controls, retention, sanitization and failure handling appropriate to the application. Subject identifiers can themselves be personal data.
Reporting emits sanitized module/resource/action, actor, outcome and correlation information without filters, rows or SQL. Its documented audit-delivery failure withholds the result after a bounded delivery attempt. CRUD mutation events may contain sanitized keys and old/new values. Do not assume all module audit payloads contain metadata only or share one failure policy.
For committed CRUD writes, a later audit/logger failure does not undo the business save. Keep business audit storage separate from general diagnostic logs and test delivery behavior at the actual execution boundary. Request-body logging must not reintroduce information the module deliberately excludes.
Separate diagnostics from receipts#
A support reference helps locate a failure; an operation GUID does not by itself provide durable idempotency. There is no automatic unified trace across every query, save and command. Collect timestamp, exact artifact identity, operation surface and the safe reference without exposing tokens, raw SQL or sensitive input.
For a lost mutation response, consult the owning operation's authorized status/receipt contract. Do not infer rollback from timeout or cancellation, and do not replay an unsafe request merely because logs are missing. Retain receipts beyond the supported recovery window and preserve them across deployment.
Verify the operating boundary#
Test direct denial, cross-user/tenant access, protected fields, concurrent mutation, stale references, missing receipts and the chosen audit failure policy. Partition any Consumer cache by the relevant authorization scope and invalidate it when that scope changes; a hashed cache key is not authorization.
Distinguish process liveness from readiness for identity, data, audit and receipt services. A starter health response proves neither dependency health nor production readiness. Finish the Product record with tested budgets, outage behavior, recovery windows, rollback limitations and unresolved checks. See verification and versioning for how those results bind to an exact release.