Add Access Policies
Put authorization rules in Inspire so reads, writes, routes, and live queries all follow the same model.
Kizaki policies are declarative. You define who can act on which rows, and the runtime enforces those rules everywhere. Authorization is part of the data model, not something each handler remembers to check.
Start With Ownership
For first apps, ownership policies are usually enough:
entity Project {
name: string,
ownerId: __User.id,
@grant read, write, delete where resource.ownerId == principal.id
}This one rule applies across:
- server-side queries
- generated client calls
- browser live queries
- related data loaded through includes
If your product has a clear concept of "my data", start with ownership. It is simple, readable, and hard to misinterpret later.
Add Roles When Needed
entity Invoice {
total: decimal(10, 2),
accountId: Account.id,
@grant read to role(Admin)
@grant read where resource.accountId == principal.accountId
@deny delete to *
}Use roles when access is organizational rather than personal.
Good role design stays small:
AdminManagerBillingSupport
Prefer a small set of durable roles over a large matrix of narrow permissions in your first version.
Keep App Code Thin
Follow this split:
- schema owns authorization
- server functions own workflow
- frontend owns presentation
If a rule can live in Inspire, keep it out of your UI code.
A Good Policy Design Sequence
For most apps, build policies in this order:
- ownership rules first
- role-based reads next
- role-based writes when needed
- deny rules for hard invariants
This sequence produces policies that stay readable as the app grows.
Next Step
Once access rules are in place, you can add business logic. Continue with Write Server Functions.