Skip to Content
DocsConceptsAccess control

Access control

Each collection has one rule per operation: read, create, update, delete. A rule returns true, false or a where filter. It may be async.

import { defineCollection, fields as f } from "@quickben/core"; export const posts = defineCollection({ slug: "posts", fields: { title: f.text({ required: true }), status: f.select({ options: ["draft", "published"], required: true, default: "draft" }), author: f.relation({ to: "users" }), }, access: { read: ({ user }) => (user ? true : ({ status: { eq: "published" } } as const)), create: ({ user }) => user !== null, update: ({ user }) => (user ? { author: { eq: user.id } } : false), delete: ({ user }) => user?.roles?.includes("admin") === true, }, });

Anonymous users read published posts. Signed-in users read all posts and edit only their own. Admins delete.

Results

OperationtrueA filter
readall documentsAND-ed with the query. findById of a filtered-out document is NOT_FOUND.
createallowedThe new document, after hooks, must match.
updateallowedThe stored document must match.
deleteallowedThe stored document must match.

false throws UnauthorizedError when there is no user and ForbiddenError when there is one.

Defaults

SituationBehavior
No rule for an operationSigned-in users only.
overrideAccess: true in ctxRules are skipped.
// Trusted server code only, e.g. a seed script or a webhook handler. await qb.create("tags", { name: "news" }, { user: null, overrideAccess: true });

Rule arguments

ArgumentValue
userQuickbenUser or null
reqThe Request, when the call has one
operation"read", "create", "update" or "delete"
idDocument id for update, delete and findById
dataInput data for create and update

Filters returned by rules use the same query model as find. They are typed from the collection’s fields.

Last updated on