Skip to main content

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 field
  • workspaceTeam - any workspace team member can access the field
  • groups - 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:

  1. Workspace - Alice is a participant, so she passes layer 1
  2. App - The "Bug tracker" app is visible to Engineering, so she passes layer 2
  3. 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:

  1. Checks that the calling user has RunAs permission for the target resource (via AccessPermissionRequest.PermissionTypes.RunAs)
  2. If allowed, executes API calls using the target user's identity (Author = new UserInfoForRequest(runAsUser))
  3. 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.