Skip to content

Database and RLS

Each app receives one PostgreSQL schema exposed through same-origin PostgREST. Migrations use unqualified object names because OpenCloud selects the schema.

Owner-isolated records

sql
create table items (
  id uuid primary key default gen_random_uuid(),
  owner_id uuid not null default auth.uid(),
  title text not null check (length(title) between 1 and 200),
  created_at timestamptz not null default now()
);

create index items_owner_created_idx
  on items(owner_id, created_at desc);

create policy items_owner_access
  on items for all
  using (owner_id = auth.uid())
  with check (owner_id = auth.uid());

OpenCloud enables and forces RLS, then adds a restrictive app boundary. Application policies are still required for business access.

Shared member records

For data shared with every authorized app member:

sql
create policy items_member_access
  on items for all
  using (true)
  with check (true);

The permissive policy does not cross the platform’s restrictive app boundary. Declare data.mode: shared in the verification contract for this model.

REST patterns

Read:

js
const response = await opencloud.rest.request(
  "items?select=id,title,created_at&order=created_at.desc",
);

Insert:

js
const response = await opencloud.rest.request("items", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    prefer: "return=representation",
  },
  body: JSON.stringify({ title: "New item" }),
});

Update:

js
await opencloud.rest.request(`items?id=eq.${encodeURIComponent(id)}`, {
  method: "PATCH",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({ title: "Updated item" }),
});

Migration safety

Deployments preflight the full migration history in a disposable schema using the pinned runtime and constrained migration role before changing the live app schema. Static policy validation still runs first.

See Migration SQL for supported and forbidden capabilities.

Self-hosted infrastructure for agent-built applications.