Module 6: Databases & Auth with Supabase
Lesson 2

Supabase Setup — Project, tables, Row Level Security


Now you'll create a real database. By the end of this lesson you'll have a Supabase project, your first table, and — most importantly — security rules that keep each user's data private. You won't write any SQL by hand; the dashboard and Claude handle that.


Create Your Supabase Account

  1. Go to supabase.com
  2. Click Start your projectSign up
  3. Sign up with GitHub (recommended — keeps your tools connected) or email
  4. Verify your email if prompted

Create a New Project

  1. Once logged in, click New project
  2. Fill in the details:
    • Organization: Supabase creates one automatically; your name is fine
    • Project name: Match your app (e.g., focus-dashboard)
    • Database Password: Click Generate for a strong one. Save it somewhere safe — you'll need it later and Supabase won't show it again
    • Region: Pick the one closest to you (e.g., Southeast Asia – Singapore, US East, EU West) so your app feels fast
  3. Click Create new project

Supabase takes 1–2 minutes to provision the database. Let it finish before moving on.


A Tour of the Dashboard

Once the project is ready, you'll land on the dashboard. The sections you'll actually use:

SectionWhat it's for
Table EditorA spreadsheet-like view of your tables. Create tables, add rows, and browse data — no SQL needed.
SQL EditorWrite and run SQL directly. Useful for advanced operations; Claude often hands you SQL to paste here.
AuthenticationManage users, configure login methods, see who's signed up.
StorageStore files (images, documents). Not needed yet, handy later.
APIAuto-generated docs showing how to query your data.

Getting Your API Keys

Your app needs two values to connect to Supabase:

  1. In the dashboard, open Settings (the gear icon)
  2. Click API
  3. You'll see:
    • Project URL — looks like https://abcdefgh.supabase.co
    • Project API keys → anon public — a long string of characters

Keep this tab open; you'll copy both values into your app in the next lesson.

Security — the most important rule in this module. The anon (publishable) key is safe to expose in frontend code; it's designed for the browser. The service_role key is a master key that bypasses every security rule — it must never appear in browser code, in a NEXT_PUBLIC_* variable, or anywhere a visitor could read it. Treat it like a root password and keep it server-only. We won't use it at all in these lessons.


Creating Your First Table

Let's build the main table for your app using the Table Editor — no SQL required.

  1. Click Table EditorNew table
  2. Fill in:
    • Name: tasks (or whatever your main table is)
    • Enable Row Level Security (RLS):Yes — always. We'll configure the rules in a moment.
    • Enable Realtime: optional for now
  3. Supabase automatically adds id and created_at. Add your own columns with Add column:
Column nameTypeDefaultNotes
titletextNot null
doneboolfalseNot null
user_iduuidReferences auth.users.id
  1. Click Save

Linking Tasks to Users (Foreign Key)

The user_id column connects each task to the person who owns it. When adding that column:

  1. Set the type to uuid
  2. Find the Foreign key relationship option
  3. Choose: schema auth, table users, column id

This means every task must point to a real user in Supabase's authentication system — which is exactly how, later, your app shows each person only their own tasks.


Row Level Security (RLS): The Heart of Safe Data

RLS is the rule that stops one user from reading or deleting another user's data. It runs inside the database itself, so even if your app code has a bug, the database refuses to hand over rows a user shouldn't see.

  • Without RLS: any logged-in user could read, edit, or delete everyone's tasks.
  • With RLS: you define rules like "a user can only SELECT rows where user_id equals their own id."

This is why you enabled RLS when creating the table. Now you add the policies — the specific permissions.

Setting Up the Four Policies

In the Table Editor, open your tasks table → Policies (or RLS). Add one policy per operation:

Policy nameOperationExpression
Users can read own tasksSELECTUSING: auth.uid() = user_id
Users can insert own tasksINSERTWITH CHECK: auth.uid() = user_id
Users can update own tasksUPDATEUSING: auth.uid() = user_id
Users can delete own tasksDELETEUSING: auth.uid() = user_id

auth.uid() is Supabase's shorthand for "the currently logged-in user's id." So every rule reads: only touch rows that belong to me.

You don't have to click through these by hand. Hand the job to Claude:

Set up Row Level Security policies for the tasks table in Supabase. Users should only be able to read, insert, update, and delete their own tasks — rows where user_id = auth.uid(). Give me the SQL to paste into the Supabase SQL Editor.

Paste the SQL it produces into SQL Editor and run it.

Remember: enabling RLS on a table with no policies means no one can access anything (deny by default). That's a safe starting point — you open access deliberately by adding the four policies above, not accidentally.


Turning On Login Methods

By default Supabase enables email/password authentication, which is enough for most apps.

To check or adjust:

  1. Go to AuthenticationProviders
  2. Email is on by default — leave it
  3. Optional: enable Google or GitHub for one-click sign-in

Google sign-in is nicer for users but needs a Google Cloud project and OAuth credentials. Supabase links to a setup guide right in the provider settings — we'll come back to it in the authentication lesson.


Summary

  • Create a Supabase account and project at supabase.com; save the database password.
  • Grab your Project URL and anon key from Settings → API for the next lesson.
  • Build tables in the Table Editor — no SQL needed for the basics.
  • Always enable Row Level Security on every table.
  • Add RLS policies (read/insert/update/delete) so users only touch their own rows; Claude can generate the SQL.
  • The anon key is browser-safe; the service_role key is server-only and must never reach the browser.