Install
openclaw skills install supabase-security-auditorAudit Supabase projects for security — check Row Level Security policies, auth configuration, API exposure, storage rules, and edge function security.
openclaw skills install supabase-security-auditorAudit Supabase projects for security vulnerabilities including Row Level Security (RLS) policies, authentication configuration, API key exposure, storage bucket rules, and edge function security. Use before launching, after configuration changes, or during security reviews.
"Audit my Supabase project for security"
"Check RLS policies on all tables"
"Review auth configuration for vulnerabilities"
"Are my Supabase storage buckets secure?"
# Find Supabase config
cat supabase/config.toml 2>/dev/null
ls supabase/migrations/ 2>/dev/null | tail -10
# Find API usage
grep -rn "createClient\|supabase\." src/ lib/ app/ | head -20
# Check for exposed keys
grep -rn "SUPABASE_\|supabase\.\(url\|key\|anon\)" .env* src/ | head -10
Critical checks:
using (true))auth.uid() correctly for ownershipCommon vulnerabilities:
-- BAD: Anyone can read all users
create policy "public read" on users for select using (true);
-- GOOD: Users can only read own profile
create policy "own profile" on users for select
using (auth.uid() = id);
-- BAD: No RLS means API exposes everything
-- (table has no policies at all)
anon key: only used client-side, limited by RLSservice_role key: NEVER exposed to clientSECURITY DEFINER (runs as owner, not caller)## Supabase Security Audit
**Project:** my-app | **Tables:** 12 | **RLS Enabled:** 8/12
### 🔴 Critical (3)
1. **4 tables without RLS** — orders, payments, audit_log, api_keys
These are fully accessible via the anon API key!
→ Enable RLS: `alter table orders enable row level security;`
2. **service_role key in frontend** — src/lib/supabase.ts:3
`createClient(url, 'eyJhbGciOiJIUz...')` — this key bypasses ALL RLS
→ Use NEXT_PUBLIC_SUPABASE_ANON_KEY only in client code
3. **Public storage bucket** — 'avatars' bucket is public
Anyone can list and download all uploaded files
→ Set bucket to private, use signed URLs for access
### 🟡 Warnings (4)
4. profiles table: SELECT policy uses `using (true)` — all profiles public
5. No email confirmation required — anyone can create accounts
6. JWT expiry: 3600s default — consider shorter for sensitive apps
7. No file type restriction on uploads — allows executables
### ✅ Secure
- Auth using PKCE flow (no implicit grant)
- Password minimum length enforced
- Edge functions use env vars for secrets
- Database functions use SECURITY INVOKER
### 📋 RLS Policy Coverage
| Table | SELECT | INSERT | UPDATE | DELETE | Status |
|-------|--------|--------|--------|--------|--------|
| users | ✅ | ✅ | ✅ | ❌ | 🟡 |
| posts | ✅ | ✅ | ✅ | ✅ | ✅ |
| orders | ❌ | ❌ | ❌ | ❌ | 🔴 NO RLS |
| payments | ❌ | ❌ | ❌ | ❌ | 🔴 NO RLS |