FOR SUPABASE USERS

RLS Policies That Actually Work

You love Supabase. You just hate writing Row-Level Security policies by hand. Quickback compiles them from your TypeScript definitions - every edge case covered, every policy auditable in git.

Read the Docs

RLS Is Powerful. Writing It Is Painful.

Row-Level Security is the right approach. But the developer experience is brutal.

One missed policy = data leaks between tenants

Policies are SQL strings with no type safety

Hard to review in PRs - easy to miss bugs

No compile-time validation - fails at runtime

Define Once. Compile to RLS.

Write your security rules in TypeScript. Quickback compiles them into production-ready RLS policies.

quickback/features/todos/todos.ts
export default defineTable(todos, {
  firewall: { organization: {}  },
  guards: {
    createable: ["title", "content"],
    updatable: ["title", "content"],
    protected: { status: ["complete"] },
  },
  crud: {
    list:   { access: { roles: ["member", "admin"] } },
    create: { access: { roles: ["member", "admin"] } },
    update: { access: { roles: ["member", "admin"] } },
    delete: { access: { roles: ["admin"] } },
  },
});
compiled RLS output
-- Generated by Quickback Compiler

-- Firewall: org isolation
CREATE POLICY "todos_org_isolation" ON "todos"
  FOR ALL USING (
    organization_id = auth.jwt() ->> 'org_id'
  );

-- Access: list + select
CREATE POLICY "todos_select" ON "todos"
  FOR SELECT USING (
    auth.jwt() ->> 'role' IN ('member', 'admin')
  );

-- Access + Guards: insert (title, content only)
CREATE POLICY "todos_insert" ON "todos"
  FOR INSERT WITH CHECK (
    auth.jwt() ->> 'role' IN ('member', 'admin')
  );

-- Access + Guards: update (title, content only)
CREATE POLICY "todos_update" ON "todos"
  FOR UPDATE USING (
    auth.jwt() ->> 'role' IN ('member', 'admin')
  );

-- Guards: restrict writable columns
CREATE FUNCTION todos_guard_columns()
  RETURNS TRIGGER AS $$
BEGIN
  IF TG_OP = 'INSERT' THEN
    -- createable: title, content
    NEW.status := NULL;
  ELSIF TG_OP = 'UPDATE' THEN
    -- updatable: title, content
    -- protected: status (action-only)
    NEW.status := OLD.status;
  END IF;
  RETURN NEW;
END; $$ LANGUAGE plpgsql;

-- Access: delete (admin only)
CREATE POLICY "todos_delete" ON "todos"
  FOR DELETE USING (
    auth.jwt() ->> 'role' = 'admin'
  );

Same Drizzle schema you already use

Generates org isolation, role-based access, field protection

Validates at compile time - won't generate if config is incomplete

Auditable in version control

Keep Everything You Love

Quickback adds security policies. Everything else stays exactly the same.

Supabase Auth

Unchanged

Supabase Storage

Unchanged

Supabase Realtime

Unchanged

Supabase Dashboard

Unchanged

Quickback + Claude Code

Let AI define your RLS policies

Connect the Quickback Skill to Claude Code and describe your security rules in plain English. Claude writes your defineTable() definitions, Quickback compiles them to RLS - no manual policy writing at all.

Also by Kardoe

Supa Tools - Auth Email Designer

Design and preview your Supabase auth email templates visually. Confirmation emails, magic links, password resets - styled and ready to deploy.

Visit supa-tools.com

When You're Ready for More

The same definitions that compile to Supabase RLS can also compile to a full Cloudflare stack - auth, database, storage, realtime, edge functions - running on your own account. And the Account UI gives you a ready-made auth frontend.

Start with compiled RLS. Graduate to the full stack when you're ready.

Stop Writing RLS by Hand

Join the beta and let the compiler handle your security policies.

Read the Docs