Quickback Docs
Quickback for Supabase

Limitations

What Quickback for Supabase doesn't compile to RLS, and how to handle those concerns in app code or Edge Functions.

The Supabase target compiles schema, firewall, and access to RLS. The other Quickback primitives are runtime concerns that RLS can't express. This page lists what doesn't compile and where to handle it.

Actions

defineActions() describes custom endpoints with input validation, role checks, and side effects. RLS only governs row access, not arbitrary procedures.

Where to handle them:

  • Supabase Edge Functions — port the action body to a TypeScript Deno function. Role checks happen in the function; the underlying database mutations still pass through your RLS policies.
  • Postgres functions — for simple state transitions, write a CREATE FUNCTION and call it via supabase.rpc(). Use SECURITY INVOKER (the default) so RLS still applies.
  • Your application server — any backend you already run can host the action, with the JWT forwarded to Supabase for the underlying writes.

Views

Quickback views define column-level projections per role (e.g. "members see name + email; admins also see salary"). RLS gates rows, not columns.

Where to handle them:

  • Postgres viewsCREATE VIEW with SELECT lists matching each Quickback view. Apply RLS to the view or the underlying table.
  • Column lists in queries — pass the projection at the application layer: supabase.from('users').select('id, name, email').
  • Column-level grantsGRANT SELECT (col1, col2) ON table TO role for fine-grained server-side restriction.

Masking

Masking redacts sensitive fields per role at response time (email → j***@example.com, SSN → ***-**-1234). This is purely a runtime transformation — the data is in the row, RLS just decides whether the row is returned.

Where to handle it:

  • Edge Functions or your server — apply the mask in the layer that serializes the response.
  • Postgres functions — for SQL-driven masking, write a wrapper view or function that applies the mask conditionally on auth.jwt() ->> 'role'.

Guards

guards block field modifications based on row state, role, or external context (e.g. "members can change notes but not status; only admins can set archived"). Some of this can be expressed with RLS WITH CHECK, but the full Quickback guard model is richer than RLS supports.

Where to handle them:

  • WITH CHECK clauses — simple field-level guards (e.g. "only admins can set archived = true") can sometimes be expressed via more granular FOR UPDATE policies.
  • TriggersBEFORE UPDATE triggers can RAISE EXCEPTION if a guarded field is modified by a non-eligible role.
  • Edge Functions / app server — for anything stateful or context-dependent, validate guards in the layer that issues the update.

Generated API routes, batch ops, OpenAPI, MCP

These are Hono-target features. The Supabase target doesn't generate application code — your app talks to Supabase directly (PostgREST, Edge Functions, or your own server).

If you want generated routes alongside RLS, consider compiling to the Hono target with Neon, which gives you both the generated API and database-level RLS.

On this page