# Writing Policies With auth.uid() — Supabase

Source: https://www.skillbyai.com/en/supabase/r-policies

> Using and with check.

## USING and WITH CHECK

A policy targets a table, a command (`select`, `insert`, `update`, `delete` or `all`) and roles (`to authenticated`). The **USING** expression filters which existing rows are visible or affected; **WITH CHECK** validates new or changed rows on insert and update. Comparing a column with `auth.uid()` gives owner-only access. Wrapping it as `(select auth.uid())` lets Postgres evaluate it once per statement instead of per row, which Supabase recommends for performance.

## Owner-only notes

Four policies, one per command.

```sql
create policy "read own notes" on public.notes
  for select to authenticated
  using ((select auth.uid()) = user_id);

create policy "insert own notes" on public.notes
  for insert to authenticated
  with check ((select auth.uid()) = user_id);

create policy "update own notes" on public.notes
  for update to authenticated
  using ((select auth.uid()) = user_id)
  with check ((select auth.uid()) = user_id);

create policy "delete own notes" on public.notes
  for delete to authenticated
  using ((select auth.uid()) = user_id);
```

## Index the policy columns

Policies act like extra WHERE clauses; an index on `user_id` keeps them fast on large tables.

**Quiz:** Which clause validates the values of a newly inserted row?

- [ ] GRANT
- [ ] USING
- [x] WITH CHECK
- [ ] RETURNING

*Answer:* WITH CHECK. USING filters existing rows; WITH CHECK validates new ones.
