diff --git a/ansible/files/postgresql_config/supautils.conf.j2 b/ansible/files/postgresql_config/supautils.conf.j2 index bbfd61cea..2fefa6496 100644 --- a/ansible/files/postgresql_config/supautils.conf.j2 +++ b/ansible/files/postgresql_config/supautils.conf.j2 @@ -3,6 +3,7 @@ supautils.policy_grants = '{"postgres":["auth.audit_log_entries","auth.flow_stat supautils.drop_trigger_grants = '{"postgres":["auth.audit_log_entries","auth.flow_state","auth.identities","auth.instances","auth.mfa_amr_claims","auth.mfa_challenges","auth.mfa_factors","auth.oauth_clients","auth.one_time_tokens","auth.refresh_tokens","auth.saml_providers","auth.saml_relay_states","auth.sessions","auth.sso_domains","auth.sso_providers","auth.users","realtime.messages","realtime.subscription","storage.buckets","storage.buckets_analytics","storage.objects","storage.prefixes","storage.s3_multipart_uploads","storage.s3_multipart_uploads_parts"]}' # full list: address_standardizer, address_standardizer_data_us, adminpack, amcheck, autoinc, bloom, btree_gin, btree_gist, citext, cube, dblink, dict_int, dict_xsyn, earthdistance, file_fdw, fuzzystrmatch, hstore, http, hypopg, index_advisor, insert_username, intagg, intarray, isn, lo, ltree, moddatetime, old_snapshot, orioledb, pageinspect, pg_buffercache, pg_cron, pg_freespacemap, pg_graphql, pg_hashids, pg_jsonschema, pg_net, pg_prewarm, pg_repack, pg_stat_monitor, pg_stat_statements, pg_surgery, pg_tle, pg_trgm, pg_visibility, pg_walinspect, pgaudit, pgcrypto, pgjwt, pgmq, pgroonga, pgroonga_database, pgrouting, pgrowlocks, pgsodium, pgstattuple, pgtap, plcoffee, pljava, plls, plpgsql, 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, xml2 # omitted because may be unsafe: adminpack, amcheck, file_fdw, lo, old_snapshot, pageinspect, pg_freespacemap, pg_surgery, pg_visibility +# NOTE: keep nix/tests/prime-superuser.sql in sync with the "may be unsafe" list above. # omitted because deprecated: intagg, xml2 # omitted because doesn't require superuser: pgmq # omitted because protected: plpgsql diff --git a/nix/checks.nix b/nix/checks.nix index 0cf9ed999..ca5fb99ec 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -452,6 +452,13 @@ pg_ctl -D "$PGTAP_CLUSTER" stop exit 1 fi + log info "Loading prime-superuser SQL file (extensions excluded from supautils privileged list)" + if ! log_cmd psql -p ${pgPort} -h localhost --username=supabase_admin -d testing -v ON_ERROR_STOP=1 -Xf ${./tests/prime-superuser.sql}; then + log error "Error executing prime-superuser SQL file. PostgreSQL log content:" + cat "$PGTAP_CLUSTER"/postgresql.log + pg_ctl -D "$PGTAP_CLUSTER" stop + exit 1 + fi fi # Create a table to store test configuration @@ -507,6 +514,11 @@ log error "Error executing SQL file" exit 1 fi + log info "Loading prime-superuser SQL file (extensions excluded from supautils privileged list)" + if ! log_cmd psql -p ${pgPort} -h localhost --no-password --username=supabase_admin -d postgres -v ON_ERROR_STOP=1 -Xf ${./tests/prime-superuser.sql} 2>&1; then + log error "Error executing prime-superuser SQL file" + exit 1 + fi fi # Create a table to store test configuration for pg_regress tests diff --git a/nix/packages/docker-image-test.nix b/nix/packages/docker-image-test.nix index fe69f0932..9717de706 100644 --- a/nix/packages/docker-image-test.nix +++ b/nix/packages/docker-image-test.nix @@ -525,10 +525,16 @@ writeShellApplication { fi log_info "Container will access mock server at $HTTP_MOCK_HOST:$HTTP_MOCK_PORT" - # Select the appropriate prime.sql for this image variant + # Select the appropriate prime.sql for this image variant. + # The multigres variant bundles its own complete prime file + # (prime-multigres.sql); the standard variant needs prime.sql plus + # prime-superuser.sql for the extensions excluded from supautils' + # privileged_extensions list. local prime_sql="$TESTS_DIR/prime.sql" + local prime_superuser_sql="$TESTS_DIR/prime-superuser.sql" if [[ "$VERSION" == multigres-* ]]; then prime_sql="$TESTS_DIR/prime-multigres.sql" + prime_superuser_sql="" fi log_info "Running prime.sql to enable extensions..." @@ -544,6 +550,21 @@ writeShellApplication { exit 1 fi + if [[ -n "$prime_superuser_sql" ]]; then + log_info "Running prime-superuser.sql for supautils-gated extensions..." + if ! PGPASSWORD="$POSTGRES_PASSWORD" "$PSQL_PATH" \ + -h localhost \ + -p "$PORT" \ + -U "$POSTGRES_USER" \ + -d "$POSTGRES_DB" \ + -v ON_ERROR_STOP=1 \ + -X \ + -f "$prime_superuser_sql" 2>&1; then + log_error "Failed to run prime-superuser.sql" + exit 1 + fi + fi + log_info "Creating test_config table..." PGPASSWORD="$POSTGRES_PASSWORD" "$PSQL_PATH" \ -h localhost \ diff --git a/nix/packages/migrate-tool.nix b/nix/packages/migrate-tool.nix index c98992110..1931d2420 100644 --- a/nix/packages/migrate-tool.nix +++ b/nix/packages/migrate-tool.nix @@ -3,6 +3,7 @@ let configFile = ../tests/postgresql.conf.in; getkeyScript = ../tests/util/pgsodium_getkey.sh; primingScript = ../tests/prime.sql; + primingSuperuserScript = ../tests/prime-superuser.sql; migrationData = ../tests/migrations/data.sql; in writeShellApplication { @@ -79,9 +80,11 @@ writeShellApplication { "$OLDVER/bin/pg_ctl" start -D "$DATDIR" PRIMING_SCRIPT="${primingScript}" + PRIMING_SUPERUSER_SCRIPT="${primingSuperuserScript}" MIGRATION_DATA="${migrationData}" "$OLDVER/bin/psql" -h localhost -d postgres -Xf "$PRIMING_SCRIPT" + "$OLDVER/bin/psql" -h localhost -d postgres -Xf "$PRIMING_SUPERUSER_SCRIPT" "$OLDVER/bin/psql" -h localhost -d postgres -Xf "$MIGRATION_DATA" if [ "$UPGRADE_METHOD" == "pg_upgrade" ]; then diff --git a/nix/tests/prime-superuser.sql b/nix/tests/prime-superuser.sql new file mode 100644 index 000000000..d2998ce4c --- /dev/null +++ b/nix/tests/prime-superuser.sql @@ -0,0 +1,27 @@ +-- Superuser-only extensions for testing. +-- +-- These extensions are excluded from `supautils.privileged_extensions` (see +-- the "omitted because may be unsafe" comment in +-- `ansible/files/postgresql_config/supautils.conf.j2`). Hosted Supabase +-- projects cannot install them via non-superuser sessions, so this file is +-- loaded only by superuser-context harnesses: pg_regress (nix/checks.nix), +-- the docker-image-test, and the local migrate-tool. supadev's hosted +-- engines-with-smoke test sources `prime.sql` only. +-- +-- This file covers the "may be unsafe" extensions available in BOTH PG 15 +-- and PG 17 builds. Two more entries from the same list, `adminpack` and +-- `old_snapshot`, were removed from contrib in PG 17 and are loaded directly +-- by nix/tests/sql/z_15_ext_interface.sql for the PG 15 path. +-- +-- Keep this list in sync with the "may be unsafe" list in supautils.conf.j2, +-- minus adminpack and old_snapshot. + +set client_min_messages = warning; + +create extension if not exists amcheck; +create extension if not exists file_fdw; +create extension if not exists lo; +create extension if not exists pageinspect; +create extension if not exists pg_freespacemap; +create extension if not exists pg_surgery; +create extension if not exists pg_visibility; diff --git a/nix/tests/prime.sql b/nix/tests/prime.sql index 5ae47444e..015d1ef4f 100644 --- a/nix/tests/prime.sql +++ b/nix/tests/prime.sql @@ -3,9 +3,15 @@ set client_min_messages = warning; -- CREATE ROLE anon; -- CREATE ROLE authenticated; -- CREATE ROLE service_role; +-- +-- Extensions in supautils' "may be unsafe" list (amcheck, file_fdw, lo, +-- pageinspect, pg_freespacemap, pg_surgery, pg_visibility) are NOT enabled +-- here so this file can be sourced by non-superuser contexts (e.g. supadev's +-- engines-with-smoke against hosted projects). Superuser-context harnesses +-- (nix/checks.nix, docker-image-test, migrate-tool) source prime-superuser.sql +-- in addition to this file. create extension if not exists address_standardizer; create extension if not exists address_standardizer_data_us; -create extension if not exists amcheck; create extension if not exists autoinc; create extension if not exists bloom; create extension if not exists btree_gin; @@ -16,7 +22,6 @@ create extension if not exists dblink; create extension if not exists dict_int; create extension if not exists dict_xsyn; create extension if not exists earthdistance; -create extension if not exists file_fdw; create extension if not exists fuzzystrmatch; create extension if not exists http; create extension if not exists hstore; @@ -26,10 +31,8 @@ create extension if not exists insert_username; create extension if not exists intagg; create extension if not exists intarray; create extension if not exists isn; -create extension if not exists lo; create extension if not exists ltree; create extension if not exists moddatetime; -create extension if not exists pageinspect; create extension if not exists pg_buffercache; /* @@ -41,7 +44,6 @@ cron.database_name = 'testing' create extension if not exists pg_net; create extension if not exists pg_graphql; -create extension if not exists pg_freespacemap; create extension if not exists pg_hashids; create extension if not exists pg_prewarm; create extension if not exists pgmq; @@ -51,10 +53,8 @@ create extension if not exists pg_partman with schema partman; create extension if not exists pg_repack; create extension if not exists pg_stat_monitor; create extension if not exists pg_stat_statements; -create extension if not exists pg_surgery; create extension if not exists pg_tle; create extension if not exists pg_trgm; -create extension if not exists pg_visibility; create extension if not exists pg_walinspect; create extension if not exists pgaudit; create extension if not exists pgcrypto;