Skip to Content
Getting StartedCore Concepts

Core Concepts

Before diving into the API, it helps to understand the four core building blocks of the platform.

Collections

A collection is a database table (or view). Every collection has a name, a primary key, and zero or more fields.

daas_users ← system collection (managed by the platform) daas_roles ← system collection posts ← custom collection you create products ← custom collection you create

You interact with any collection’s data through the Items API:

GET /api/items/posts → list posts POST /api/items/posts → create a post GET /api/items/posts/:id → get one post PATCH /api/items/posts/:id → update a post DELETE /api/items/posts/:id → delete a post

Fields

A field maps to a database column. Each field has a name, a data type, and optional metadata (interface type, display options, validation rules).

Field typePostgreSQL type
stringtext / varchar
integerint4
bigIntegerint8
floatfloat8
booleanbool
jsonjsonb
dateTimetimestamptz
uuiduuid

Additional types such as text, decimal, date, time, csv, hash, and binary are also supported.

Relational patterns — M2O (many-to-one), O2M (one-to-many), and M2M (many-to-many) — are local types that describe how a field relates to other collections. At the storage level, they use uuid columns with foreign key constraints.

Fields also carry interface metadata that drives the Data Studio’s form renderer (e.g., show a <input>, a rich-text editor, a file picker, etc.).

Items

An item is a single row in a collection. The platform treats every table the same way — system tables and user-defined tables share the same CRUD API surface.

Items support:

  • Filtering?filter[status][_eq]=active
  • Field selection?fields=id,title,author
  • Sorting?sort=-created_at
  • Pagination?limit=20&page=2
  • Relational data?fields=*,author.* (deep reads)
  • Aggregates?aggregate[count]=*

See Filter Rules for the complete filter syntax.

Access Control Model

Access control is built on four layers that compose from the most granular to the broadest:

┌─────────────────────────────────────────────────────────────┐ │ PERMISSIONS (what can be done on a collection) │ │ │ │ Read Posts Read Users Create Posts │ │ (public=true) (name & id only) │ │ │ │ Edit Posts Delete Posts Edit All Posts │ │ (own rows only) │ └──────────────────────────┬──────────────────────────────────┘ │ grouped into ┌──────────────────────────▼──────────────────────────────────┐ │ POLICIES (reusable bundles of permissions) │ │ │ │ Read Public Data │ Manage Own Posts │ Full Moderator │ └──────────────────────────┬──────────────────────────────────┘ │ assigned to ┌──────────────────────────▼──────────────────────────────────┐ │ ROLES (organisational groups) │ │ │ │ Viewer │ User │ Moderator │ └──────────────────────────┬──────────────────────────────────┘ │ assigned to ┌──────────────────────────▼──────────────────────────────────┐ │ USERS │ │ │ │ User 1 │ User 2 │ User 3 │ User 4 │ User 5 │ └─────────────────────────────────────────────────────────────┘

Permissions

A permission is the most granular unit of access control. It is always scoped to a collection and an action (create, read, update, delete, share), and can further restrict:

  • Item filter — which rows the rule applies to, using the same filter syntax as the API (e.g., only rows where user_created = $CURRENT_USER)
  • Field access — which columns are readable or writable for that action
  • Field validation — value constraints that must pass before a write is accepted
  • Field presets — default values automatically injected on create or update

A permission can grant all access, no access, or custom access for its collection/action pair.

Collection: posts Action: read Item filter: { "status": { "_eq": "published" } } Fields: id, title, slug, published_at

Policies

A policy is a named bundle of permissions that can be assigned to any number of roles or users. Instead of configuring permissions per-role, you define them once in a policy and reuse that policy wherever it applies.

Each policy also carries three top-level flags:

  • Admin access — bypasses all permission checks entirely
  • App access — allows the user to log in to the DaaS Studio
  • Delegate access — allows a service account to act on behalf of another user via the X-On-Behalf-Of request header

When a user has multiple policies (through multiple roles, or ones attached directly), their effective access is the additive union of all applicable policies:

  • Field access is merged — if Policy A exposes title and Policy B exposes body, the user sees both.
  • Item filters are combined with OR — a user matching either policy’s row condition can access those rows.

Policies only expand access — they can never revoke access granted by another policy. Design each policy around the minimum access it needs, then layer policies up to build more permissive roles.

Roles

A role is an organisational group (e.g., viewer, editor, moderator). Roles hold one or more policies and can be assigned to any number of users. Users can belong to multiple roles simultaneously — their effective permissions are the union of all policies across all their roles.

Two roles are seeded by default:

RoleLinked policyBehaviour
AdministratorAdmin Policy (admin_access = true)Full system access — bypasses all permission checks.
UserUser Policy (admin_access = false)Standard user access — subject to all permission rules.

You can create additional roles and attach any combination of policies to them.

Public access applies to every authenticated user regardless of role. It is represented by policy entries in daas_access with no role and no user set. Any policy linked this way grants its permissions to all logged-in users as a default layer. Unauthenticated access is not supported — every data API route requires authentication. All access is off by default — opt-in only.

Last updated on