Roles
How Roles, Capabilities, and scopes decide who can do what inside an Organization
A Role is a named bundle of Capabilities. A Member holds one or more Roles, and what that person can do is the sum of those bundles.
This is how a volunteer scans tickets without also being able to change prices.
The five starter Roles
Every new Organization is created with these Roles, ready to assign.
| Role | Capabilities | Who usually holds it |
|---|---|---|
| Owner | Every Capability | Founders and the person who signed up |
| Administrator | All 76 named Capabilities | A trusted operations lead |
| Event Manager | 41, from Events through check-in | Programmers and event producers |
| Finance Viewer | 6 read and export Capabilities | Accountants and bookkeepers |
| Check-in Operator | 5, around admission only | Door staff and volunteers |
Owner is the only Role with a wildcard; every other Role is an explicit list you can read.
Administrator holds every named Capability but is not a wildcard. If Ulsav adds a Capability later, Owner has it and Administrator does not, which keeps deliberate grants deliberate.
Capabilities
A Capability is a dotted name such as events.publish, payments.refund, or checkin_sessions.operate. The first part is the area, the second is the action, and reads are separate from writes.
Every route that changes something checks a Capability, so a bug in a screen cannot grant authority the API will not honour.
Catalogue
76 Capabilities
Versioned as v1
Naming
area.action
e.g. passes.update
Wildcard
Owner only
Custom Roles may not use *
The list endpoint returns the catalogue; the full table is in Capabilities.
Custom Roles
You can build a Role for a job the starter set does not cover, such as "Merchandise Lead" or "Press Liaison".
- The key is lowercase letters, digits, and hyphens, 2 to 48 characters, and unique inside the Organization.
- The name is free text up to 80 characters.
- At least one Capability is required, every name must exist in the catalogue, duplicates are rejected, and wildcards are refused.
- You cannot create a Role that grants more than you hold. The request fails with
role_escalation. Owners bypass that check because their wildcard is not enumerable.
Roles are editable: rename them, add or remove Capabilities. Changes apply to every holder immediately, which is the point of a Role and also the danger.
The Owner Role is protected. Editing or deleting it fails with role_protected. A custom Role that still has active assignments cannot be deleted either; revoke the assignments first or the request returns role_in_use.
Scopes
A Role assignment always names a resource, called its Scope. The Scope decides how far the Role reaches.
| Scope | Reaches |
|---|---|
| Organization | Everything the Organization owns |
| EventGroupSeries | That group series and the EventGroups and Events under it |
| EventSeries | That series and its editions |
| EventGroup | That group, its portal, and its member Events |
| Event | That Event with its Sessions and Passes |
| CheckInSession | One admission checkpoint |
Effective authority is the sum of every active assignment that covers the target, with a wider Scope covering everything beneath it. There is no deny rule and no priority order, so adding a Role can only add access.
Inheritance is worked out on every request from the current hierarchy. If an Event moves from one EventSeries to another, inherited access changes immediately; nothing has to be recalculated.
Narrow grants are recorded, not yet enforced
An assignment at Event, EventGroup, EventSeries, or CheckInSession scope is stored and listed, and it counts when you grant Roles or issue API keys. The Event, Pass, Registration, and check-in routes still read Organization-scope grants only, so a narrow grant does not yet change what a person can open. Use Organization scope for access that must work today.
Owner assignments are only allowed at Organization scope. A scoped Owner grant is rejected, because "the last Owner" would stop being a single, checkable fact.
A Scope must reference a real resource in the same Organization; an ID from elsewhere fails with scope_invalid.
Worked example
Priya owns Vidyut, a three-day festival. She hires Rahul to run programming and Sana to run the door.
- Rahul gets Event Manager at Organization scope: Events, Sessions, Passes, applications, and check-in.
- Sana gets Check-in Operator at Organization scope. She can scan at an existing CheckInSession and read pass issues, but cannot create a checkpoint, see Orders, or change a price.
- Priya keeps Owner, so she alone can change the platform fee.
API keys are not Roles
An API key carries its own Capability list and one Scope, captured when the key is created or edited. It does not follow the creator's Roles, so removing a person does not break an integration.
Keys are narrower by construction: an Event-scoped key only acts on that Event, and no key may carry api_keys.* capabilities.
Related
- Members — inviting people who will hold these Roles
- Organizations — the workspace being protected
- Capabilities — the complete permission catalogue
- Event Groups and Series — the resources scopes attach to