Skip to content
Back to skills

Supabase

ASecurity

Supabase migrations, RLS policies, auth integration and generated TypeScript types. Use when creating Supabase tables or migrations, writing RLS policies, or wiring Supabase auth.

  • 80 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added May 28, 2026
ai-agentstypescriptgobashsqlgitdatabasesecurity

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned October 5, 2026

npx -y skills add monkilabs/opencastle --skill supabase-database --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Supabase?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Supabase
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/monkilabs-supabase/badge)](https://www.skillsdirectory.com/skills/monkilabs-supabase)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: supabase-database
description: "Supabase migrations, RLS policies, auth integration and generated TypeScript types. Use when creating Supabase tables or migrations, writing RLS policies, or wiring Supabase auth."
---

# Supabase Database

Project schema, roles, migration history, auth flow, and key files: `.opencastle/stack/supabase-config.md`. Docs: https://supabase.com/docs

## RLS gotchas

- **`ENABLE ROW LEVEL SECURITY` with no policy denies everything.** Enabling and adding policies must land in the same migration.
- Policies are per-operation. `FOR SELECT USING (...)` does not cover writes; `INSERT` needs `WITH CHECK`, not `USING`.
- `auth.uid()` is the owner check (`auth.uid() = id`). It is `NULL` for the `anon` role, so any policy relying on it silently blocks anonymous access.
- Policies target the Postgres roles `anon`, `authenticated` and `service_role` (which bypasses RLS). Test every policy as `anon` and as `authenticated`, plus any app-level role your policies check. A policy that works as your own user tells you nothing about `anon`.
- Reference `auth.users(id)` with `ON DELETE CASCADE` on profile-style tables, or deleted users leave orphans.

Confirm RLS coverage before shipping:

```sql
SELECT tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public';
```

## Migration workflow

1. Create the file with `supabase migration new add_profiles` (it writes `supabase/migrations/<14-digit timestamp>_add_profiles.sql`); comment intent and rollback considerations inline.
2. Apply to a local/ephemeral DB; run smoke tests plus per-role RLS checks.
3. Review the SQL for destructive actions (table drops, column rewrites) — those need a backfill script and phased rollout, never a single migration.
4. Re-run in CI against a test replica with the full suite.
5. Deploy via the safe-deploy pipeline, then re-verify RLS, indexes, and a data sanity query.

Regenerate types after every schema change (CI step):

```bash
supabase gen types typescript --project-id <project-id> > src/types/supabase.ts
```

Assert at steps 2 and 4 that the migration completes, per-role RLS queries still pass, and tests on changed paths pass. On failure: revert, adjust, re-run.

Files in this skill

  • REFERENCE.md306 B
  • SKILL.md2.6 KB
  • config.ts1.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…