ACL evaluation order
Comind evaluates access control in four layers, from broadest to narrowest. Each layer can only narrow the access granted by the layer above it - a more specific layer cannot grant access that a broader layer denied.
┌─────────────────────────────────────────┐
│ 1. Workspace │
│ ┌───────────────────────────────────┐ │
│ │ 2. App │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ 3. Record │ │ │
│ │ │ ┌───────────────────────┐ │ │ │
│ │ │ │ 4. Field │ │ │ │
│ │ │ └───────────────────────┘ │ │ │
│ │ └─────────────────────────────┘ │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
Layer 1 - workspace
The workspace layer determines who can access the workspace at all. Workspace admins manage this through participant management and group assignment.
A user who is not a participant of a workspace has zero visibility into its contents - no apps, no records, no fields.
Layer 2 - app
Within a workspace, each app can be visible or hidden per group. If a user's group does not have access to an app, that user cannot see it in navigation or reach it by direct URL.
Example: A workspace has a "Contracts" app restricted to the Legal group. Users in the Sales group can access other apps in the same workspace but cannot see or open Contracts.
Layer 3 - record
Individual records can carry their own access restrictions beyond what the app allows. The plugin-permission adds ACL fields to records, letting you lock down specific items to specific users or groups.
Example: A project record in a shared app can be restricted so only the assigned team sees it. Other workspace participants with app access still cannot view that record.
Layer 4 - field
Individual fields can be restricted to specific groups or roles. The field access option accepts three values:
workspaceAdmin- only workspace administrators can see or edit the fieldworkspaceTeam- any workspace team member can access the fieldgroups- only members of specified groups can access the field
Example: A "Cost" field on a deal record is set to access: 'workspaceAdmin'. Regular users can view the deal but that field is invisible to them.
When a user lacks access to a field, the behavior depends on the field configuration - the field may be hidden entirely or shown as read-only.
How layers interact
Consider a user named Alice who belongs to the "Engineering" group:
- Workspace - Alice is a participant, so she passes layer 1
- App - The "Bug tracker" app is visible to Engineering, so she passes layer 2
- Record - A specific bug report is restricted to the QA group via
plugin-permission. Alice is not in QA, so she is denied at layer 3
Alice never reaches layer 4 for that record. The evaluation stops at the first layer that denies access.
Admin overrides
Two admin roles bypass normal ACL evaluation:
- System admin (global admin) - full access across all workspaces, apps, records, and fields
- Workspace admin - full access within their workspace, regardless of app, record, or field restrictions
Groups
Groups are the primary mechanism for controlling access across all four layers. Each user belongs to one or more groups. Groups determine:
- Which apps are visible in a workspace
- Which fields a user can see or edit
- Which actions a user can perform (via action preconditions)
- Which records are accessible (via record-level ACL)
Assign users to groups through the workspace participant management interface. Group names are workspace-specific - a "Managers" group in one workspace is independent of a "Managers" group in another.
Automated workflows
When a server-side action or job runs on behalf of another user via the runAsUser parameter (stored as c_run_as on job records), the system:
- Checks that the calling user has
RunAspermission for the target resource (viaAccessPermissionRequest.PermissionTypes.RunAs) - If allowed, executes API calls using the target user's identity (
Author = new UserInfoForRequest(runAsUser)) - All subsequent ACL checks evaluate against the target user's permissions, not the caller's
This means runAsUser adopts the target user's access level. If the target user has less access than the automation account, the operation is restricted. If the target user has access the caller doesn't, the caller must first have RunAs permission granted to impersonate them.