Portal Community

Access Control Layers

Application data access control is enforced at three independent layers. Each layer provides a different scope of protection:

LayerWhere EnforcedProtection ScopeConfigured By
Layer 1: Tenant IsolationSQL node execution enginePrevents cross-tenant data access entirelyAutomatic — no configuration needed
Layer 2: Workflow AccessWorkflow trigger authenticationControls which users/roles can call a workflowWorkflow designer (role claims)
Layer 3: Row-Level ScopingSQL WHERE clause in workflowControls which rows within a tenant a user can seeWorkflow SQL node queries

Layer 1: Tenant Isolation (Automatic)

Tenant isolation is automatic and non-bypassable. The SQL node execution engine extracts tenantId from the authenticated workflow execution context and makes it available as {{workflow.tenantId}}. The framework validates that this parameter is used in every SQL query.

Users authenticated to Tenant A cannot construct a request that accesses Tenant B's data — the tenantId comes from the token, not from the request payload.

Tenant ID Is Never Caller-Supplied

Do not use {{input.tenantId}} in SQL parameters. Always use {{workflow.tenantId}}, which is sourced from the authenticated session — not from the API caller. Caller-supplied tenant IDs would allow tenant hopping attacks.

Layer 2: Workflow Access Control

Configure which roles can trigger each workflow using the workflow's Access Policy:

// Workflow access policy configuration
{
  "workflowId": "lead-delete",
  "accessPolicy": {
    "requireAuthentication": true,
    "allowedRoles": ["SalesManager", "Administrator"],
    "denyRoles": [],
    "allowedUsers": [],
    "requireClaims": []
  }
}

// lead-list — accessible to all sales roles
{
  "workflowId": "lead-list",
  "accessPolicy": {
    "requireAuthentication": true,
    "allowedRoles": ["SalesRep", "SalesManager", "Administrator", "ReadOnly"]
  }
}

When a user without the required role calls a restricted workflow trigger, the API returns:

HTTP 403 Forbidden
{
  "error": "Access denied",
  "requiredRoles": ["SalesManager", "Administrator"],
  "userRoles": ["SalesRep"]
}

Layer 3: Row-Level Data Scoping

Within a tenant, you can restrict which rows a user can see or modify based on their identity or role. This is implemented in the SQL node query using {{workflow.userId}} and {{workflow.userRoles}} context variables.

Sales Rep Sees Only Their Leads

{
  "query": "SELECT LeadId, FullName, Email, Status, EstimatedValue FROM Lead WHERE TenantId = @tenantId AND IsDeleted = 0 AND (@isSalesManager = 1 OR AssignedToUserId = @userId)",
  "parameters": {
    "tenantId": "{{workflow.tenantId}}",
    "userId": "{{workflow.userId}}",
    "isSalesManager": "{{workflow.hasRole('SalesManager')}}"
  }
}
-- Result: SalesManagers see all leads; SalesReps see only their assigned leads

Role-Based Field Masking

To prevent certain roles from seeing sensitive fields, use SQL CASE expressions to mask values in the query result:

SELECT
    LeadId,
    FullName,
    CASE WHEN @isSalesManager = 1 THEN Email ELSE '***@***.***' END AS Email,
    CASE WHEN @isSalesManager = 1 THEN CAST(EstimatedValue AS nvarchar) ELSE 'Hidden' END AS EstimatedValue,
    Status
FROM Lead
WHERE TenantId = @tenantId
  AND IsDeleted = 0;

Form-Level Access Control

Atlas Forms provides field-level visibility rules based on user roles:

// AtlasForms field visibility rule
{
  "field": "EstimatedValue",
  "visibilityRule": {
    "type": "role",
    "allowedRoles": ["SalesManager", "Administrator"]
    // SalesRep users will not see the EstimatedValue field at all
  }
}

// Section-level visibility
{
  "section": "AI Enrichment Data",
  "visibilityRule": {
    "type": "role",
    "allowedRoles": ["Administrator", "DataEngineer"]
  }
}
Form-Level Is UI Only — Not a Security Control

Hiding a field in the form designer prevents it from appearing in the UI — but an API caller can still retrieve the value by calling the workflow directly. If a field must be inaccessible to a role, enforce the restriction at the SQL query level (Layer 3) in addition to the form visibility rule.