111 lines
3.7 KiB
PL/PgSQL
111 lines
3.7 KiB
PL/PgSQL
-- ==========================================
|
|
-- 06: GRANT BYPASSRLS TO BACKEND USER
|
|
-- ==========================================
|
|
-- This script grants Row-Level Security bypass privilege
|
|
-- Required for registration flow (tenant + user creation in same transaction)
|
|
-- Runs as: postgres (superuser)
|
|
|
|
\echo '🔓 Granting BYPASSRLS privilege...'
|
|
|
|
-- ==========================================
|
|
-- WHY BYPASSRLS IS NECESSARY
|
|
-- ==========================================
|
|
-- During registration, we create tenant and user in a single transaction:
|
|
--
|
|
-- BEGIN;
|
|
-- INSERT INTO tenants (...) VALUES (...); -- Creates tenant
|
|
-- INSERT INTO users (tenant_id, ...) VALUES (...); -- References tenant
|
|
-- COMMIT;
|
|
--
|
|
-- PROBLEM WITHOUT BYPASSRLS:
|
|
-- - PostgreSQL validates foreign key (users.tenant_id → tenants.id)
|
|
-- - Foreign key check runs: SELECT 1 FROM tenants WHERE id = ?
|
|
-- - RLS policy blocks this SELECT (no tenant context during registration)
|
|
-- - Foreign key check fails: "violates foreign key constraint"
|
|
-- - Transaction rolls back
|
|
--
|
|
-- SOLUTION WITH BYPASSRLS:
|
|
-- - Backend user can see ALL rows during registration
|
|
-- - Foreign key check succeeds (tenant visible immediately)
|
|
-- - Transaction commits successfully
|
|
-- - Regular operations still protected by RLS (when app.current_tenant_id is set)
|
|
-- ==========================================
|
|
|
|
-- Grant BYPASSRLS to backend API user
|
|
ALTER USER aurganize_backend_api WITH BYPASSRLS;
|
|
|
|
\echo ' ✅ BYPASSRLS privilege granted to aurganize_backend_api'
|
|
|
|
-- ==========================================
|
|
-- VERIFY PRIVILEGE GRANTED
|
|
-- ==========================================
|
|
DO $$
|
|
DECLARE
|
|
has_bypassrls BOOLEAN;
|
|
user_privileges TEXT;
|
|
BEGIN
|
|
-- Check if BYPASSRLS was granted
|
|
SELECT rolbypassrls INTO has_bypassrls
|
|
FROM pg_roles
|
|
WHERE rolname = 'aurganize_backend_api';
|
|
|
|
IF has_bypassrls THEN
|
|
RAISE NOTICE ' ✅ Verification: BYPASSRLS is active';
|
|
ELSE
|
|
RAISE WARNING ' ❌ Verification: BYPASSRLS not active!';
|
|
RAISE EXCEPTION 'Failed to grant BYPASSRLS privilege';
|
|
END IF;
|
|
|
|
-- Build privilege summary
|
|
SELECT CASE
|
|
WHEN rolsuper THEN '🔴 SUPERUSER'
|
|
WHEN rolbypassrls THEN '🟡 RLS BYPASS'
|
|
ELSE '🟢 STANDARD'
|
|
END INTO user_privileges
|
|
FROM pg_roles
|
|
WHERE rolname = 'aurganize_backend_api';
|
|
|
|
RAISE NOTICE ' 🔐 Privilege Level: %', user_privileges;
|
|
END $$;
|
|
|
|
-- ==========================================
|
|
-- DISPLAY FINAL USER CONFIGURATION
|
|
-- ==========================================
|
|
\echo ''
|
|
\echo '📋 Final user configuration:'
|
|
|
|
SELECT
|
|
rolname AS "Username",
|
|
rolcanlogin AS "Can Login",
|
|
rolsuper AS "Superuser",
|
|
rolbypassrls AS "Bypass RLS",
|
|
rolconnlimit AS "Conn Limit",
|
|
CASE
|
|
WHEN rolsuper THEN '🔴 Full Access'
|
|
WHEN rolbypassrls THEN '🟡 RLS Bypass (for registration)'
|
|
ELSE '🟢 Standard (RLS enforced)'
|
|
END AS "Access Level"
|
|
FROM pg_roles
|
|
WHERE rolname = 'aurganize_backend_api';
|
|
|
|
-- ==========================================
|
|
-- SECURITY NOTES
|
|
-- ==========================================
|
|
\echo ''
|
|
\echo '=========================================='
|
|
\echo '🔒 SECURITY NOTES'
|
|
\echo '=========================================='
|
|
\echo ''
|
|
\echo '✅ SAFE USAGE:'
|
|
\echo ' - Backend sets app.current_tenant_id for regular operations'
|
|
\echo ' - RLS still protects all normal CRUD operations'
|
|
\echo ' - Only registration flow runs without tenant context'
|
|
\echo ' - Audit logs capture all operations'
|
|
\echo ''
|
|
\echo '⚠️ IMPORTANT:'
|
|
\echo ' - BYPASSRLS only needed for registration endpoint'
|
|
\echo ' - All other operations MUST set tenant context'
|
|
\echo ' - Readonly user does NOT have BYPASSRLS'
|
|
\echo ''
|
|
\echo '✅ BYPASSRLS configuration complete!'
|
|
\echo '' |