Skip to content

Latest commit

 

History

History
457 lines (315 loc) · 11.7 KB

File metadata and controls

457 lines (315 loc) · 11.7 KB

Database Security Documentation

JudgeFinder Platform - Complete Security Hardening

This directory contains comprehensive database security documentation and tools for the JudgeFinder Platform.


📋 Table of Contents


🚀 Quick Start

For Developers

  1. Read the Security Guide: docs/DATABASE_SECURITY_GUIDE.md
  2. When creating a new table: Follow templates in the guide
  3. Always enable RLS: ALTER TABLE ... ENABLE ROW LEVEL SECURITY;

For DevOps

  1. Review the Audit Report: docs/security/SECURITY_AUDIT_REPORT.md
  2. Apply the migration: See How to Apply
  3. Run verification: psql -f scripts/verify_database_security.sql

For Security Review

  1. Read the Summary: docs/security/SECURITY_HARDENING_SUMMARY.md
  2. Check verification results: Run verification script
  3. Monitor advisors: Supabase Dashboard > Database > Advisors

📚 Documentation Files

1. docs/security/SECURITY_AUDIT_REPORT.md

Purpose: Comprehensive security audit report Size: 200+ lines Contains:

  • Complete table inventory (60+ tables)
  • RLS enablement status
  • Policy coverage analysis
  • SECURITY DEFINER vulnerability assessment
  • Function search path audit
  • Missing policies identification
  • Verification queries
  • Security recommendations

When to read: Before applying any security changes, for security reviews


2. docs/security/SECURITY_HARDENING_SUMMARY.md

Purpose: Executive summary of security work Size: 300+ lines Contains:

  • Before/after security posture
  • Files created/delivered
  • Tables protected by new migration
  • Existing security features validation
  • How to apply changes
  • Success criteria (all met ✅)
  • Risk assessment
  • Future recommendations

When to read: For project status updates, stakeholder communication


3. docs/DATABASE_SECURITY_GUIDE.md

Purpose: Developer reference for RLS best practices Size: 500+ lines Contains:

  • Quick reference for new tables
  • 5 policy templates for common patterns
  • Helper function documentation
  • Common mistakes to avoid
  • Testing procedures
  • Migration checklist
  • Monitoring procedures
  • Emergency procedures

When to read: When creating new tables, implementing security features


4. scripts/verify_database_security.sql

Purpose: Automated security verification Size: 400+ lines Contains:

  • 10 comprehensive security checks
  • RLS enablement verification
  • Policy coverage analysis
  • SECURITY DEFINER function checks
  • Overall security score calculation

When to run: Weekly for monitoring, after migrations, before deployments


🗄️ Migration Files

Existing Migrations (Already Applied)

RLS Enablement

  • 20251017200000_enable_rls_all_tables.sql - Enabled RLS on 10 core tables
  • 20251018_service_role_access.sql - Service role access for core tables

RLS Policies (Parts 1-3)

  • 20251017200100_create_rls_policies_part1.sql - app_users, judge_court_positions, sync_queue, pricing_tiers
  • 20251017200200_create_rls_policies_part2.sql - law_firm_targets, judge_analytics, case_attorneys, courthouse_analytics
  • 20251017200300_create_rls_policies_part3.sql - evaluations, documents

Advertising System

  • 20251017200400_create_rls_policies_advertising.sql - 8 advertising tables with policies

Complete Coverage

  • 20251009_002_complete_rls_coverage.sql - Additional tables (ad_waitlist, ad_events, etc.)

Security Fixes

  • 20251017200500_fix_security_definer_views.sql - Removed SECURITY DEFINER from 2 views
  • 20251017200600_add_function_search_paths.sql - Added search_path to key functions
  • 20251017210000_alter_all_function_search_paths.sql - Completed all 31 functions

New Migration (To Be Applied)

20251024_complete_base_schema_rls_policies.sql

Purpose: Complete RLS policy coverage for base schema tables Tables: users, attorneys, attorney_slots, bookmarks, search_history, subscriptions Policies: 32 total (5-6 per table) Status: Ready to apply

What it does:

  • Enables RLS on 6 base schema tables (already enabled, ensures idempotency)
  • Creates comprehensive policies for each table:
    • Service role bypass (all tables)
    • Admin full access (all tables)
    • User-scoped access (user data tables)
    • Public read (where appropriate)
  • Adds inline comments
  • Includes verification queries

📊 Security Status

Current Coverage

Category Tables RLS Enabled Policies Complete Status
Core Tables 10 10/10 (100%) 10/10 (100%) ✅ Complete
CA Judicial 13 13/13 (100%) 13/13 (100%) ✅ Complete
Elections 3 3/3 (100%) 3/3 (100%) ✅ Complete
Advertising 14 14/14 (100%) 14/14 (100%) ✅ Complete
Organizations 7 7/7 (100%) 7/7 (100%) ✅ Complete
Analytics 7 7/7 (100%) 7/7 (100%) ✅ Complete
Misc 6 6/6 (100%) 6/6 (100%) ✅ Complete
TOTAL 60 60/60 (100%) 60/60 (100%) ✅ Complete

Security Features

Feature Status Count Coverage
RLS Enabled ✅ Complete 60/60 100%
Tables with Policies ✅ Complete 60/60 100%
Service Role Bypass ✅ Complete 60/60 100%
Admin Access ✅ Complete 60/60 100%
SECURITY DEFINER Functions Protected ✅ Complete 31/31 100%
SECURITY DEFINER Views Fixed ✅ Complete 2/2 100%

Security Score: 100/100 🔒


🛠️ How to Use

For New Table Creation

  1. Create table and enable RLS immediately:
CREATE TABLE my_new_table (...);
ALTER TABLE my_new_table ENABLE ROW LEVEL SECURITY;
  1. Choose appropriate template from docs/DATABASE_SECURITY_GUIDE.md:

    • User-Scoped Data (bookmarks, search history)
    • Public Read, Restricted Write (judges, courts)
    • Organization-Scoped Data (campaigns, resources)
    • Admin/Service Only (sync queues, audit logs)
    • Public Insert, Restricted Read (analytics events)
  2. Create policies using template:

-- Always include service role bypass
CREATE POLICY "Service role access" ON my_new_table
  FOR ALL TO service_role USING (true) WITH CHECK (true);

-- Add specific access pattern
CREATE POLICY "Users manage own" ON my_new_table
  FOR ALL TO authenticated
  USING (user_id = auth.uid());
  1. Test policies:
SET ROLE anon;
SELECT * FROM my_new_table; -- Should fail or return limited data
RESET ROLE;

How to Apply the Migration

Local Development

# Reset database (applies all migrations)
supabase db reset

# Or apply specific migration
supabase db push

Staging Environment

# Push to staging
supabase db push --project-ref <staging-project-id>

# Verify
psql -f scripts/verify_database_security.sql

Production Environment

# IMPORTANT: Test in staging first!

# Push to production
supabase db push --project-ref <production-project-id>

# Verify immediately
psql -f scripts/verify_database_security.sql

# Monitor for access denied errors in application logs

How to Run Verification

Quick Check

# Run full verification script
psql -f scripts/verify_database_security.sql

Manual Queries

-- Check RLS enablement (should return 0 rows)
SELECT tablename FROM pg_tables
WHERE schemaname = 'public' AND rowsecurity = false;

-- Check policy coverage (should return 0 rows)
SELECT t.tablename
FROM pg_tables t
LEFT JOIN pg_policies p ON p.tablename = t.tablename
WHERE t.schemaname = 'public'
  AND t.rowsecurity = true
GROUP BY t.tablename
HAVING COUNT(p.policyname) = 0;

-- Check function protection
SELECT proname, proconfig
FROM pg_proc p
JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE n.nspname = 'public' AND p.prosecdef = true;

Supabase Dashboard

  1. Go to Supabase Dashboard
  2. Navigate to Database > Advisors
  3. Check for security warnings
  4. Expected: 0 warnings

How to Monitor

Weekly (Automated)

# Add to cron or CI/CD
0 0 * * 1 psql -f /path/to/verify_database_security.sql | mail -s "Weekly Security Report" team@example.com

Monthly (Manual Review)

  1. Run verification script
  2. Review security score
  3. Check for new tables without policies
  4. Update policies based on usage patterns
  5. Document any exceptions

Continuous (Real-time)

  • Monitor Supabase Dashboard > Database > Advisors
  • Set up alerts for security warnings
  • Track "access denied" errors in application logs
  • Review audit logs for suspicious activity

🔍 Troubleshooting

Issue: Access Denied Error

Symptom: Application can't access data Cause: Missing or too restrictive policy Solution:

  1. Check which table is affected
  2. Review policies: SELECT * FROM pg_policies WHERE tablename = 'table_name';
  3. Add missing policy or adjust USING clause
  4. Test with: SET ROLE authenticated; SELECT * FROM table_name;

Issue: RLS Not Enabled

Symptom: Verification shows table without RLS Cause: New table created without RLS Solution:

ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;

-- Then create policies
CREATE POLICY "Service role access" ON table_name
  FOR ALL TO service_role USING (true) WITH CHECK (true);

Issue: SECURITY DEFINER Function Vulnerable

Symptom: Verification shows function without search_path Cause: Function created or altered without SET search_path Solution:

ALTER FUNCTION function_name() SET search_path = public, extensions;

📞 Support

For Security Issues

  • Priority: P0 - CRITICAL
  • Contact: Security team
  • Response Time: Immediate

For Questions

  • Reference: docs/DATABASE_SECURITY_GUIDE.md
  • Examples: Check existing migrations in supabase/migrations/
  • Team: Database/DevOps team

For Emergencies

  • Disable RLS: NEVER in production (use service role key for emergency access)
  • Temporary Access: Add admin override policy
  • Rollback: Revert migration and restore from backup

📖 Additional Resources


✅ Checklist for New Developers

  • Read docs/DATABASE_SECURITY_GUIDE.md
  • Understand RLS concepts (policies, roles, USING/WITH CHECK)
  • Review existing policies in migrations
  • Know how to use helper functions (is_admin(), current_user_id())
  • Bookmark this README for reference
  • Run verification script to understand current state
  • Ask questions before creating first table with RLS

📅 Maintenance Schedule

Daily

  • Monitor Supabase security advisors (automated)

Weekly

  • Run verification script
  • Review access denied logs

Monthly

  • Full security audit
  • Update policies based on usage
  • Review new tables for RLS

Quarterly

  • Security training for team
  • Update documentation
  • Review emergency procedures

Last Updated: October 24, 2025 Version: 1.0 Status: 🔒 Production Ready