From 2934984d878c20ad305f7c1128fbc69070c75790 Mon Sep 17 00:00:00 2001 From: Utkarash Singh Date: Thu, 28 May 2026 12:35:55 +0100 Subject: [PATCH 1/3] fix(tests): split prime.sql so non-superuser harnesses can source it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nix/tests/prime.sql is loaded by both superuser-context harnesses (pg_regress in nix/checks.nix, the docker image test, the local migrate-tool) and supadev's test-postgres-engines-with-smoke.sh, which runs as the non-superuser postgres role against a hosted project. Seven extensions are intentionally excluded from supautils' privileged_extensions list (labeled "may be unsafe" in ansible/files/postgresql_config/supautils.conf.j2): amcheck, file_fdw, lo, pageinspect, pg_freespacemap, pg_surgery, pg_visibility Hosted non-superuser sessions cannot create these, so prime.sql halts with "permission denied to create extension amcheck" (alphabetically first) under psql -v ON_ERROR_STOP=1 — which became supadev's default in supabase/supadev@c6be2cb. Split into: - prime.sql: the safe set, sourced by all 4 consumers - prime-superuser.sql (new): the 7 gated extensions, sourced only by the 3 superuser-context harnesses --- nix/checks.nix | 12 ++++++++++++ nix/packages/docker-image-test.nix | 23 ++++++++++++++++++++++- nix/packages/migrate-tool.nix | 3 +++ nix/tests/prime-superuser.sql | 21 +++++++++++++++++++++ nix/tests/prime.sql | 14 +++++++------- 5 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 nix/tests/prime-superuser.sql diff --git a/nix/checks.nix b/nix/checks.nix index 0cf9ed999c..ca5fb99ec0 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 fe69f09328..9717de706c 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 c989921106..1931d24203 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 0000000000..000fe9b041 --- /dev/null +++ b/nix/tests/prime-superuser.sql @@ -0,0 +1,21 @@ +-- 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. +-- +-- Keep this list in sync with the "may be unsafe" list in supautils.conf.j2. + +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 5ae47444e1..015d1ef4f1 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; From 4279bcd411f0bebc66094c63fd6fcda177d89560 Mon Sep 17 00:00:00 2001 From: Utkarash Singh Date: Thu, 28 May 2026 16:19:13 +0100 Subject: [PATCH 2/3] docs(supautils): cross-reference prime-superuser.sql in supautils.conf.j2 Mirrors the "keep in sync" comment that lives in prime-superuser.sql so that anyone editing the supautils privileged_extensions list gets a pointer back to the test-side counterpart. Addresses review feedback on PR #2175. --- ansible/files/postgresql_config/supautils.conf.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/ansible/files/postgresql_config/supautils.conf.j2 b/ansible/files/postgresql_config/supautils.conf.j2 index bbfd61ceab..2fefa64961 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 From 63491bbef41107ddd740783c74246be13c5b6a82 Mon Sep 17 00:00:00 2001 From: Utkarash Singh Date: Thu, 28 May 2026 18:00:27 +0100 Subject: [PATCH 3/3] docs(prime-superuser): document PG-15-only entries from supautils' may-be-unsafe list adminpack and old_snapshot are also in supautils.conf.j2's "may be unsafe" list but were removed from contrib in PG 17. They're loaded by nix/tests/sql/z_15_ext_interface.sql for the PG 15 pg_regress path; adding them unconditionally to prime-superuser.sql would break PG 17 with "extension is not available". Header now documents the asymmetry to match the actual file contents. --- nix/tests/prime-superuser.sql | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nix/tests/prime-superuser.sql b/nix/tests/prime-superuser.sql index 000fe9b041..d2998ce4ce 100644 --- a/nix/tests/prime-superuser.sql +++ b/nix/tests/prime-superuser.sql @@ -8,7 +8,13 @@ -- the docker-image-test, and the local migrate-tool. supadev's hosted -- engines-with-smoke test sources `prime.sql` only. -- --- Keep this list in sync with the "may be unsafe" list in supautils.conf.j2. +-- 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;