swiftops-backend / docs /dev /intergrations /SUPABASE_STORAGE_SETUP.md
kamau1's picture
chore: migrate to useast organize the docs, delete redundant migrations
c4f7e3e

Supabase Storage Setup Guide

Issue: RLS Policy Error

If you see this error:

'new row violates row-level security policy'

This means your Supabase Storage buckets have Row Level Security (RLS) enabled but no policies configured.

Quick Fix (Development Only)

Option 1: Disable RLS via Dashboard

For each bucket:

  1. Go to: https://supabase.com/dashboard โ†’ Your Project โ†’ Storage
  2. Click on each bucket (documents-users, documents-tickets, etc.)
  3. Click "Policies" tab
  4. Click "Disable RLS" (if you see this option)

OR

  1. Click on bucket name
  2. Go to "Configuration" tab
  3. Toggle "Enable RLS" to OFF

Proper Solution (Production)

Option 2: Add RLS Policies

The migration file supabase/migrations/08_storage_policies.sql contains all the policies.

Apply via Supabase Dashboard:

  1. Go to: https://supabase.com/dashboard โ†’ Your Project โ†’ SQL Editor
  2. Copy the contents of supabase/migrations/08_storage_policies.sql
  3. Paste and run the SQL

Or apply via CLI:

supabase db push

What the Policies Do:

The policies allow authenticated users to:

  • โœ… Upload files (INSERT)
  • โœ… Read files (SELECT)
  • โœ… Update files (UPDATE)
  • โœ… Delete files (DELETE)

For all buckets:

  • documents-users
  • documents-tickets
  • documents-projects
  • documents-clients
  • documents-contractors
  • documents-general

Alternative: Use Service Role Key

Your backend already uses SUPABASE_SERVICE_KEY which bypasses RLS.

The issue is that the Supabase Python client might not be using it correctly. Let me check...

Actually, looking at the code in src/app/integrations/supabase.py, it IS using the service key:

def get_client() -> Client:
    return create_client(settings.SUPABASE_URL, settings.SUPABASE_SERVICE_KEY)

Why It's Still Failing

The service role key should bypass RLS, but there might be an issue with how the Supabase Python client handles it.

Temporary Workaround:

Disable RLS on all storage buckets (quickest solution for now):

  1. Go to Supabase Dashboard โ†’ Storage
  2. For each bucket, click the three dots (โ‹ฎ) โ†’ "Edit bucket"
  3. Uncheck "Enable RLS" or set it to "Public"
  4. Save

This will allow uploads to work immediately while we investigate the proper RLS setup.

Verification

After disabling RLS or adding policies, test with:

node tests/integration/test_document_upload.js

Choose option 1 (Supabase) and it should work!

Security Note

For production:

  • โœ… Keep RLS enabled
  • โœ… Add proper policies based on user roles
  • โœ… Restrict access based on entity ownership
  • โŒ Don't leave buckets completely public

Example production policy:

-- Users can only access their own documents
CREATE POLICY "Users can access own documents"
ON storage.objects FOR ALL
TO authenticated
USING (
  bucket_id = 'documents-users' 
  AND (storage.foldername(name))[1] = 'user'
  AND (storage.foldername(name))[2] = auth.uid()::text
);

This would restrict users to only access files in their own folder: user/{their_user_id}/