Files
awoooi/scripts/ops/awooop-rls-role-bootstrap.sql
Your Name f0255e0300
All checks were successful
Code Review / ai-code-review (push) Successful in 10s
chore(ops): 補強 RLS role bootstrap gate
2026-05-12 18:36:35 +08:00

87 lines
2.9 KiB
PL/PgSQL

-- AwoooP RLS role bootstrap.
--
-- IMPORTANT:
-- - Do not put this file under apps/api/migrations; Gitea auto-migration should
-- not attempt CREATE ROLE / BYPASSRLS with the limited migrator account.
-- - Run manually as postgres or a CREATEROLE-capable operator after review.
-- - This script does not create passwords and does not change application
-- DATABASE_URL. It creates NOLOGIN group roles and grants awooop_app to the
-- current production app connection role (`awoooi`).
--
-- Suggested command on 188:
-- sudo -u postgres psql -d awoooi_prod -v ON_ERROR_STOP=1 \
-- -f /path/to/awooop-rls-role-bootstrap.sql
--
-- Post-check:
-- bash scripts/ops/awooop-rls-preflight.sh --exact-counts
BEGIN;
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'awooop_app') THEN
EXECUTE 'CREATE ROLE awooop_app NOLOGIN';
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'awooop_platform_admin') THEN
EXECUTE 'CREATE ROLE awooop_platform_admin NOLOGIN';
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'awooop_migration') THEN
EXECUTE 'CREATE ROLE awooop_migration NOLOGIN';
END IF;
END $$;
ALTER ROLE awooop_platform_admin BYPASSRLS;
ALTER ROLE awooop_migration BYPASSRLS;
-- Current production API connects as `awoooi`. Until DATABASE_URL is split to a
-- dedicated LOGIN role, make that role a member of the RLS-constrained group so
-- policies written as `FOR ALL TO awooop_app` apply without secret rotation.
GRANT awooop_app TO awoooi;
-- Keep existing migration account usable without changing its password or
-- DATABASE_URL. The group role is NOLOGIN; operators may SET ROLE during manual
-- RLS migrations if needed.
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'awoooi_migrator') THEN
EXECUTE 'GRANT awooop_migration TO awoooi_migrator';
END IF;
END $$;
-- Minimum grants for existing target tables that already have project_id. RLS
-- policies remain a separate staged migration and are not enabled here.
GRANT USAGE ON SCHEMA public TO awooop_app;
DO $$
DECLARE
table_name text;
target_tables text[] := ARRAY[
'incidents',
'knowledge_entries',
'playbooks',
'audit_logs',
'budget_ledger',
'awooop_projects',
'awooop_contract_revisions',
'awooop_run_state',
'awooop_mcp_tool_registry',
'awooop_mcp_grants',
'awooop_mcp_credential_refs',
'awooop_mcp_gateway_audit',
'awooop_conversation_event',
'awooop_outbound_message'
];
BEGIN
FOREACH table_name IN ARRAY target_tables LOOP
IF to_regclass('public.' || table_name) IS NOT NULL THEN
EXECUTE format('GRANT SELECT, INSERT, UPDATE, DELETE ON public.%I TO awooop_app', table_name);
END IF;
END LOOP;
END $$;
GRANT USAGE, SELECT, UPDATE ON ALL SEQUENCES IN SCHEMA public TO awooop_app;
COMMIT;