Assign Roles
Give identities the access a role bundles: one identity at a time, or many at once.
Overview
An assignment is the link between a role and an identity. Until a role is assigned to someone, nothing it bundles applies to anyone. Each assignment is a three-part record: identity_id, role_id, and node_id: the identity getting access, the role being granted, and the node in your Environment's hierarchy where the role takes effect. In flat RBAC the node_id is always your Environment's root, so the visible decision is just who and which role. Before you can assign a role, the identity has to exist at the Account and have active access to the Environment. See the Identities overview for the three-layer model.
Scope
Role assignments are scoped to an Environment
When you assign a role to an identity at a node, the assignment lives in the active Environment, the one selected on the Tenant › Applications page. An identity is a single record in your Account directory, not duplicated per Environment, but it reaches an Environment only once you grant it access there, and the rows that say "this identity holds this role at this node" are per-Environment on top of that. Adding an identity to your Account does not place it in any Environment automatically.
This is what makes safe iteration possible: you can hand out roles freely in Development to test invite flows or evaluator behavior, with zero risk of granting access in Production by accident.
What an assignment grants
When you assign a role, the identity gains every permission the role bundles, at the target node and at every descendant via cascade. There's no separate publish step or cache flush:
If you ever need to revoke, removing the assignment row stops the cascade just as immediately.
Under the hood, Canopy evaluates access by walking up the node's lineage, collecting every active assignment along the way, and unioning the permissions from each role. The evaluate endpoint is the canonical source of truth at any moment.
Examples
Flat RBAC
Assign the role Manager to Alice. In flat RBAC every assignment lands at your Environment's single root node:
Acme ProductionAlice now has Manager permissions across your entire Environment, because there's no narrower scope to choose.
Hierarchy
Assign the role Store Manager to Alice at the node Store #42:
Store #42
├── Electronics
├── Clothing
└── WarehouseAlice now has Store Manager permissions at every node in that subtree:
Direct vs Inherited
When evaluating a permission for an identity at a node, Canopy walks the hierarchy from that node up to the root, gathering every assignment that applies. The result is a union of:
An identity needs only one assignment at the highest applicable level, with no per-leaf duplication. Assign a Regional Manager role at the North America node and it covers every office, team, and identity beneath it.
Multiple roles per identity
An identity can hold many roles at the same node. The unique constraint is the three-tuple (identity_id, role_id, node_id), not the two-tuple (identity_id, node_id), so you can stack a Manager role on top of a Member role for the same person at the same place. Permissions union across roles, so the identity's effective access is the combination of every role they hold. There is no implicit role hierarchy: assigning Admin doesn't auto-replace Member; both rows live independently and both contribute to the union.
Assignments are additive: removing one role doesn't affect any other roles the same identity holds.
Time-bound access
Every assignment carries an effective window. effective_from defaults to the moment the assignment is created; effective_to defaults to never. Together they place the assignment in one of three states:
The evaluator factors the lifecycle in automatically: a scheduled assignment doesn't grant access until its start date, and an expired one stops granting on its end date. No cron jobs, no manual cleanup.
Next Step
Tell us how we can improve this guide.