Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Roles and Permissions

ScaiGrid authorization is permission-based. Roles are bundles of permissions. Users get roles; endpoints check permissions.

Built-in roles#

Six roles ship out of the box, covering the common hierarchy:

Role Scope Typical use
super_admin Platform Platform operators — full access
partner_admin Partner Reseller administrators
partner_viewer Partner Partner-level read-only / accounting
tenant_admin Tenant Customer admin — manages their own tenant
tenant_user Tenant Regular user — uses models, manages own keys
tenant_viewer Tenant Read-only user — can list models, view own usage

Permission bundles (from lowest to highest):

tenant_viewermodels:list, accounting:view_own.

tenant_user — tenant_viewer permissions plus models:use, api_keys:manage, modules:use.

tenant_admin — tenant_user permissions plus routing:view, accounting:view_tenant, accounting:manage_budgets, users:manage, webhooks:manage, modules:manage, admin:access.

partner_viewermodels:list, accounting:view_own, accounting:view_tenant, accounting:view_partner.

partner_admin — partner_viewer permissions plus accounting:manage_budgets, users:manage, admin:access.

super_admin — every permission, all the time, platform-wide.

Core permissions#

The 15 core permissions ScaiGrid uses internally:

Permission What it grants
models:list See which models are available
models:use Call inference endpoints
models:manage Create, update, delete models and backends
routing:view See routing policies
routing:manage Edit routing policies and model/backend mappings
accounting:view_own View your own usage
accounting:view_tenant View full tenant usage
accounting:view_partner View partner-level usage across tenants
accounting:manage_budgets Create, update, enforce budgets
users:manage Create, update, delete users in tenant
api_keys:manage Create and revoke your own API keys
webhooks:manage Configure outbound webhooks
modules:use Call module endpoints
modules:manage Enable, disable, configure modules
admin:access Access the admin UI

Module permissions#

Modules register their own permissions. They follow the convention {module_id}:{action} and are stored on the user as a separate set from core IAM permissions. A few representative examples:

  • scaibot:manage — manage chatbot configurations
  • scaimatrix:ingest — add documents to a knowledge collection
  • scaibunker:execute — run commands inside a sandbox
  • scaibunker:admin:tenant — manage tenant-scoped quota profiles + assignments
  • scaiqueue:publish — send messages to a queue

ScaiBunker has the most granular permission set in the platform — covering bunker creation, lifecycle modes, network profiles, image management, and tiered admin levels (scaibunker:admin, scaibunker:admin:tenant, scaibunker:admin:platform). See ScaiBunker → Permissions for the full table.

Implicit grants on tenant / partner admin roles. Tenant admins and partner admins receive every module permission by default through a short-circuit in has_module_permission. This means a tenant_admin automatically has scaibunker:admin:tenant (the intent), and also nominally has scaibunker:admin:platform (which is route-gated separately to platform-only operations like cross-tenant availability-group management). Module routes that need platform-scope authorization check the user's role rather than the module-permission flag.

See each module's page in the Modules section for its full permission list.

How permissions resolve#

A user's effective permissions come from three sources, combined:

  1. Role-based permissions. Each role the user has contributes its permission set. A tenant_user contributes models:use, api_keys:manage, etc. A user can have multiple roles (unusual but supported) and their effective permissions are the union.
  2. Group mappings. ScaiKey groups can map to ScaiGrid roles via the role_mappings table. If you're in a ScaiKey group mapped to tenant_admin, you get that role whenever you authenticate. Configure via /v1/role-mappings.
  3. Module permissions. Users can have per-module permissions granted directly (not through a role). These are additive — a user who's a tenant_user plus has scaibot:manage granted can use models and manage bots, but not other admin functions. Configure via /v1/users/{user_id}/module-permissions.

Effective permission set = (role permissions) ∪ (group-mapped permissions) ∪ (direct module permissions).

Per-resource ACLs (some modules)#

Some modules layer a per-resource ACL on top of the role/permission system. The role/permission system gates whether you can use the module's API; the ACL gates which specific resources within the module you can touch.

ScaiMatrix is the most prominent example — collections and individual documents each carry an NTFS-style ACL with allow/deny entries, parent inheritance, and an owner concept. A user with scaimatrix:search can call the search endpoint, but the ACL decides which collections and documents the search results actually contain.

When both a module permission and an ACL apply, the user needs both. Group memberships are expanded transitively where the module supports it, including nested groups.

Custom roles#

If the six built-in roles don't match your access pattern, create a custom role. Custom roles are tenant-scoped, composed from any mix of core permissions and module permissions.

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
curl -X POST https://scaigrid.scailabs.ai/v1/custom-roles \
  -H "Authorization: Bearer $TENANT_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Analytics Team",
    "slug": "analytics",
    "description": "Can view all tenant usage and export reports, no admin access",
    "core_permissions": ["accounting:view_tenant", "models:list"],
    "module_permissions": []
  }'

Assign to a user:

bash
1
2
3
curl -X PUT https://scaigrid.scailabs.ai/v1/users/{user_id}/roles \
  -H "Authorization: Bearer $TENANT_ADMIN_TOKEN" \
  -d '{"roles": ["tenant_user"], "custom_role_ids": ["role_abc"]}'

Custom roles can include any module permission the tenant has enabled. See Custom Roles.

Checking permissions programmatically#

The current user's permissions are available at /v1/me:

bash
1
curl -H "Authorization: Bearer $TOKEN" https://scaigrid.scailabs.ai/v1/me
json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "status": "ok",
  "data": {
    "user_id": "...",
    "email": "alice@acme.example",
    "tenant_id": "...",
    "roles": ["tenant_admin"],
    "permissions": ["models:use", "users:manage", ...],
    "module_permissions": ["scaibot:manage", "scaimatrix:search", ...]
  }
}

Useful for building permission-aware UI — show the "Manage users" button only to callers with users:manage.

What happens on a permission denial#

Requests without sufficient permissions return 403 AUTHZ_PERMISSION_DENIED:

json
1
2
3
4
5
6
7
{
  "status": "error",
  "error": {
    "code": "AUTHZ_PERMISSION_DENIED",
    "message": "User lacks required permission"
  }
}

No indication of which specific permission is missing — to avoid leaking the permission taxonomy to unauthenticated callers. Authenticated admins can inspect a user's permissions directly.

What's next#

Updated 2026-05-18 15:01:28 View source (.md) rev 17