QUESTPIE
Build Your BackendRules

Access Control

Control who can read, create, update, and delete records at the operation, row, and field level.

Access control determines who can perform operations on your collections and globals. Rules are defined per-collection and receive the full request context.

Basic Access Rules

collections/posts.ts
.access({
  read: true,                                           // Public read
  create: ({ session }) => !!session,                   // Authenticated users
  update: ({ session }) => session?.user?.role === "admin",  // Admin only
  delete: ({ session }) => session?.user?.role === "admin",
})

Each operation accepts either:

  • boolean — Static allow/deny
  • (context) => boolean — Dynamic function receiving the request context

Operations

OperationWhen checked
readListing and fetching records
createCreating new records
updateUpdating existing records
deleteDeleting records

Context

Access functions receive the full AppContext:

.access({
  update: ({ session, db }) => {
    if (!session) return false;
    return (session.user as any).role === "admin";
  },
})

Available context properties:

  • session — Current auth session (null if unauthenticated)
  • db — Database instance
  • collections — Typed collection API
  • Any custom services injected via AppContext

Global Access

Globals support read and update (no create/delete since they're singletons):

globals/site-settings.ts
.access({
  read: true,
  update: ({ session }) => (session?.user as any)?.role === "admin",
})

System Access Mode

Server-side code can bypass access control using accessMode: "system":

const ctx = await app.createContext({ accessMode: "system" });
const allPosts = await app.collections.posts.find({}, ctx);
// No access checks — useful for server-side scripts, jobs, seeds

HTTP requests from clients always use the session-based access mode.

Real-World Patterns

Public read, admin write

.access({
  read: true,
  create: ({ session }) => (session?.user as any)?.role === "admin",
  update: ({ session }) => (session?.user as any)?.role === "admin",
  delete: ({ session }) => (session?.user as any)?.role === "admin",
})

Authenticated-only

.access({
  read: ({ session }) => !!session,
  create: ({ session }) => !!session,
  update: ({ session }) => !!session,
  delete: false,  // Never allow deletion
})

Owner-only updates

.access({
  read: true,
  update: ({ session }) => {
    if (!session) return false;
    // Return a where clause to limit updates to own records
    return { author: session.user.id };
  },
})

On this page