Repository navigation
Authorization Patterns
gaiacasalinuovo-hub edited this page Aug 20, 2026
·
4 revisions
Define a permission branch on each endpoint for each supported role. Missing roles are rejected.
{ type: "DELETE", admin: ALL, editor: NONE, viewer: NONE }viewer: {
allowed: ["id", "display_name", "avatar_url"],
disallowed: ["email", "password_hash"]
}user: {
allowed: {
field: ["id", "title", "owner_id"],
where: { field: "owner_id", operator: "=", value: "$user.id" }
},
disallowed: []
}Bind every protected table to the tenant identity established by the server-side session.
where: { field: "workspace_id", operator: "=", value: "$user.workspace_id" }Apply the same principle to joined tables and mutation endpoints; a tenant filter on only one read path is not an isolation strategy.
Use $data to evaluate the proposed mutation. For example, a transition can require a specific current state and an intended next state.
Prefer an explicit admin branch such as ALL over hidden exceptions. This keeps elevated access reviewable in the structure.
- Trusting a role string supplied by the client.
- Adding VoidQL checks to reads but bypassing them for background jobs or mutations.
- Using
ALLfor convenience without a documented reason. - Relying on response filtering after unauthorized rows were fetched.
- Treating field denial as a substitute for tenant row isolation.
VoidQL is experimental and under active development · Documentation home · Status & limitations
Start Here
Learn & Build
- Learn VoidQL
- Build with VoidQL
- Query Operations
- Authorization Patterns
- Validation & Workflows
- Triggers & Extensibility
Use & Reference
Internals & Project