Tables and schema
Every project is a Postgres database. Create tables in the dashboard (table editor or SQL editor), with migrations or through the Management API.
Secure by default
Section titled “Secure by default”A new table in an exposed schema is unreadable twice over:
- RLS is switched on automatically for every
CREATE TABLEinpublic(andapi, if you expose it). RLS with no policy means deny all. - No table grants for
anonorauthenticated. You grant privileges and write policies yourself. See row level security.
Functions follow the same rule: no function is executable by PUBLIC. An RPC becomes callable only after grant execute ... to authenticated (or anon).
Exposed schemas
Section titled “Exposed schemas”Only public is exposed to the REST API by default. You can opt in to an api schema in the project’s Data API settings and select it in the SDK:
const base = createClient({ url, key, db: { schema: "api" } })The schemas auth, storage, realtime, base and extensions can never be exposed.
Example
Section titled “Example”create table public.orders ( id bigint generated by default as identity primary key, user_id uuid not null default auth.uid(), total numeric not null, created_at timestamptz not null default now());create index on public.orders (user_id);grant select, insert, update, delete on public.orders to authenticated;Migrations
Section titled “Migrations”Keep schema changes as versioned SQL files and apply them with potalab base db push or the Management API. Pick one path per project. See the CLI.
Generated types
Section titled “Generated types”potalab base gen types turns your schema into a Database type for createClient<Database>(). Nullable columns become | null, columns with defaults are optional on insert, and identity ALWAYS and generated columns are typed never.
Security advisor
Section titled “Security advisor”The dashboard Advisors page and potalab base lint report tables without RLS, unwrapped auth.uid() calls, missing indexes and more. See row level security.