RBAC and roles

Saaya enforces two layers of role-based access control. System roles govern who can administer Saaya itself; organization roles govern who can do what inside a workspace. Permissions are fine-grained and live in code as enums.

System roles

  • `SUPER_ADMIN`, Saaya staff only; emergency org-level operations.
  • `USER`, every authenticated human; the default.

Organization roles

  • `OWNER`, full control of the org including billing and seat management.
  • `ADMIN`, manage agents, KBs, channels, webhooks, RBAC; cannot change billing.
  • `MEMBER`, create and edit agents and KBs; cannot publish to production.
  • `VIEWER`, read-only access to agents, sessions, analytics.

Fine-grained scopes

Every endpoint declares the permissions it requires (`agents.create`, `sessions.read`, `webhooks.manage`, …). A role is a bundle of permissions. You can compose custom roles from the same permission set if the four built-in roles are not the right shape.

custom-role.ts
await saaya.roles.create({
  name: "campaign-runner",
  description: "Can run campaigns but cannot publish agents.",
  permissions: [
    "agents.read",
    "campaigns.create",
    "campaigns.start",
    "campaigns.pause",
    "sessions.read",
  ],
});

Attribute-based extensions

Roles can be scoped to a tag, for example, "this user is `MEMBER` on agents tagged `support`, but `VIEWER` on agents tagged `sales`". Tags are arbitrary strings you set on agents; the policy engine evaluates them at request time.

API keys inherit roles

A key minted by an `ADMIN` user has admin-level scopes. Mint API keys under a service user with the narrowest role you can, never under your personal admin account.
Was this page helpful?