Skip to main content

scopes.json schema

Scope naming conventions

Common actions: view, viewAll, edit, editAll, create, delete, manage

Enforcement layers

Frontend routes

Frontend route protection is a UX convenience — the actual security enforcement happens on the backend via scopedProcedure and database-level RLS.

Procedure enforcement

Create separate procedures for different access levels rather than checking scopes inside a handler. The build validator blocks ctx.userScopes access and getUserScopes imports in procedure handlers — use scopedProcedure for all scope enforcement.

Service access control

The services section controls which service tools the AI agent can access per user. Each service entry has requiredScopes (scopes needed to use any tool from that service) and tools (per-tool scope overrides):
  • requiredScopes: [] — any authenticated user can use the service’s tools (unless overridden per-tool)
  • tools — maps tool names to arrays of required scopes for that specific tool

System scopes

The framework defines system scopes for built-in features. These are included in the scaffolded scopes.json and assigned to the Admin role: System scopes have "isSystem": true and "orgAssignable": false in the scope definition.

Default roles

Roles are not defined in scopes.json. Default roles (Admin, Member) are seeded at first build via seed:publisher. The database is the source of truth for roles — users with roles:edit scope can create and edit roles at runtime.

Build-time validation

  • Every scope in tables and services must exist in the scopes array
  • Every table and column in tables must exist in the Prisma schema
  • Every service in services must have its client package installed
  • Forbidden patterns (ctx.userScopes, _unscopedPrisma, $executeRaw) are blocked