Row Level Security (RLS) Policies
Row Level Security (RLS) is a critical security feature in our Supabase database that ensures data isolation between clinics and proper access control based on user roles.Overview
RLS policies control which rows in a database table each user can access. When properly configured, they provide:- Multi-tenant isolation: Each clinic can only access their own data
- Role-based access: Different user roles have appropriate permissions
- Data privacy: Patient information is protected from unauthorized access
Key Security Principles
1. Never Use USING (true)
Policies with USING (true) bypass all security checks and should never be used in production unless absolutely necessary for system operations.
2. Always Enforce Clinic Isolation
Every policy should verify that the user belongs to the same clinic as the data they’re accessing:3. Validate User Roles
In addition to clinic isolation, verify that users have the appropriate role for the action:Common RLS Patterns
Read Access Pattern
For tables that need to be read by all clinic members:Write Access Pattern
For tables that should only be modified by specific roles:Service Role Pattern
System operations often need unrestricted access:Critical Tables and Their Policies
audit_logs
Audit logs should only be accessible to administrators:medications
Medications need clinic isolation for multi-tenant security:patients
Patient data is highly sensitive and requires strict access control:Testing RLS Policies
Always test RLS policies before deploying to production:- Test as different user roles to ensure appropriate access
- Verify clinic isolation by attempting cross-clinic access
- Check edge cases like new users or role changes
- Monitor query performance as complex policies can impact speed
Testing Example
Common Security Issues
1. Overly Permissive Policies
Issue: Policies that useUSING (true) or don’t check clinic membership
Solution: Always include clinic isolation checks
2. Missing Policies
Issue: Tables with RLS enabled but no policies defined Solution: Define appropriate policies or disable RLS if not needed3. Weak Validation
Issue: Policies that only check authentication without role validation Solution: Add role checks for operations that require specific permissions4. Policy Conflicts
Issue: Multiple policies that contradict each other Solution: Review all policies on a table to ensure consistencyDeployment Best Practices
- Review all policies in the migration file before deployment
- Test in development environment first
- Deploy during low-traffic periods to minimize impact
- Monitor for access issues after deployment
- Keep audit logs of policy changes
Security Audit Checklist
Regular audits should verify:- No policies use
USING (true)except for service role - All tables with sensitive data have RLS enabled
- All policies enforce clinic isolation
- Role-based access is properly implemented
- No tables have RLS enabled without policies
- Policy performance is acceptable
Recent Security Fixes
The following critical vulnerabilities were recently addressed:- audit_logs: Removed policy allowing all authenticated users full access
- medications: Removed global access policies, added clinic isolation
- pickup_schedules: Added missing policies for clinic-based access
- patient_app_requests: Strengthened INSERT validation
20240110_fix_critical_rls_policies.sql