npm version Node License: MIT Website
π Visit the website for full documentation and examples.
Catch Supabase RLS security vulnerabilities before they reach production.
- Security vulnerability detection
- Smart schema discovery
- RLS policy testing (tables + storage buckets)
- Real user context testing
- CI/CD ready
- Zero configuration
npm install -g supashield
Set your Supabase database URL:
export SUPASHIELD_DATABASE_URL="postgresql://postgres.[project-ref]:[password]@aws-0-[region].pooler.supabase.com:5432/postgres"
Get this from: Supabase Dashboard β Settings β Database β Connection string β URI
Note: DATABASE_URL is also supported for backwards compatibility.
supashield init # discover tables and storage buckets supashield test # test all table RLS policies supashield test-storage # test storage bucket RLS policies supashield test --table public.users # test specific table supashield test --as-user admin@company.com # test with real user supashield users # list users from auth.users for testing supashield export-pgtap -o tests.sql # export tests to pgTap format
Testing public.users:
anonymous_user:
SELECT: ALLOW (expected DENY) - MISMATCH!
INSERT: DENY (expected DENY) - PASS
authenticated_user:
SELECT: ALLOW (expected ALLOW) - PASS
INSERT: DENY (expected ALLOW) - MISMATCH!
Results: 2 passed, 2 failed
2 policy mismatches detected!
tables: public.users: test_scenarios: - name: anonymous_user jwt_claims: {} expected: { SELECT: DENY, INSERT: DENY, UPDATE: DENY, DELETE: DENY } - name: authenticated_user jwt_claims: { sub: "user-123", role: "authenticated" } expected: { SELECT: ALLOW, INSERT: ALLOW, UPDATE: ALLOW, DELETE: ALLOW } storage_buckets: avatars: test_scenarios: - name: anonymous_user jwt_claims: {} expected: { SELECT: DENY, INSERT: DENY, UPDATE: DENY, DELETE: DENY } - name: authenticated_user jwt_claims: { sub: "user-123", role: "authenticated" } expected: { SELECT: ALLOW, INSERT: ALLOW, UPDATE: ALLOW, DELETE: ALLOW }
RLS Testing is Hard
- Manual testing doesn't scale
- Complex permission logic is error-prone
- Security bugs are expensive to fix in production
SupaShield Makes it Easy
- Automatically discovers your schema
- Tests all CRUD operations for each role
- Validates real user permissions
- Integrates with your CI/CD pipeline
- run: supashield test env: SUPASHIELD_DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}
- All operations use transactions and rollbacks
- No data is ever persisted during testing
- Works safely with production databases
Got an idea? Open an issue or ping me on X/Twitter.
This tool tests RLS policies using safe, rolled-back transactions. Always test on staging/local environments first. Use at your own risk. Not liable for data loss.
MIT