Permissions that read
like sentences.
Define actions, compose them into roles, and grant them to your product's users — then answer any access question in one call.
Actions compose into roles
granted to your users.
Three primitives cover the whole access story. Your team operates the console while your product's users live in the graph — keyed by your own IDs, checked in one call.
Actions
The atomic things a user can do — invoices.refund, members.invite. You define them.
Roles
Named bundles of actions. Editor, Support, Finance — whatever your org calls them.
Grants
Users hold roles. A user can hold several; access is the union of all of them.
Any access question.
Ships in an afternoon.
Every read and write is evaluated against the grant graph in the database itself, so a client can never talk itself into an action it doesn't hold.
?subject=user_123&permission=invoices.refund { "subject": "user_123", "permission": "invoices.refund", "allowed": true }
More than allow or deny
the whole workflow around it.
One-call checks
Every read and write is evaluated against the grant graph in the database itself.
External subjects
Your product's users connect by their own IDs. Console accounts never enter the graph.
Fresh by default
No seeded roles, no demo actions. Your graph starts empty and stays yours.
Union semantics
Hold several roles and your access is simply the union of all of them.
Full audit trail
Every grant, revocation and policy edit lands in the activity log.
Join requests
Nobody self-joins a workspace. Membership starts with an approved request.