Skip to main content

Table Access Permissions

SpacetimeDB enforces different levels of table access depending on the context. All contexts access tables through ctx.db, but the available operations differ based on whether the context is read-write or read-only.

Reducers - Read-Write Access

Reducers receive a ReducerContext which provides full read-write access to tables. They can perform all CRUD operations: insert, read, update, and delete.

spacetimedb.reducer('example', {}, (ctx) => {
  // Insert
  ctx.db.user.insert({ id: 0, name: 'Alice', email: 'alice@example.com' });

  // Read: iterate all rows
  for (const user of ctx.db.user.iter()) {
    console.log(user.name);
  }

  // Read: find by unique column
  const foundUser = ctx.db.user.id.find(123);
  if (foundUser) {
    // Update
    foundUser.name = 'Bob';
    ctx.db.user.id.update(foundUser);
  }

  // Delete
  ctx.db.user.id.delete(456);
});

Procedures with Transactions - Read-Write Access

Procedures receive a ProcedureContext and can access tables through transactions. Unlike reducers, procedures must explicitly open a transaction to read from or modify the database.

spacetimedb.procedure('updateUserProcedure', { userId: t.u64(), newName: t.string() }, t.unit(), (ctx, { userId, newName }) => {
  // Must explicitly open a transaction
  ctx.withTx(ctx => {
    // Full read-write access within the transaction
    const user = ctx.db.user.id.find(userId);
    if (user) {
      user.name = newName;
      ctx.db.user.id.update(user);
    }
  });
  // Transaction is committed when the function returns
  return {};
});

See the Procedures documentation for more details on using procedures, including making HTTP requests to external services.

Views - Read-Only Access

Views receive a ViewContext or AnonymousViewContext which provides read-only access to tables. They can query and iterate tables, but cannot insert, update, or delete rows.

spacetimedb.view(
  { name: 'findUsersByName', public: true },
  t.array(user.rowType),
  (ctx) => {
    // Can read and filter
    return Array.from(ctx.db.user.name.filter('Alice'));

    // Cannot insert, update, or delete
    // ctx.db.user.insert(...) // ❌ Method not available
  });

Client Access - Read-Only Access

Clients connect to databases and can access public tables through subscriptions and queries. See the Subscriptions documentation for details on client-side table access.