6.8 KiB
name, description
| name | description |
|---|---|
| supabase-rls-policy-generator | This skill should be used when the user requests to generate, create, or add Row-Level Security (RLS) policies for Supabase databases in multi-tenant or role-based applications. It generates comprehensive RLS policies using auth.uid(), auth.jwt() claims, and role-based access patterns. Trigger terms include RLS, row level security, supabase security, generate policies, auth policies, multi-tenant security, role-based access, database security policies, supabase permissions, tenant isolation. |
Supabase RLS Policy Generator
To generate comprehensive Row-Level Security policies for Supabase databases, follow these steps systematically.
Step 1: Analyze Current Schema
Before generating policies:
- Ask user for the database schema file path or table names
- Read the schema to understand table structures, foreign keys, and relationships
- Identify tables that need RLS protection
- Determine the security model: multi-tenant, role-based, or hybrid
Step 2: Identify Security Requirements
Determine access patterns by asking:
- Is this a multi-tenant application? (tenant_id isolation)
- What roles exist in the system? (admin, user, viewer, etc.)
- Are there public vs private resources?
- Do users need to share resources across accounts?
- Are there hierarchical permissions? (organization > team > user)
Consult references/rls-patterns.md for common security patterns.
Step 3: Generate RLS Policies
For each table requiring protection, generate policies following this structure:
Enable RLS
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
Policy Types to Generate
SELECT Policies - Control read access:
- User can view their own records
- User can view records in their tenant
- Role-based viewing (admins see all)
- Public records accessible to all authenticated users
INSERT Policies - Control creation:
- User can create records with their own user_id
- User can create records in their tenant
- Role-based creation restrictions
UPDATE Policies - Control modifications:
- User can update their own records
- Admins can update all records
- Tenant-scoped updates
DELETE Policies - Control deletion:
- User can delete their own records
- Admin-only deletion
- Tenant-scoped deletion
Policy Templates
Use templates from assets/policy-templates.sql:
Basic User Ownership:
CREATE POLICY "Users can view own records"
ON table_name FOR SELECT
USING (auth.uid() = user_id);
Multi-Tenant Isolation:
CREATE POLICY "Tenant isolation"
ON table_name FOR ALL
USING (
tenant_id IN (
SELECT tenant_id FROM user_tenants
WHERE user_id = auth.uid()
)
);
Role-Based Access:
CREATE POLICY "Admins have full access"
ON table_name FOR ALL
USING (
auth.jwt() ->> 'role' = 'admin'
);
JWT Claims:
CREATE POLICY "Organization access"
ON table_name FOR SELECT
USING (
organization_id = (auth.jwt() -> 'app_metadata' ->> 'organization_id')::uuid
);
Step 4: Generate Helper Functions
Create PostgreSQL functions to support complex policies:
-- Function to check user role
CREATE OR REPLACE FUNCTION auth.user_has_role(required_role TEXT)
RETURNS BOOLEAN AS $$
BEGIN
RETURN (auth.jwt() ->> 'role') = required_role;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Function to check tenant membership
CREATE OR REPLACE FUNCTION auth.user_in_tenant(target_tenant_id UUID)
RETURNS BOOLEAN AS $$
BEGIN
RETURN EXISTS (
SELECT 1 FROM user_tenants
WHERE user_id = auth.uid()
AND tenant_id = target_tenant_id
);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
Step 5: Generate Testing Queries
Create test queries to verify policies work correctly:
-- Test as authenticated user
SET request.jwt.claim.sub = 'user-uuid';
SELECT * FROM table_name; -- Should see only accessible records
-- Test as admin
SET request.jwt.claim.role = 'admin';
SELECT * FROM table_name; -- Should see all records
-- Test as different tenant
SET request.jwt.claim.sub = 'other-user-uuid';
SELECT * FROM table_name; -- Should see different tenant's records
Step 6: Create Migration File
Generate a migration file with proper structure:
-- Migration: Add RLS policies
-- Created: [timestamp]
-- Enable RLS on tables
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE items ENABLE ROW LEVEL SECURITY;
-- Drop existing policies if any
DROP POLICY IF EXISTS "policy_name" ON table_name;
-- Create new policies
[Generated policies here]
-- Create helper functions
[Generated functions here]
-- Grant necessary permissions
GRANT SELECT, INSERT, UPDATE, DELETE ON table_name TO authenticated;
GRANT SELECT ON table_name TO anon; -- If public read needed
Step 7: Document Generated Policies
Create documentation explaining:
- What each policy does
- Which users/roles have what access
- Any special cases or exceptions
- How to test the policies
- Common troubleshooting tips
Use template from assets/policy-documentation-template.md.
Implementation Guidelines
Security Best Practices
- Always enable RLS on tables with user data
- Use auth.uid() for user-owned records
- Use JWT claims for role-based access
- Prefer SECURITY DEFINER functions for complex logic
- Test policies with different user roles
- Use USING clause for read access, WITH CHECK for write validation
Performance Considerations
- Add indexes on columns used in policies (user_id, tenant_id, role)
- Keep policy logic simple for better performance
- Use helper functions for reusable complex logic
- Avoid subqueries in policies when possible
Common Patterns
Consult references/rls-patterns.md for detailed examples of:
- Multi-tenant isolation
- Role-based access control (RBAC)
- Attribute-based access control (ABAC)
- Hierarchical permissions
- Public/private resource splitting
- Shared resource access
Output Format
Generate files in the following structure:
migrations/
[timestamp]_add_rls_policies.sql
docs/
rls-policies.md (documentation)
tests/
rls_tests.sql (test queries)
Verification Checklist
Before completing:
- RLS enabled on all sensitive tables
- Policies cover all operations (SELECT, INSERT, UPDATE, DELETE)
- Policies tested with different user roles
- Indexes added for policy columns
- Helper functions created for complex logic
- Documentation generated
- Test queries provided
- No policies accidentally grant excessive access
Consulting References
Throughout generation:
- Consult
references/rls-patterns.mdfor security patterns - Consult
references/supabase-auth.mdfor auth.uid() and JWT structure - Use templates from
assets/policy-templates.sql
Completion
When finished:
- Display the generated migration file
- Summarize the policies created
- Provide testing instructions
- Offer to generate additional policies or modify existing ones