Skip to main content

Documentation Index

Fetch the complete documentation index at: https://prismeai-legacy.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

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

- run:
    module: access-manager
    function: getServiceAccountToken
    parameters:
      orgSlug: "{{orgSlug}}"
      serviceAccountSlug: "{{saSlug}}"
      create: true
      expiresIn: 3600
    output: tokenResult
ParameterTypeRequiredDescription
orgSlugstringyesOrganization slug
serviceAccountSlugstringyesService account slug
createbooleannoWhen true, creates the service account if it doesn’t exist and rotates the secret if needed. When false or omitted, only works with a cached secret.
namestringnoDisplay name for the service account (used on creation)
roleSlugstringnoRole to assign. Must be in the workspace’s allowedRoleSlugs. Defaults to the workspace’s defaultRoleSlug.
expiresInnumbernoToken TTL in seconds
Returns the token response including accessToken, tokenType, expiresAt, permissions, and scopes.

createServiceAccount — Create a new service account

- run:
    module: access-manager
    function: createServiceAccount
    parameters:
      orgSlug: "{{orgSlug}}"
      serviceAccountSlug: "{{saSlug}}"
      name: "My Agent"
      roleSlug: "agent-standard"
    output: result
ParameterTypeRequiredDescription
orgSlugstringyesOrganization slug
serviceAccountSlugstringyesService account slug
namestringnoDisplay name
roleSlugstringnoRole to assign (validated against allowed roles)
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

- run:
    module: access-manager
    function: rotateServiceAccountSecret
    parameters:
      orgSlug: "{{orgSlug}}"
      serviceAccountSlug: "{{saSlug}}"
    output: result
ParameterTypeRequiredDescription
orgSlugstringyesOrganization slug
serviceAccountSlugstringyesService account slug
Returns the new clientSecret.

deleteServiceAccount — Delete a service account

- run:
    module: access-manager
    function: deleteServiceAccount
    parameters:
      orgSlug: "{{orgSlug}}"
      serviceAccountSlug: "{{saSlug}}"
    output: result
ParameterTypeRequiredDescription
orgSlugstringyesOrganization slug
serviceAccountSlugstringyesService account slug

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

slug: get-agent-token
name: Get Agent Token
do:
  # Create (or reuse) a service account and get a JWT token
  - run:
      module: access-manager
      function: getServiceAccountToken
      parameters:
        orgSlug: "{{orgSlug}}"
        serviceAccountSlug: "agent-{{agentId}}"
        name: "Agent {{agentId}}"
        create: true
        expiresIn: 3600
      output: tokenResult

  # Use the token to call an API
  - fetch:
      url: "{{config.apiUrl}}/resources"
      method: GET
      headers:
        Authorization: "Bearer {{tokenResult.accessToken}}"
      output: resources

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

- run:
    module: access-manager
    function: findBindings
    parameters:
      query:
        resourceType: agents
        principalType: user
        principalId: "{{userId}}"
      options:
        pagination:
          limit: 50
          page: 0
        sort:
          createdAt: desc
    output: bindings
ParameterTypeRequiredDescription
queryobjectyesFilter fields matching ProductBinding (e.g. resourceType, resourceId, principalType, principalId, orgSlug)
options.paginationobjectno{ page, skip, limit }
options.sortobjectnoSort fields (e.g. { createdAt: 'desc' })
options.fieldsarraynoFields to return
Returns an array of binding documents.

findAndCountBindings — Query bindings with total count

- run:
    module: access-manager
    function: findAndCountBindings
    parameters:
      query:
        resourceType: agents
      options:
        pagination:
          limit: 20
          page: 0
    output: result
# result.items = [...], result.total = 42
Same parameters as findBindings. Returns { items: [...], total: number }.

countBindings — Count matching bindings

- run:
    module: access-manager
    function: countBindings
    parameters:
      query:
        resourceType: agents
        orgSlug: "{{orgSlug}}"
    output: count
ParameterTypeRequiredDescription
queryobjectyesFilter fields
Returns a number.

insertBinding — Create a binding

- run:
    module: access-manager
    function: insertBinding
    parameters:
      data:
        resourceType: agents
        resourceId: "{{agentId}}"
        principalType: user
        principalId: "{{targetUserId}}"
        orgSlug: "{{orgSlug}}"
        grantedBy: "{{userId}}"
        email: "{{targetEmail}}"
    output: result
# result.acknowledged = true, result.insertedId = "..."
ParameterTypeRequiredDescription
data.resourceTypestringyesResource type (e.g. agents, workflows)
data.resourceIdstringyesResource identifier
data.principalTypestringyesuser, org, or group
data.principalIdstringyesPrincipal identifier
data.orgSlugstringyesOrganization slug
data.grantedBystringyesUser who granted the binding
data.emailstringnoEmail for user bindings
data.roleSlugstring | nullnoOptional role slug controlling which actions this binding grants. See Role-based bindings. When null or omitted, the binding grants every action except delete.
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

- run:
    module: access-manager
    function: updateBinding
    parameters:
      query:
        resourceType: agents
        resourceId: "{{agentId}}"
        principalType: user
        principalId: "{{targetUserId}}"
      data:
        roleSlug: editor
    output: result
# result.matchedCount = 1, result.modifiedCount = 1
ParameterTypeRequiredDescription
queryobjectyesFilter to match the binding(s) to update
data.roleSlugstring | nullnoNew role slug to apply. Pass null to clear the role (binding will then grant all actions except delete).
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

- run:
    module: access-manager
    function: deleteOneBinding
    parameters:
      query:
        resourceType: agents
        resourceId: "{{agentId}}"
        principalType: user
        principalId: "{{targetUserId}}"
    output: result
# result.deletedCount = 1
ParameterTypeRequiredDescription
queryobjectyesFilter to match the binding to delete
Emits a runtime.bindings.deleted event if a binding was deleted.

deleteManyBindings — Delete multiple bindings

- run:
    module: access-manager
    function: deleteManyBindings
    parameters:
      query:
        resourceType: agents
        resourceId: "{{agentId}}"
    output: result
# result.deletedCount = 5
ParameterTypeRequiredDescription
queryobjectyesFilter to match bindings to delete
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

- run:
    module: access-manager
    function: checkAccess
    parameters:
      resourceType: agents
      resourceId: "{{agentId}}"
      action: read
    output: access
All parameters are optional. When called without resourceType/action, it only checks authentication and returns isWorkspaceAdmin.
ParameterTypeRequiredDescription
resourceTypestringnoResource type (e.g. agents, workflows). Must be set together with action.
resourceIdstringnoSpecific resource ID. Requires resourceType.
actionstringnoAction to check (typically read, write, share, delete, manage, but any string is accepted — must match the keys in roles[*].permissions). Must be set together with resourceType.
listbooleannoWhen true, returns the list of granted resource IDs instead of a single grant
rolesobjectnoRole definitions for binding role enforcement. Record<string, { name?: string, permissions: string[] }>. Required as soon as any matching binding has a roleSlug — otherwise checkAccess throws. See Role-based bindings.

Return value

FieldTypeDescription
grantedbooleanWhether access is granted
reasonstringWhy access was granted: permission, wildcard-scope, scope, or binding:{principalType} (e.g. binding:user, binding:org, binding:group). When the matching binding carries a roleSlug, the reason becomes binding:{principalType}:{roleSlug} (e.g. binding:user:editor).
grantedIdsstring[]Only in list mode — merged set of IDs from scopes and bindings
hasWildcardScopebooleantrue if the caller has wildcard scope (sees all resources of this type)
isWorkspaceAdminbooleantrue if the caller has * or {workspaceSlug} manage permission
errorobjectOnly when granted is false — contains error (code) and message (human-readable)
The error object follows the same shape as _auth automations:
error.errorerror.messageWhen
UnauthorizedAuthentication requiredNo authenticated user (no userId and no org API key)
ForbiddenAccess denied: missing permission '{workspaceSlug}:{resourceType}:{action}'User is authenticated but has no matching permission

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):
- run:
    module: access-manager
    function: checkAccess
    parameters:
      resourceType: agents
      resourceId: "{{agentId}}"
      action: write
      roles:
        owner:
          name: Owner
          permissions: [read, write, share, delete]
        admin:
          name: Admin
          permissions: [read, write, share]
        editor:
          name: Editor
          permissions: [read, write]
        reader:
          name: Reader
          permissions: [read]
    output: access
Resolution rules applied to each candidate binding:
Binding roleSlugroles parameterBehavior
null / unset(any)Binding grants every action except delete. Used for legacy bindings or “full collaborator” semantics.
set (e.g. editor)provided, slug existsAction must be in roles[slug].permissions — otherwise the binding is ignored and checkAccess continues to the next binding (or returns Forbidden).
setnot provided at allcheckAccess throws — passing roles is required as soon as any binding could be role-typed.
setprovided but slug missingThe binding is ignored (treated as having no permissions).
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

- run:
    module: access-manager
    function: checkAccess
    parameters:
      resourceType: agents
      resourceId: "{{agentId}}"
      action: read
    output: access

# access.error is set when granted=false (UNAUTHORIZED or FORBIDDEN)
- conditions:
    "{{access.error}}":
        - break:
            automation: true
            output:
              error: "{{access.error.error}}"
              message: "{{access.error.message}}"

Check auth + admin status only

- run:
    module: access-manager
    function: checkAccess
    output: access

# access.granted = true if authenticated
# access.isWorkspaceAdmin = true if user has * or workspace-level manage

List all accessible resources

- run:
    module: access-manager
    function: checkAccess
    parameters:
      resourceType: agents
      action: read
      list: true
    output: access

# If access.hasWildcardScope is true, query all agents without filter
# Otherwise, filter agents by access.grantedIds
- conditions:
    "{{access.hasWildcardScope}}":
        - fetch:
            url: "{{config.apiUrl}}/agents"
            output: agents
    default:
        - fetch:
            url: "{{config.apiUrl}}/agents?ids={{access.grantedIds | join ','}}"
            output: agents