task-l.3
This commit is contained in:
84
docs/security/crm-authorization-boundaries.md
Normal file
84
docs/security/crm-authorization-boundaries.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# CRM Authorization Boundaries
|
||||
|
||||
## Source of Truth
|
||||
|
||||
Resolved CRM access is the source of truth for CRM authorization.
|
||||
|
||||
The effective model is:
|
||||
|
||||
1. Authenticated user
|
||||
2. Active organization membership
|
||||
3. CRM role assignments
|
||||
4. Resolved permission union
|
||||
5. Resolved branch scope
|
||||
6. Resolved product scope
|
||||
7. Resolved ownership scope
|
||||
8. Resolved approval authority
|
||||
|
||||
`memberships.businessRole` remains a compatibility fallback only inside the resolver path.
|
||||
|
||||
## Enforcement Layers
|
||||
|
||||
### Route permission gates
|
||||
|
||||
Every CRM route must first require organization access plus at least one explicit permission.
|
||||
|
||||
### Service-level scope enforcement
|
||||
|
||||
Sensitive list/detail/mutation services must additionally enforce:
|
||||
|
||||
- branch scope
|
||||
- product scope
|
||||
- ownership visibility
|
||||
|
||||
This is required because UI filtering is not a security boundary.
|
||||
|
||||
### Pricing visibility
|
||||
|
||||
Pricing-bearing outputs require quotation pricing visibility:
|
||||
|
||||
- quotation PDF preview/download
|
||||
- approved PDF
|
||||
- document preview/data
|
||||
- revenue dashboard/export
|
||||
- approved artifact download
|
||||
|
||||
Denied pricing access is logged as `crm_security_access` with action `pricing_hidden`.
|
||||
|
||||
### Approval authority
|
||||
|
||||
Approval step handling must use resolved CRM role unions instead of a single legacy business-role string.
|
||||
|
||||
## Current Ownership Model
|
||||
|
||||
- `own`: creator or assigned owner/salesman
|
||||
- `team`: currently treated as broader-than-own, but still requires future team graph formalization
|
||||
- `organization`: organization-wide inside active tenant
|
||||
- `monitor`: read-oriented role with limited commercial visibility
|
||||
|
||||
## Artifact Boundary
|
||||
|
||||
Artifact permission alone is not enough for approved quotation PDFs.
|
||||
|
||||
The caller must satisfy:
|
||||
|
||||
1. artifact download permission
|
||||
2. quotation pricing visibility when the artifact is an approved quotation PDF
|
||||
|
||||
## Dashboard Boundary
|
||||
|
||||
Dashboard access is split:
|
||||
|
||||
- base dashboard visibility: `crm.dashboard.read`
|
||||
- revenue/commercial visibility: quotation pricing visibility
|
||||
- approval widgets: approval read permission
|
||||
- export visibility: same scope as dashboard, with extra revenue export restriction
|
||||
|
||||
## Audit Events
|
||||
|
||||
Security-sensitive denials are recorded under entity type `crm_security_access` with actions:
|
||||
|
||||
- `access_denied`
|
||||
- `scope_violation`
|
||||
- `permission_violation`
|
||||
- `pricing_hidden`
|
||||
Reference in New Issue
Block a user