Skip to main content
The access-manager module provides three groups of functions :
  1. Service account management — Create, rotate, delete service accounts and issue JWT tokens. Restricted to privileged workspaces defined via PRIVILEGED_WORKSPACES.
  2. Product bindings — CRUD operations on the product_bindings collection to link resources to users, orgs, or groups. Available to any workspace.
  3. Access checking — High-level checkAccess function that combines permissions, scopes, and bindings to determine if a caller can access a resource. Available to any workspace.
Service account functions (getServiceAccountToken, createServiceAccount, rotateServiceAccountSecret, deleteServiceAccount) are only available to workspaces listed in the PRIVILEGED_WORKSPACES environment variable. Binding and access check functions are available to all workspaces.

Service Account Functions

getServiceAccountToken — Get a JWT token for a service account

Returns the token response including accessToken, tokenType, expiresAt, permissions, and scopes.

createServiceAccount — Create a new service account

Returns the created service account including slug and clientSecret. If the service account already exists, returns { slug } without error.

rotateServiceAccountSecret — Rotate a service account’s client secret

Returns the new clientSecret.

deleteServiceAccount — Delete a service account

Cache behavior

The module caches client secrets in memory after creation or rotation. This cache is automatically invalidated when:
  • A service account is deleted (clears secret + permissions cache)
  • A service account secret is rotated (clears secret cache)
  • A service account is updated (clears permissions cache)
Cache invalidation is event-driven and applies to all runtime instances simultaneously.

Service Account Example


Product Bindings Functions

Product bindings associate resources (agents, workflows, etc.) to principals (users, orgs, groups) within a workspace. All binding functions automatically scope queries to the caller’s workspaceId — it cannot be overridden.

findBindings — Query bindings

Returns an array of binding documents.

findAndCountBindings — Query bindings with total count

Same parameters as findBindings. Returns { items: [...], total: number }.

countBindings — Count matching bindings

Returns a number.

insertBinding — Create a binding

The workspaceId and workspaceSlug are set automatically from the caller’s context. Emits a runtime.bindings.created event. A unique constraint prevents duplicate bindings for the same (workspaceId, resourceType, resourceId, principalType, principalId).

updateBinding — Update an existing binding

Only roleSlug can be updated through this function — other fields are immutable. Emits a runtime.bindings.updated event when at least one binding is modified.

deleteOneBinding — Delete a single binding

Emits a runtime.bindings.deleted event if a binding was deleted.

deleteManyBindings — Delete multiple bindings

Emits a runtime.bindings.deleted.many event if any bindings were deleted.

Workspace cleanup

When a workspace is deleted, all its bindings are automatically removed.

Access Check Function

The checkAccess function provides a high-level access control check that combines three sources: permissions (from run.permissions), scopes (from run.scopes), and bindings (from the product_bindings collection). This replaces the need for complex DSUL-based permission checking.

checkAccess — Check resource access

All parameters are optional. When called without resourceType/action, it only checks authentication and returns isWorkspaceAdmin.

Return value

The error object follows the same shape as _auth automations:

Resolution order

  1. Authentication — The caller must have a userId (user session) or an orgSlug (org API key). If neither is present, returns Unauthorized immediately.
  2. Permissions — Checked from run.permissions (set by the token’s role). The function checks in order:
    • * with manage → workspace admin
    • {workspaceSlug} with manage → workspace admin
    • {workspaceSlug}:{resourceType} with manage or {action} → access
    • If no permission matches → returns Forbidden immediately (scopes and bindings are not checked)
  3. Scopes — Parsed from run.scopes (only if permission was granted):
    • *, {workspaceSlug}:*, or {workspaceSlug}:{resourceType}:* → wildcard scope (all resources)
    • {workspaceSlug}:{resourceType}:{id} → adds id to scoped IDs
  4. Bindings — Looked up in product_bindings for the caller’s identity (userId, org, groups). Only checked for single resource mode when the scope doesn’t match. Each matching binding is then evaluated against the requested action through role-based bindings.

Role-based bindings

Bindings can carry a roleSlug to restrict which actions they grant. The role definitions themselves live outside the binding — they must be passed to checkAccess via the roles parameter (typically loaded from config.roles):
Resolution rules applied to each candidate binding: checkAccess only stops at the first binding that grants the requested action. If a user has multiple bindings (e.g. reader and editor), the most permissive applicable one wins. When the binding is granted, the reason field reflects the role: binding:user:editor, binding:org:admin, etc.
Keep your role catalog in config.roles so it can be referenced consistently from every endpoint that calls checkAccess (and from insertBinding / updateBinding for validation).

Modes

Auth-only (no resourceType, no action):
  • Returns { granted: true, isWorkspaceAdmin } — just confirms the caller is authenticated
Unauthenticated caller:
  • Returns { granted: false, error: { error: 'Unauthorized', message: 'Authentication required' } }
Single resource (resourceId provided):
  • If wildcard scope → { granted: true, reason: 'wildcard-scope', hasWildcardScope: true, isWorkspaceAdmin }
  • If scoped ID match → { granted: true, reason: 'scope', hasWildcardScope: false, isWorkspaceAdmin }
  • If binding found and the binding’s roleSlug allows the action → { granted: true, reason: 'binding:{principalType}' or 'binding:{principalType}:{roleSlug}', hasWildcardScope: false, isWorkspaceAdmin }
  • Otherwise → { granted: false, hasWildcardScope: false, error: { error: 'Forbidden', message: '...' } }
List mode (list: true, no resourceId):
  • If wildcard scope → { granted: true, grantedIds: [], hasWildcardScope: true } (caller sees everything)
  • Otherwise → { granted: true, grantedIds: [...], hasWildcardScope: false } (merged+deduplicated scoped IDs + binding IDs)
Permission-only (resourceType + action, no resourceId, no list):
  • Returns { granted: true, reason: 'permission', hasWildcardScope, isWorkspaceAdmin }

Access check examples

Guard a specific resource

Check auth + admin status only

List all accessible resources