3.6 KiB
CRM Authorization Boundaries
Source of Truth
Resolved CRM access is the source of truth for CRM authorization.
The effective model is:
- Authenticated user
- Active organization membership
- CRM role assignments
- Resolved permission union
- Resolved branch scope
- Resolved product scope
- Resolved ownership scope
- 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/salesmanteam: currently treated as broader-than-own, but still requires future team graph formalizationorganization: organization-wide inside active tenantmonitor: read-oriented role with limited commercial visibility
Customer Boundary
Customer visibility is now enforced from resolved CRM access.
organizationand admin scopes can see organization customers within branch scopeteamcurrently behaves as branch/product-scoped broad visibility until a first-class team graph existsowncan see customers they created or customers linked to enquiries/quotations they can already accessmonitorcan see customers only when those customers are related to visible lead/enquiry records
Contact Boundary
Contact visibility is enforced through customer visibility plus contact ownership rules.
- if a user can access the parent customer, they can access its contact list within their role boundary
- contact creators retain access to their own contacts
- admin/organization scope retains access
- production shared-contact persistence does not exist yet, so legacy demo sharing is not part of the live authorization boundary
Approval Boundary
Approval visibility is now narrower than generic approval-read permission.
A user can see approval records only when at least one of these is true:
- they can access the related quotation through resolved CRM scope
- they are the current approval actor by resolved CRM role
- they are admin / organization-wide CRM authority
Artifact Boundary
Artifact permission alone is not enough for approved quotation PDFs.
The caller must satisfy:
- artifact download permission
- 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
Approval widgets additionally inherit approval-request visibility rules, not just a raw approval permission.
Audit Events
Security-sensitive denials are recorded under entity type crm_security_access with actions:
access_deniedscope_violationpermission_violationpricing_hidden