# How Workflow Authorization and Workspace Permissions Work in SimStudioAI Sim

> Learn how SimStudioAI Sim secures workflows with authorization and workspace permissions. Understand permission validation and hierarchical locks for secure mutations.

- Repository: [Sim/sim](https://github.com/simstudioai/sim)
- Tags: deep-dive
- Published: 2026-05-02

---

**SimStudioAI Sim secures every workflow operation by tying workflows to workspaces and validating caller permissions through the `@sim/workflow-authz` package, enforcing hierarchical locks before allowing mutations.**

The `simstudioai/sim` repository implements robust **workflow authorization and workspace permissions** through a model that ties every workflow to a workspace and validates user access before allowing any operation. By centralizing access control in the `@sim/workflow-authz` package and storing permissions in a dedicated database table, the system maintains strict separation between authentication and authorization across API routes, webhook handlers, and Copilot tools.

## Workspace Permission Architecture

The authorization system resolves workflow access through two primary steps: active workflow validation and workspace-level permission lookup.

### Active Workflow Resolution

Before checking permissions, the system must locate a valid, non-archived workflow record. The `getActiveWorkflowContext` function in [`packages/workflow-authz/src/index.ts`](https://github.com/simstudioai/sim/blob/main/packages/workflow-authz/src/index.ts) (lines 18‑31) fetches the workflow together with its workspace ID, verifying that the workflow isn't archived and its parent workspace remains active. If the workflow cannot be found, the authorization routine aborts early with a 404 result.

### The Permissions Table

Workspace permissions are stored in the `permissions` table defined in [`packages/db/schema.ts`](https://github.com/simstudioai/sim/blob/main/packages/db/schema.ts). This table stores a row per `(user, entity-type, entity-id)` combination, where `entity-type` is `workspace` and `permissionType` is an enum with values `read`, `write`, and `admin`. The authorization function queries this table to retrieve the caller’s permission level for the workflow’s specific workspace.

## Authorization Logic and Permission Hierarchy

The `authorizeWorkflowByWorkspacePermission` function serves as the single source of truth for workflow access decisions. Located in [`packages/workflow-authz/src/index.ts`](https://github.com/simstudioai/sim/blob/main/packages/workflow-authz/src/index.ts) (lines 2‑80), this function receives a workflow ID, user ID, and requested action (`read`, `write`, or `admin`), then returns a `WorkflowWorkspaceAuthorizationResult` containing `allowed`, `status`, `message`, the workflow record, and the user's workspace permission.

The permission evaluation follows a strict hierarchy:

- **read**: Always allowed if the user has any permission on the workspace (`read`, `write`, or `admin`)
- **write**: Requires `write` or `admin` permission
- **admin**: Requires explicit `admin` permission

The function enforces that every workflow must be attached to a workspace—personal workflows are deprecated—returning 403 if the workspace ID is missing. If no permission record exists for the user-workspace pair, the request is denied.

## Lock Handling for Concurrent Access

Before mutating a workflow, the system checks resource locks to prevent concurrent edits. The `getWorkflowLockStatus` function climbs from the workflow to its folder hierarchy, reusing `getFolderLockStatus` to detect locks at any level.

If a lock is detected, `assertWorkflowMutable` or `assertFolderMutable` throw `WorkflowLockedError` or `FolderLockedError`, resulting in HTTP 423 (Locked) responses. These utilities in [`packages/workflow-authz/src/index.ts`](https://github.com/simstudioai/sim/blob/main/packages/workflow-authz/src/index.ts) (lines 41‑73) ensure immutable resources cannot be modified, providing optimistic concurrency control for collaborative environments.

## API Integration and Usage Examples

Every API route that touches a workflow invokes the authorization routine, passing the current user ID from the auth session and the appropriate action. For example, `apps/sim/app/api/workflows/[id]/state/route.ts` (lines 46‑58) demonstrates this pattern for workflow state requests.

### Authorizing a Read Request

To check if a user can view a workflow:

```typescript
import { authorizeWorkflowByWorkspacePermission } from '@sim/workflow-authz'

async function canReadWorkflow(workflowId: string, userId: string) {
  const result = await authorizeWorkflowByWorkspacePermission({
    workflowId,
    userId,
    action: 'read',
  })
  return result.allowed   // true → proceed; false → send result.status / result.message
}

```

### Authorizing a Write Request in an API Route

For mutations within Next.js API routes:

```typescript
import { authorizeWorkflowByWorkspacePermission } from '@sim/workflow-authz'
import { NextResponse } from 'next/server'

export async function POST(request) {
  const { workflowId, userId } = await request.json()
  const auth = await authorizeWorkflowByWorkspacePermission({
    workflowId,
    userId,
    action: 'write',
  })

  if (!auth.allowed) {
    return NextResponse.json(
      { error: auth.message },
      { status: auth.status }
    )
  }

  // …perform mutable operation (e.g. update workflow)…
}

```

### Checking Lock Status Before Updates

To prevent edits on locked workflows:

```typescript
import { assertWorkflowMutable } from '@sim/workflow-authz'

async function updateWorkflow(workflowId: string, updates: Partial<Workflow>) {
  await assertWorkflowMutable(workflowId)   // throws 423 if locked
  // …apply updates…
}

```

## Summary

- **Workspace-centric security**: Every workflow must belong to a workspace; personal workflows are deprecated.
- **Hierarchical permissions**: The `permissions` table stores `read`, `write`, and `admin` levels, with `authorizeWorkflowByWorkspacePermission` enforcing that `write` requires `write` or higher, and `admin` requires explicit admin rights.
- **Active workflow validation**: `getActiveWorkflowContext` ensures workflows exist, aren't archived, and belong to active workspaces before permission checks occur.
- **Lock-based concurrency**: `assertWorkflowMutable` and `assertFolderMutable` prevent modifications to locked resources, returning HTTP 423 when conflicts are detected.
- **Universal enforcement**: All API routes, webhook handlers, and Copilot tools use the same authorization flow from `@sim/workflow-authz` to maintain consistent security boundaries.

## Frequently Asked Questions

### What happens if a workflow isn't attached to a workspace?

The authorization function returns a 403 Forbidden response. According to the source code in [`packages/workflow-authz/src/index.ts`](https://github.com/simstudioai/sim/blob/main/packages/workflow-authz/src/index.ts), SimStudioAI Sim has deprecated personal workflows, so every workflow must have a valid workspace ID to pass authorization.

### How does the system handle read versus write permissions?

Read requests are allowed if the user has any permission level on the workspace (`read`, `write`, or `admin`). Write requests require explicit `write` or `admin` permissions, while admin operations require the `admin` permission type specifically. This hierarchy is enforced in the `authorizeWorkflowByWorkspacePermission` function.

### What HTTP status code is returned when a workflow is locked?

The system returns HTTP 423 (Locked) when attempting to mutate a locked workflow or folder. The `assertWorkflowMutable` and `assertFolderMutable` functions throw `WorkflowLockedError` or `FolderLockedError` respectively, which translate to this status code in API responses.

### Where are workspace permissions stored in the database?

Permissions are stored in the `permissions` table defined in [`packages/db/schema.ts`](https://github.com/simstudioai/sim/blob/main/packages/db/schema.ts). Each row maps a user to a workspace with a specific `permissionType` enum value, allowing efficient lookups during the authorization process.