Supabase Security Checklist
Last updated: January 12, 2026
Use this checklist to ensure your Supabase application is secure before launch. 6 critical items require immediate attention.
Why This Security Checklist Matters
Security checklists serve as systematic guides for identifying vulnerabilities that might otherwise be overlooked during rapid development cycles. For Supabase applications specifically, this checklist addresses the most common security gaps that emerge when using AI-assisted development workflows.
Research from multiple security organizations indicates that approximately 80% of AI-built applications contain at least one exploitable vulnerability at launch. The vulnerabilities are often predictable—they follow patterns that this checklist is designed to catch. By systematically reviewing each item, you significantly reduce the risk of launching an insecure application.
Unlike generic security checklists, this guide focuses specifically on vulnerabilities prevalent in Supabase applications. Each item has been prioritized based on real-world attack patterns and the potential impact of exploitation. Critical items should be addressed before any production deployment.
Critical Priority
Critical items can lead to complete application compromise, data breaches, or unauthorized access to all user accounts. These must be addressed before deploying to production. Attackers actively scan for these vulnerabilities.
High Priority
High priority items represent significant security risks that could allow unauthorized access to sensitive data or functionality. While not immediately catastrophic, these vulnerabilities should be fixed as soon as possible.
Medium/Low Priority
Medium and low priority items strengthen your overall security posture. While they may not be immediately exploitable, addressing them prevents attack chains and defense-in-depth gaps.
Manual vs Automated Security Checking
While manual security reviews are thorough, they're time-consuming and prone to human error. Automated scanning catches common vulnerabilities instantly, freeing you to focus on business logic and complex security decisions.
Items VAS Automates
- Exposed API keys and secrets in JavaScript bundles
- HTTP security header configuration
- Supabase RLS policy testing
- Firebase Security Rules validation
- Cookie security attributes
Manual Review Still Required
- Business logic vulnerabilities
- Custom authentication implementations
- Access control logic in API routes
- Data validation requirements
- Third-party integration security
Row Level Security
Enable RLS on all tables
AutoALTER TABLE x ENABLE ROW LEVEL SECURITY;
Write SELECT policies
AutoControl who can read data
Write INSERT policies
AutoControl who can create data
Write UPDATE policies
AutoControl who can modify data
Write DELETE policies
AutoControl who can remove data
Use (select auth.uid()) pattern
Performance optimization for RLS
Key Security
Anon key in frontend only
This key is public by design
Service role key server-only
AutoNever expose in client code
Rotate keys if exposed
Generate new keys in dashboard
Functions & RPCs
Auth check in functions
Verify auth.uid() in RPC functions
SECURITY DEFINER caution
Understand implications of elevated privileges
Input validation
Validate parameters in functions
Authentication
Enable email confirmation
AutoRequire email verification
Configure password policy
AutoSet minimum requirements
Set up rate limiting
Protect against brute force
Don't Check Manually
VAS automatically checks 8 of these 15 items. Get instant results with detailed remediation guidance.
Run Automated Security ScanFrequently Asked Questions
Why are there 5 critical items just for RLS?
Each CRUD operation (SELECT, INSERT, UPDATE, DELETE) needs its own policy. A table with RLS enabled but no policies blocks ALL access. A table with only SELECT policy allows reads but blocks writes. You need policies for every operation your app performs.
What's the (select auth.uid()) pattern mentioned in the checklist?
Using (select auth.uid()) instead of auth.uid() in RLS policies improves performance. The subquery evaluates once per query rather than once per row. On large tables, this can significantly speed up queries. Supabase linter warns about this.