Concepts
The three permission domains
Orgo splits permissions into three domains. Each domain has its own roles. Granting one doesn’t grant the others.
Each domain has three scope levels: TENANT (whole org), PARENT_LOCAL (a local center and everything under it), and LOCAL (one specific local center).
So
HR_LOCAL means “manages people for this one local center”, ADMIN_TENANT means “configures the whole organization”. The combinations make 9 distinct permission scopes; see Permissions for the full matrix.
Where local centers fit
ALocalCenter is a kind of Unit. Units are the generic grouping primitive — local centers, role groups (automatic membership by role), private project teams. Most permission scopes attach to a specific Unit (which, for local-scope roles, is the LocalCenter itself).
Step 1 — Create a local center
isPublic: true makes the local center appear on the public “find your center” map and listing. isActive: false hides it from new-member registration forms while keeping it visible to admins.
Response carries the integer id you’ll use for /api/v1/local_centers/{id} references throughout the rest of the system.
Step 2 — Create a role definition
Roles are the named permission containers (“Chapter Lead”, “Treasurer”, “Outreach Coordinator”). Create one per distinct responsibility:GET /api/v1/permission_definitions (or see Permissions).
Step 3 — Assign the role to a user, scoped to a unit
The scoping happens at assignment time. The same role can be assigned to different users with different unit scopes.UserRole assignments stack. A user can be Chapter Lead in Boston, Outreach Coordinator in Manchester, and Treasurer at the tenant level — three separate UserRole records.
Step 4 — Audit who has what
Who admins this local center?
hydra:totalItems gives the count.
Every assignment for one user
The org chart
Step 5 — Revoke
Delete theUserRole record:
User account is untouched — they remain a member; they just lose the elevated permissions immediately. Active sessions are not invalidated; revocation takes effect on the next request that re-evaluates permissions (which, for most endpoints, is the next request).
Step 6 — Restructure the hierarchy (parent locals)
For federations with regional hierarchy (“Northeast Region” containing Boston, New York, Philadelphia), set a parent on each local center:HR_PARENT_LOCAL on the parent (Northeast Region) can manage all children — Boston, New York, Philadelphia — without needing individual HR_LOCAL grants on each.
Step 7 — Self-service join
For local centers configured asisOpen: true, members can join themselves:
UserRole with the default member role for that local center. Useful for self-organizing chapters where any member can join.
Common gotchas
I granted ADMIN_TENANT but the user still gets 403 on some endpoints
I granted ADMIN_TENANT but the user still gets 403 on some endpoints
ADMIN_TENANT is the configuration domain — it grants access to settings, branding, modules. It does NOT grant HR (manage people) or FINANCIAL (manage payments). To grant truly everything, assign all three: ADMIN_TENANT, HR_TENANT, FINANCIAL_TENANT. This is intentional — it separates the “configure the org” role from the “see member PII” role from the “issue refunds” role.A local center deletion is blocked
A local center deletion is blocked
Local centers with active members, ongoing fees, or unresolved payments cannot be deleted. Reassign members to another center first (
PATCH /api/v1/users/{id} setting localCenter to the new one), then close out fees, then delete.Parent permissions don't seem to cascade
Parent permissions don't seem to cascade
PARENT_LOCAL scope only cascades when the parent relationship is set via local_centers.parent. Setting it via the Unit hierarchy alone doesn’t grant cascading permissions on local-center-scoped queries. If cascading isn’t working, double-check the LocalCenter has parent set correctly, not just the Unit.How do I bulk-assign one role to all chapter members?
How do I bulk-assign one role to all chapter members?
Two options: (1) automatic role groups — create a Unit of type “role group” filtered by membership criteria; new members auto-join. (2) Loop on the client side — paginate through
GET /api/v1/users?localCenter=... and POST one UserRole per. The bulk endpoint doesn’t exist for role assignment because the side effects (audit log, permission cache invalidation) are per-user.What to do next
- Permissions — the full domain × scope matrix
- Onboard a new member — the adhesion side of getting members into a local center
- Tenancy — how tenant isolation interacts with local-center scoping

