Analyze Supabase Row Level Security policies
Analyzes Supabase Row Level Security policies for gaps and weaknesses.
/plugin marketplace add Rahat-ch/vibe-check/plugin install rahat-ch-vibe-check@Rahat-ch/vibe-checkAnalyze Supabase Row Level Security policies for gaps and weaknesses.
Usage: /vibe-check:rls
Check for Supabase project structure:
supabase/
├── config.toml
├── migrations/
│ ├── 20240101000000_init.sql
│ └── ...
└── seed.sql
If no supabase/ folder, check for:
.sql files in project rootprisma/ folder (different approach needed)Read all .sql files in supabase/migrations/.
Extract:
Missing RLS (HIGH): Tables with CREATE TABLE but no corresponding:
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
Overly Permissive Policies (HIGH):
CREATE POLICY "..." ON table_name FOR ALL USING (true);
CREATE POLICY "..." ON table_name FOR ALL WITH CHECK (true);
Missing Operation Policies (MEDIUM): Table has SELECT policy but missing INSERT/UPDATE/DELETE policies.
No User Scoping (MEDIUM):
Policies that don't reference auth.uid():
CREATE POLICY "..." USING (status = 'published'); -- No user check
Read supabase/config.toml for security settings:
[auth]
enable_signup = true # Should be false if invite-only
Flag if:
enable_signup = true in production configsAfter static analysis, use AskUserQuestion to offer:
Want me to verify RLS policies in your live Supabase dashboard?
Requires: Claude Chrome extension + logged into Supabase
Options:
- Yes, check via browser
- No, skip (I'll check manually)
If yes, use Claude Chrome extension:
supabase/.env or ask userhttps://supabase.com/dashboard/project/[ref]/auth/policiesread_page to extract RLS status for each tableAlways include:
Manual RLS Verification:
1. Go to Supabase Dashboard → Table Editor
2. Click each table → "View Policies" (shield icon)
3. Verify:
- RLS is "Enabled" (green badge)
- Policies exist for SELECT/INSERT/UPDATE/DELETE as needed
- Conditions reference auth.uid() appropriately
SQL Query to check RLS status:
SELECT schemaname, tablename, rowsecurity
FROM pg_tables
WHERE schemaname = 'public';
[HIGH] Missing RLS on table: profiles
File: supabase/migrations/001_init.sql:45
Issue: Table created without Row Level Security
Risk: Any authenticated user can read/write all rows
Fix:
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view own profile"
ON profiles FOR SELECT
USING (auth.uid() = user_id);
CREATE POLICY "Users can update own profile"
ON profiles FOR UPDATE
USING (auth.uid() = user_id);
User-owned data:
USING (auth.uid() = user_id)
Public read, owner write:
FOR SELECT USING (true)
FOR INSERT/UPDATE/DELETE USING (auth.uid() = user_id)
Role-based:
USING (
auth.uid() IN (
SELECT user_id FROM user_roles WHERE role = 'admin'
)
)