1. Platform
  2. Features
  3. Dynamic Permissions
Feature Dynamic Permissions

Your permission model. Not ours.

Most platforms force you into predefined roles or rigid permission systems. Canopy lets you define your own permission vocabulary, then stores, enforces, and evaluates it without hardcoding access rules into your application.

You define the keys Canopy enforces them Per-tenant isolation
yourapp · permission catalog YOUR VOCABULARY
billing
invoice.create
invoice.approve
invoice.export
reports
report.view
report.export
identity
identity.manage
user.deactivate
You define the vocabulary. Canopy enforces it consistently across your hierarchy.
Your model, not ours

You define the keys. Canopy never interprets them.

Define your own permission keys: invoice.read, report.export, identity.manage. Canopy doesn't assign meaning to them; it enforces them consistently across your hierarchy. Each account defines its own model, completely isolated from every other tenant.

invoice.readreport.exportidentity.manage
Acme Logistics Isolated
shipment.dispatchroute.assignfleet.manage
no shared vocabulary
Northwind Health Isolated
chart.viewrx.approvepatient.admit
Stop hardcoding access logic

Permissions are data, not code

Without dynamic permissions, access checks live in your codebase. Every new feature needs new conditionals, and changing a rule means a deployment.

access.js · before
// access rules baked into the app
if (user.role === 'admin' ||
(user.role === 'manager' &&
user.region === invoice.region)) {
allowInvoiceApproval();
}
// + 40 more conditionals…
Every change ships a deploy
access.js · with Canopy
// ask Canopy — rules live as data
const { data } = await canopy.post(
'/v1/permissions/evaluate',
{ identity_id, permission: 'invoice.approve',
scope: 'node', node_id }
);
if (data.allowed) approveInvoice();
Update roles without redeploying
Without dynamic permissions
  • Permission checks hardcoded in your app
  • Every new feature needs new conditionals
  • Changing access rules requires a deployment
With Canopy
  • Permissions are data, not code
  • Roles updated without redeploying
  • Access rules evolve with your product
Flexible structure

A simple resource.action pattern, to any depth

Permissions follow a predictable pattern, with unlimited depth for complex domains, and categories to keep them organized. The structure is yours to define.

billingResource
.
invoiceSub-resource
.
approveAction
Simple
invoice.create
Two segments cover most resources and actions.
Deep
billing.invoice.approve
Unlimited depth for complex domains.
Grouped
reports.*
Group by category to keep them organized.
Roles bundle permissions

Permissions are never assigned to users directly

You define permissions, bundle them into roles, then assign roles at nodes. Change the role's permissions and every holder updates instantly.

Permissions
report.view
report.export
identity.manage
Bundled into a role
Regional Manager
3 permissions
Assigned at a node
West Region
+ descendants
Edit the role once: every holder updates instantly.
Evaluated in real time

One question. One deterministic answer.

At runtime, your application asks Canopy: does this user have permission X at node Y? Canopy evaluates direct assignments, inherited roles, and active time windows, then returns a deterministic answer in a single API call.

Three inputs, resolved together

Direct roles, inherited roles, and time windows in one pass.

Deterministic & single-call

The same inputs always return the same answer.

evaluate → can u_8312 do "invoice.approve" at "west/sf" ?
Direct assignment
none at this node
Inherited role
Regional Manager · from west
Active time window
within valid range
allowed: true
via inherited · 1 API call · deterministic
Time-bound permissions

Access that starts later, or expires on its own

Grant access that starts in the future, expires automatically, or supports temporary roles for contractors. No cleanup required: expired access is ignored automatically at evaluation time.

Now · Jun 14
Jun 1 Jun 14 Jul 1 Aug 1 Sep 1
Q3 Auditor active · expires Sep 30
Contractor access starts Jul 1 → ends Aug 1
Temp admin expires in 3 days
Active now Scheduled (future) Expiring soon
Evaluate at scale

Check many permissions in one request

Check multiple permissions or identities at once. Build permission-aware UIs that show or hide features based on real access, and filter data by scope, without repeated API calls.

Batch checks across users and nodes
Permission-aware UIs that show or hide
Filter data based on scope
POST /api/v1/permissions/evaluate/bulk
Identityinvoice.
approve
report.
export
identity.
manage
DO D. Okafor
RT R. Tan
MK M. Khan
9 checks resolved in one request

Ready to simplify access control?

Create an account and have authentication and hierarchical access control running today.