Access
Access answers what an actor is allowed to do, and where. Who the actor is — human, machine, federated, on-behalf-of — is the Identity concern; this page covers the authorization layer that sits on top.
The model is the same for every actor: a single capability/scope/role system applies to humans, service principals, platform-hosted users, and federated users. Governance never splits into two systems for different identity sources.
Action Classes
Not every API action needs the same kind of accountability:
- Machine-native — repeatable, deterministic work where the human behind the request does not change its business meaning. Reads, reconciliation, webhook maintenance, routine provisioning. Service principal as actor is normal.
- Human-governed — actions that require an identifiable actor of record: governance changes, sensitive lifecycle mutations, payout destination changes, anything subject to four-eyes or approval. A real human must be on the request, even when the transport is machine-driven (see Acting On Behalf Of A Human).
Capabilities And Scopes
Authorization is expressed through two independent axes:
- Capabilities describe what an actor can do —
clients.read,clients.manage, and so on. They are atomic, named permissions. - Scopes describe where the actor can do it. A scope can be a
whole topology perimeter (
enterprise,client) or narrow further to a specific account (master-account,client-account).
A caller is allowed an operation only if both axes match: they hold the required capability, and that capability is granted inside a scope that covers the target resource.
The benefit is real least-privilege without exploding into bespoke roles per resource. You can grant the same capability broadly (the whole enterprise) or narrowly (one client account) by changing only the scope.
Each grant also declares how far it reaches inside the topology graph:
- subtree — the grant covers the named scope and everything under it; an enterprise-level subtree grant reaches every client and client account inside.
- self — the grant covers only the exact named scope, with no descendants; useful for narrow exceptions.
Propagation is part of the assignment, not an implicit property of the topology, so you opt in to coverage rather than getting it by accident.
Roles And Role Assignments
Capabilities are bundled into reusable roles. A role assignment binds a role to an actor inside a specific scope.
Three layers, three responsibilities:
Capability— atomic permission nameRole— named bundle of capabilitiesRoleAssignment—(actor, role, scope)triple that grants the role to the actor inside that scope
Roles are reusable across actors and scopes — the same Treasury Ops
role can be assigned to a human user inside one client and to a
service principal inside another, without duplicating the bundle.
Revoking access removes a role assignment; it does not delete the
actor or the role.
How This Appears In The API
Request URL
POST /role-assignmentsRequest Body
{
"actor_ref": "users/88888888-8888-4888-8888-888888888888",
"role_ref": "roles/99999999-9999-4999-8999-999999999999",
"scope_ref": "clients/44444444-4444-4444-8444-444444444444"
}Response
{
"id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
"resource": "role-assignments/aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
"actor_ref": "users/88888888-8888-4888-8888-888888888888",
"role_ref": "roles/99999999-9999-4999-8999-999999999999",
"scope_ref": "clients/44444444-4444-4444-8444-444444444444",
"status": "active"
}