diff --git a/ansible/files/postgresql_config/supautils.conf.j2 b/ansible/files/postgresql_config/supautils.conf.j2 index 00262b6ac..74465bb35 100644 --- a/ansible/files/postgresql_config/supautils.conf.j2 +++ b/ansible/files/postgresql_config/supautils.conf.j2 @@ -9,7 +9,7 @@ supautils.drop_trigger_grants = '{"postgres":["auth.audit_log_entries","auth.flo supautils.privileged_extensions = 'address_standardizer, address_standardizer_data_us, autoinc, bloom, btree_gin, btree_gist, citext, cube, dblink, dict_int, dict_xsyn, earthdistance, fuzzystrmatch, hstore, http, hypopg, index_advisor, insert_username, intarray, isn, ltree, moddatetime, orioledb, pg_buffercache, pg_cron, pg_graphql, pg_hashids, pg_jsonschema, pg_net, pg_prewarm, pg_repack, pg_stat_monitor, pg_stat_statements, pg_tle, pg_trgm, pg_walinspect, pgaudit, pgcrypto, pgjwt, pgroonga, pgroonga_database, pgrouting, pgrowlocks, pgsodium, pgstattuple, pgtap, plcoffee, pljava, plls, plpgsql_check, plv8, postgis, postgis_raster, postgis_sfcgal, postgis_tiger_geocoder, postgis_topology, postgres_fdw, refint, rum, seg, sslinfo, supabase_vault, supautils, tablefunc, tcn, timescaledb, tsm_system_rows, tsm_system_time, unaccent, uuid-ossp, vector, wrappers' supautils.extension_custom_scripts_path = '/etc/postgresql-custom/extension-custom-scripts' supautils.privileged_extensions_superuser = 'supabase_admin' -supautils.privileged_role = 'postgres' +supautils.privileged_role = 'supabase_superuser' supautils.privileged_role_allowed_configs = 'auto_explain.*, log_lock_waits, log_min_duration_statement, log_min_messages, log_parameter_max_length, log_replication_commands, log_statement, log_temp_files, pg_net.batch_size, pg_net.ttl, pg_stat_statements.*, pgaudit.log, pgaudit.log_catalog, pgaudit.log_client, pgaudit.log_level, pgaudit.log_relation, pgaudit.log_rows, pgaudit.log_statement, pgaudit.log_statement_once, pgaudit.role, pgrst.*, plan_filter.*, safeupdate.enabled, session_replication_role, track_functions, track_io_timing, wal_compression' supautils.reserved_memberships = 'pg_read_server_files, pg_write_server_files, pg_execute_server_program, supabase_admin, supabase_auth_admin, supabase_storage_admin, supabase_read_only_user, supabase_realtime_admin, supabase_replication_admin, supabase_etl_admin, dashboard_user, pgbouncer, authenticator' supautils.reserved_roles = 'supabase_admin, supabase_auth_admin, supabase_storage_admin, supabase_read_only_user, supabase_realtime_admin, supabase_replication_admin, supabase_etl_admin, dashboard_user, pgbouncer, service_role*, authenticator*, authenticated*, anon*' diff --git a/ansible/vars.yml b/ansible/vars.yml index 2e9cd0d92..b917baaad 100644 --- a/ansible/vars.yml +++ b/ansible/vars.yml @@ -10,9 +10,9 @@ postgres_major: # Full version strings for each major version postgres_release: - postgresorioledb-17: "17.6.0.023-orioledb" - postgres17: "17.6.1.066" - postgres15: "15.14.1.066" + postgresorioledb-17: "17.6.0.023-orioledb-sbsu-1" + postgres17: "17.6.1.066-sbsu-1" + postgres15: "15.14.1.066-sbsu-1" # Non Postgres Extensions pgbouncer_release: 1.19.0 diff --git a/migrations/db/migrations/20251215120934_supabase_superuser.sql b/migrations/db/migrations/20251215120934_supabase_superuser.sql new file mode 100644 index 000000000..7707d83a1 --- /dev/null +++ b/migrations/db/migrations/20251215120934_supabase_superuser.sql @@ -0,0 +1,5 @@ +-- migrate:up +create role supabase_superuser; +grant supabase_superuser to postgres, supabase_etl_admin; + +-- migrate:down diff --git a/nix/tests/expected/evtrigs.out b/nix/tests/expected/evtrigs.out index 3e3f523fc..25f43de8e 100644 --- a/nix/tests/expected/evtrigs.out +++ b/nix/tests/expected/evtrigs.out @@ -26,3 +26,34 @@ where p.prorettype = 'event_trigger'::regtype; pgsodium_trg_mask_update | supabase_admin | pgsodium | pgsodium.trg_mask_update | supabase_admin (12 rows) +-- postgres can create event triggers +set role postgres; +create function f() + returns event_trigger + language plpgsql + as $$ begin end $$; +create event trigger et + on ddl_command_start + execute function f(); +drop event trigger et; +drop function f(); +reset role; +-- supabase_etl_admin can create event triggers +set role supabase_etl_admin; +create schema s; +create function s.f() + returns event_trigger + language plpgsql + as $$ begin end $$; +create event trigger et + on ddl_command_start + execute function s.f(); +-- postgres can't drop supabase_etl_admin's event triggers +set role postgres; +drop event trigger et; +ERROR: must be owner of event trigger et +set role supabase_etl_admin; +drop event trigger et; +drop function s.f(); +drop schema s; +reset role; diff --git a/nix/tests/expected/roles.out b/nix/tests/expected/roles.out index 0cd94fc83..c4e25b61b 100644 --- a/nix/tests/expected/roles.out +++ b/nix/tests/expected/roles.out @@ -51,7 +51,8 @@ order by rolname; supabase_read_only_user | f | t | f | t | f | f | -1 | t | supabase_replication_admin | f | t | f | t | f | t | -1 | f | supabase_storage_admin | t | t | f | f | f | f | -1 | f | -(30 rows) + supabase_superuser | f | f | f | t | f | f | -1 | f | +(31 rows) select rolname, @@ -91,7 +92,8 @@ order by rolname; supabase_read_only_user | {default_transaction_read_only=on} supabase_replication_admin | supabase_storage_admin | {search_path=storage,log_statement=none} -(30 rows) + supabase_superuser | +(31 rows) -- Check all privileges of the roles on the schemas select schema_name, privilege_type, grantee, default_for diff --git a/nix/tests/expected/z_15_roles.out b/nix/tests/expected/z_15_roles.out index 1f967bd9a..3bb2556ea 100644 --- a/nix/tests/expected/z_15_roles.out +++ b/nix/tests/expected/z_15_roles.out @@ -29,12 +29,14 @@ order by postgres | pg_signal_backend | f postgres | pgtle_admin | f postgres | service_role | f + postgres | supabase_superuser | f supabase_etl_admin | pg_monitor | f supabase_etl_admin | pg_read_all_data | f + supabase_etl_admin | supabase_superuser | f supabase_read_only_user | pg_monitor | f supabase_read_only_user | pg_read_all_data | f supabase_storage_admin | authenticator | f -(21 rows) +(23 rows) -- Check all privileges of non-superuser roles on functions select diff --git a/nix/tests/expected/z_17_roles.out b/nix/tests/expected/z_17_roles.out index 5f598da16..054feecc0 100644 --- a/nix/tests/expected/z_17_roles.out +++ b/nix/tests/expected/z_17_roles.out @@ -66,12 +66,14 @@ order by postgres | pg_signal_backend | t postgres | pgtle_admin | f postgres | service_role | t + postgres | supabase_superuser | f supabase_etl_admin | pg_monitor | f supabase_etl_admin | pg_read_all_data | f + supabase_etl_admin | supabase_superuser | f supabase_read_only_user | pg_monitor | f supabase_read_only_user | pg_read_all_data | f supabase_storage_admin | authenticator | f -(23 rows) +(25 rows) -- Check version-specific privileges of the roles on the schemas select schema_name, privilege_type, grantee, default_for @@ -160,12 +162,14 @@ order by postgres | pg_signal_backend | t postgres | pgtle_admin | f postgres | service_role | t + postgres | supabase_superuser | f supabase_etl_admin | pg_monitor | f supabase_etl_admin | pg_read_all_data | f + supabase_etl_admin | supabase_superuser | f supabase_read_only_user | pg_monitor | f supabase_read_only_user | pg_read_all_data | f supabase_storage_admin | authenticator | f -(22 rows) +(24 rows) -- Check all privileges of non-superuser roles on functions select diff --git a/nix/tests/sql/evtrigs.sql b/nix/tests/sql/evtrigs.sql index cfbb201aa..15ecc8038 100644 --- a/nix/tests/sql/evtrigs.sql +++ b/nix/tests/sql/evtrigs.sql @@ -10,3 +10,38 @@ join pg_proc p join pg_namespace n_func on p.pronamespace = n_func.oid where p.prorettype = 'event_trigger'::regtype; + +-- postgres can create event triggers +set role postgres; +create function f() + returns event_trigger + language plpgsql + as $$ begin end $$; +create event trigger et + on ddl_command_start + execute function f(); + +drop event trigger et; +drop function f(); +reset role; + +-- supabase_etl_admin can create event triggers +set role supabase_etl_admin; +create schema s; +create function s.f() + returns event_trigger + language plpgsql + as $$ begin end $$; +create event trigger et + on ddl_command_start + execute function s.f(); + +-- postgres can't drop supabase_etl_admin's event triggers +set role postgres; +drop event trigger et; + +set role supabase_etl_admin; +drop event trigger et; +drop function s.f(); +drop schema s; +reset role;