CRM Authorization Model
Authorization Boundary
Customer requests use Platform identity and authorization, followed by CRM’s operation and record guards. Application entry also depends on an active workspace licence and application access. Public health routes disclose service health rather than customer records. Contact-role reads declare portal access; that declaration still requires the named permission and does not grant it to every portal member.
Trusted task service calls use the invoking service’s cloud identity and function grant. The task service route is unavailable over ordinary HTTP. Its declared task keys describe the work being delegated; trusted invocation does not borrow a person’s grants. Portal contact matching and login transfer remain coordinated with Platform Security.
CRM declares no staff-only permission group. Rhythm staff enter customer work through Platform’s explicit customer-access mechanisms. An HQ staff role alone does not authorize customer console work. Platform retains responsibility for staff grants, their validity, separation and audit.
Scopes
CRM’s ordinary permissions apply at workspace scope. A customer-wide assignment can supply authority across that customer’s workspaces through Platform evaluation. Each CRM operation still acts in the authorized workspace named by its execution context.
Record reach is an additional check on live history and record-scoped merge inspection. Organizational affiliations, contact roles, regions and task queues describe customer information or work routing; they do not create an organizational-unit permission scope. The CRM declaration supplies no such scope. Supported narrower grants and their evaluation remain Platform’s responsibility.
Cached authorization has a bounded freshness window. Platform documents a sixty-second gateway decision lifetime and signed-context expiry with an additional thirty-second allowance. A requested flush does not establish immediate eviction. Role changes therefore require the Platform propagation contract rather than an assumption of instant CRM refusal.
Roles
The five role rows project Platform’s shipped customer roles onto CRM’s permission catalogue. CRM defines no separate built-in roles or policies. Administrator and Power User receive the application administrator tier; their different customer security and export authority lives in Platform. Standard User receives the user and reader tiers, and Read Only receives the reader tier. Portal Member receives no CRM grant from its built-in policy.
Customers can compose their own roles and policies through Platform. Assignments determine scope and validity, and applicable denies take precedence over allows. The matrix describes the shipped role baseline before those assignments, conditions and denies are evaluated. Actor descriptions identify responsibilities rather than additional grant definitions.
Permission Catalogue
The structured catalogue lists each actual key with its declared tier, consuming operations, surfaces and rule references for further restrictions. A declared key with no local operation remains visible as a declaration; it supplies no evidence of an implemented action. Query execution and presentation-definition administration cross into Platform under CRM-owned keys.
The service contracts also contain combined permission declarations and a public-health marker. Those entries are retained as non-grantable declaration references for literal contract coverage. Their component keys carry the entitlement; the reference itself is neither published nor assignable. Evaluated keys can narrow a response or authorize a conditional action without being required for initial route entry.
Role Entitlement Matrix
Every row below is an actual permission key. Yes means the shipped CRM tier permits the key before scope, conditions and denies. The two administrator-tier columns do not imply equal authority outside CRM.
| Permission | Administrator | Power User | Standard User | Read Only | Portal Member |
|---|---|---|---|---|---|
crm.activities.bulk | Yes | Yes | — | — | — |
crm.activities.create | Yes | Yes | Yes | — | — |
crm.activities.delete | Yes | Yes | Yes | — | — |
crm.activities.history | Yes | Yes | Yes | Yes | — |
crm.activities.query | Yes | Yes | Yes | Yes | — |
crm.activities.read | Yes | Yes | Yes | Yes | — |
crm.activities.update | Yes | Yes | Yes | — | — |
crm.activity-types.bulk | Yes | Yes | — | — | — |
crm.activity-types.create | Yes | Yes | — | — | — |
crm.activity-types.delete | Yes | Yes | — | — | — |
crm.activity-types.read | Yes | Yes | Yes | Yes | — |
crm.activity-types.update | Yes | Yes | — | — | — |
crm.address-types.bulk | Yes | Yes | — | — | — |
crm.address-types.create | Yes | Yes | — | — | — |
crm.address-types.delete | Yes | Yes | — | — | — |
crm.address-types.read | Yes | Yes | Yes | Yes | — |
crm.address-types.update | Yes | Yes | — | — | — |
crm.affiliation-types.bulk | Yes | Yes | — | — | — |
crm.affiliation-types.create | Yes | Yes | Yes | — | — |
crm.affiliation-types.delete | Yes | Yes | — | — | — |
crm.affiliation-types.read | Yes | Yes | Yes | Yes | — |
crm.affiliation-types.set-default | Yes | Yes | — | — | — |
crm.affiliation-types.update | Yes | Yes | Yes | — | — |
crm.application.access | Yes | Yes | Yes | Yes | — |
crm.contact-layouts.bulk | Yes | Yes | — | — | — |
crm.contact-layouts.create | Yes | Yes | — | — | — |
crm.contact-layouts.delete | Yes | Yes | — | — | — |
crm.contact-layouts.read | Yes | Yes | Yes | Yes | — |
crm.contact-layouts.update | Yes | Yes | — | — | — |
crm.contact-roles.bulk | Yes | Yes | — | — | — |
crm.contact-roles.create | Yes | Yes | Yes | — | — |
crm.contact-roles.delete | Yes | Yes | — | — | — |
crm.contact-roles.lock | Yes | Yes | — | — | — |
crm.contact-roles.read | Yes | Yes | Yes | Yes | — |
crm.contact-roles.unlock | Yes | Yes | — | — | — |
crm.contact-roles.update | Yes | Yes | Yes | — | — |
crm.contact-types.bulk | Yes | Yes | — | — | — |
crm.contact-types.create | Yes | Yes | Yes | — | — |
crm.contact-types.delete | Yes | Yes | — | — | — |
crm.contact-types.read | Yes | Yes | Yes | Yes | — |
crm.contact-types.update | Yes | Yes | Yes | — | — |
crm.contacts.archive | Yes | Yes | — | — | — |
crm.contacts.bulk | Yes | Yes | — | — | — |
crm.contacts.create | Yes | Yes | Yes | — | — |
crm.contacts.create-despite-duplicate-block | Yes | Yes | — | — | — |
crm.contacts.delete | Yes | Yes | — | — | — |
crm.contacts.history | Yes | Yes | Yes | Yes | — |
crm.contacts.lock | Yes | Yes | — | — | — |
crm.contacts.merge | Yes | Yes | — | — | — |
crm.contacts.query | Yes | Yes | Yes | Yes | — |
crm.contacts.read | Yes | Yes | Yes | Yes | — |
crm.contacts.unlock | Yes | Yes | — | — | — |
crm.contacts.update | Yes | Yes | Yes | — | — |
crm.duplicates.configure | Yes | Yes | — | — | — |
crm.duplicates.read | Yes | Yes | Yes | — | — |
crm.duplicates.review | Yes | Yes | Yes | — | — |
crm.merges.read | Yes | Yes | Yes | — | — |
crm.organization-layouts.bulk | Yes | Yes | — | — | — |
crm.organization-layouts.create | Yes | Yes | — | — | — |
crm.organization-layouts.delete | Yes | Yes | — | — | — |
crm.organization-layouts.read | Yes | Yes | Yes | Yes | — |
crm.organization-layouts.update | Yes | Yes | — | — | — |
crm.organization-types.bulk | Yes | Yes | — | — | — |
crm.organization-types.create | Yes | Yes | Yes | — | — |
crm.organization-types.delete | Yes | Yes | — | — | — |
crm.organization-types.read | Yes | Yes | Yes | Yes | — |
crm.organization-types.update | Yes | Yes | Yes | — | — |
crm.organizations.archive | Yes | Yes | — | — | — |
crm.organizations.bulk | Yes | Yes | — | — | — |
crm.organizations.create | Yes | Yes | Yes | — | — |
crm.organizations.create-despite-duplicate-block | Yes | Yes | — | — | — |
crm.organizations.delete | Yes | Yes | — | — | — |
crm.organizations.history | Yes | Yes | Yes | Yes | — |
crm.organizations.lock | Yes | Yes | — | — | — |
crm.organizations.merge | Yes | Yes | — | — | — |
crm.organizations.query | Yes | Yes | Yes | Yes | — |
crm.organizations.read | Yes | Yes | Yes | Yes | — |
crm.organizations.unlock | Yes | Yes | — | — | — |
crm.organizations.update | Yes | Yes | Yes | — | — |
crm.phone-number-types.bulk | Yes | Yes | — | — | — |
crm.phone-number-types.create | Yes | Yes | — | — | — |
crm.phone-number-types.delete | Yes | Yes | — | — | — |
crm.phone-number-types.read | Yes | Yes | Yes | Yes | — |
crm.phone-number-types.update | Yes | Yes | — | — | — |
crm.regions.bulk | Yes | Yes | — | — | — |
crm.regions.create | Yes | Yes | Yes | — | — |
crm.regions.delete | Yes | Yes | — | — | — |
crm.regions.read | Yes | Yes | Yes | Yes | — |
crm.regions.recalculate | Yes | Yes | — | — | — |
crm.regions.update | Yes | Yes | Yes | — | — |
crm.task-queues.bulk | Yes | Yes | — | — | — |
crm.task-queues.create | Yes | Yes | — | — | — |
crm.task-queues.delete | Yes | Yes | — | — | — |
crm.task-queues.read | Yes | Yes | Yes | Yes | — |
crm.task-queues.update | Yes | Yes | — | — | — |
crm.task-types.bulk | Yes | Yes | — | — | — |
crm.task-types.create | Yes | Yes | — | — | — |
crm.task-types.delete | Yes | Yes | — | — | — |
crm.task-types.read | Yes | Yes | Yes | Yes | — |
crm.task-types.update | Yes | Yes | — | — | — |
crm.tasks.bulk | Yes | Yes | — | — | — |
crm.tasks.create | Yes | Yes | Yes | — | — |
crm.tasks.delete | Yes | Yes | — | — | — |
crm.tasks.query | Yes | Yes | Yes | Yes | — |
crm.tasks.read | Yes | Yes | Yes | Yes | — |
crm.tasks.update | Yes | Yes | Yes | — | — |
Protected Actions
Record combination requires the read and merge pair for the plan’s record type. Admitting a request through any route-level key does not satisfy that pair. Participant selection, plan freshness, locks and merge validation remain capability-owned guards. No second approver is established by the examined declarations; a confirmation control is not a separate approval role.
Creation past a duplicate block requires the sensitive override key for the record kind and a reason recorded with the creation. Record lock and unlock actions carry separate administrator keys and require a version and reason. Protected system records remain protected even when the caller holds those keys. The ordinary-lock exceptions for other CRM records remain findings.
Role-offered work requires task update authority and confirmation that the claimant holds the offered role when the task is outside a queue. Queued work follows queue claim guards even when a role is also named. Closing state, existing holders and locks can refuse authorized task work. Regional imports require both regional bulk and update authority, while workspace-wide recalculation requires its dedicated administrator key.
History and merge outcomes have distinct access boundaries. Live record history includes record reach; deleted history uses its history permission. Retained merge outcomes use the user-tier merge-read key, while a record-scoped view can expose a narrower result under that record’s read authority. CRM settings reads filter sections by authority, and settings writes require authority for every requested section.
Guards Distinguished From Permissions
Permissions establish whether a caller may attempt the work. Guards establish whether the target and proposed change are valid now. The catalogue references capability rules for locks, versions, state, workspace references and role-holder checks instead of defining those rules again. A permission never repairs a stale draft or makes a protected record removable.
A console visibility alias can admit a page more broadly than its API permits an action. The exact server key and handler guards decide the request. Task ownership and queue responsibility do not confer task permissions, and organizational contact roles do not confer security roles.
What People See When Refused
Missing authentication or an invalid protected identity produces an authentication refusal. Missing grants produce a forbidden response; application-access and licence failures carry client-readable refusal codes. Platform’s refusal metadata identifies the cause and required keys without identifying another person.
An inaccessible record is handled within the workspace boundary without exposing another workspace’s information. Once record access is established, a merged identity can return a gone response pointing to its survivor. Stale versions, locks and inapplicable lifecycle actions produce conflict or validation feedback. CRM settings can omit unreadable sections rather than return their contents.
The console hides or disables permission-dependent actions where its guards do so, and otherwise presents service feedback. Existing screen findings record alias mismatches and generic task-claim conflict feedback. No uniform screen message or complete CRM access-refusal audit coverage is established by these declarations.