Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ansible/files/postgresql_config/supautils.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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.*, deadlock_timeout, 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*'
6 changes: 3 additions & 3 deletions ansible/vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ postgres_major:

# Full version strings for each major version
postgres_release:
postgresorioledb-17: "17.6.0.024-orioledb"
postgres17: "17.6.1.067"
postgres15: "15.14.1.067"
postgresorioledb-17: "17.6.0.025-orioledb"
postgres17: "17.6.1.068"
postgres15: "15.14.1.068"
Comment on lines +13 to +15
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cat -n ansible/vars.yml | head -20

Repository: supabase/postgres

Length of output: 639


🌐 Web query:

PostgreSQL 17.6.0 release orioledb version stability

💡 Result:

Short answer: PostgreSQL 17.6.0 was released on August 14, 2025. OrioleDB is still a patched/extension-based storage engine for PostgreSQL 17 (beta series) that requires patched PostgreSQL binaries and is not yet recommended for general production use — you should treat it as experimental and test thoroughly before deploying. [1][2][3]

Sources:

  • PostgreSQL 17.6 release announcement / notes (released 2025-08-14). [1]
  • OrioleDB documentation: requires patched PostgreSQL 17 and describes current status/features/patches. [2]
  • OrioleDB project blog/docs noting beta status and limitations (production readiness: public beta, not recommended for production). [3]

🌐 Web query:

PostgreSQL 17.6.1 release version 068

💡 Result:

Do you mean the official PostgreSQL community server, or a vendor build (Percona / Postgres Pro)? I found:

  • PostgreSQL community released 17.6 on Aug 14, 2025 (no official community 17.6.1 listed). [1][2]
  • Percona released "Percona Distribution for PostgreSQL 17.6.1" on Sep 10, 2025. [3][4]
  • Postgres Pro published "Postgres Pro Enterprise 17.6.1" on Oct 17, 2025 (based on PostgreSQL 17.6). [5][6]

If by "version 068" you mean a package/release ID, build number, or a specific vendor package, tell me which distribution (OS/vendor) and I’ll look up the exact package/version details and provide links. References: [1] PostgreSQL 17.6 release notes, [2] PostgreSQL docs page for 17.6, [3] Percona announcement, [4] Percona release notes, [5] Postgres Pro 17.6.1 page, [6] Postgres Pro PostgreSQL 17.6 release notes.


🌐 Web query:

PostgreSQL 15.14 release version 068 security advisories

💡 Result:

PostgreSQL 15.14 (released 2025‑08‑14) includes fixes for multiple security issues. Key security advisories/CVEs addressed in 15.14:

  • CVE-2025-8713 — tightened security checks in planner estimation functions (fixes leakage of statistics via leaky functions / partitioning & view gaps). [1]
  • CVE-2025-8714 — untrusted-data inclusion in pg_dump/pg_restore (pg_dump output could be used to inject psql meta-commands executed by the restore user). [1][3]
  • CVE-2025-8715 — related security hardening included in 15.14 (listed in vendor and distro release notes). [1][3]

For authoritative details and full changelog see the PostgreSQL 15.14 release notes and the PostgreSQL security pages. [1][2]

Sources:
[1] PostgreSQL 15.14 release notes (E.2 Release 15.14).
[2] PostgreSQL Security Information / Security pages.
[3] Vendor/distro advisories summarizing addressed CVEs (Percona / CVE detail pages).


OrioleDB 17.6 is experimental and not recommended for production; clarify testing and vendor build status for non-standard versions.

The version identifiers with ".068" suffixes appear non-standard for PostgreSQL releases. OrioleDB 17.6 is explicitly in beta/experimental status and requires patched PostgreSQL binaries—confirm whether this is acceptable for your use case. PostgreSQL 17.6.1 does not exist in official community releases (only 17.6.0). Ensure these are documented Supabase custom builds and have been validated for your environment. PostgreSQL 15.14 does address known security issues (CVE-2025-8713, CVE-2025-8714, CVE-2025-8715)—verify that testing and deployment procedures account for the non-standard version format.

🤖 Prompt for AI Agents
In @ansible/vars.yml around lines 13-15, The version entries in ansible/vars.yml
(postgresorioledb-17, postgres17, postgres15) use non-standard suffixes and an
OrioleDB beta release; update the vars and documentation to either: a) switch
the variables to official, supported PostgreSQL release tags (remove the “.068”
suffix and use upstream 17.6.0 / 15.14 or the correct stable tags) or b)
explicitly mark these as Supabase/vendor custom builds by adding comments and a
new metadata map next to postgresorioledb-17 that records "vendor_build: true",
"experimental: true", source URL, and validation status; additionally ensure
CI/tests validate those custom binaries (compatibility and the CVE mitigations
for 15.14) and add a short note in the repo README referencing that these are
patched/custom images and listing who approved them.


# Non Postgres Extensions
pgbouncer_release: 1.19.0
Expand Down
10 changes: 10 additions & 0 deletions migrations/db/migrations/20251215120934_supabase_superuser.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- migrate:up
do $$
begin
if not exists (select from pg_roles where rolname = 'supabase_superuser') then
create role supabase_superuser;
grant supabase_superuser to postgres, supabase_etl_admin;
end if;
end $$;

-- migrate:down
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Empty down migration prevents clean rollback.

The down migration is empty, which means rolling back this migration will not remove the supabase_superuser role or revoke its grants. If rollback is needed, manual cleanup will be required.

🔎 Consider adding a down migration
 -- migrate:down
+do $$
+begin
+  if exists (select from pg_roles where rolname = 'supabase_superuser') then
+    revoke supabase_superuser from postgres, supabase_etl_admin;
+    drop role supabase_superuser;
+  end if;
+end $$;
🤖 Prompt for AI Agents
In @migrations/db/migrations/20251215120934_supabase_superuser.sql around line
10, The down migration is empty so rolling back won't remove the
supabase_superuser role or its grants; add SQL to revoke any grants given to
that role and drop the role in the down section of the migration (for example:
REVOKE ALL PRIVILEGES ON SCHEMA public FROM supabase_superuser; REVOKE ALL
PRIVILEGES ON ALL TABLES IN SCHEMA public FROM supabase_superuser; ALTER DEFAULT
PRIVILEGES FOR ROLE <owner> IN SCHEMA public REVOKE ...; DROP ROLE IF EXISTS
supabase_superuser;), updating the migration file
20251215120934_supabase_superuser.sql to include these revocation statements and
a DROP ROLE IF EXISTS supabase_superuser in the migrate:down block.

31 changes: 31 additions & 0 deletions nix/tests/expected/evtrigs.out
Original file line number Diff line number Diff line change
Expand Up @@ -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;
6 changes: 4 additions & 2 deletions nix/tests/expected/roles.out
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion nix/tests/expected/z_15_roles.out
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions nix/tests/expected/z_17_roles.out
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions nix/tests/sql/evtrigs.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Comment on lines +39 to +47
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clarify the expected behavior and add error handling.

The comment at line 39 states "postgres can't drop supabase_etl_admin's event triggers," but the test doesn't explicitly handle the expected failure. If the DROP at line 41 fails (as intended), the script will abort and skip the cleanup at lines 43-47, leaving test artifacts. If it succeeds (contrary to expectations), line 44 will fail with "event trigger does not exist."

🔎 Add explicit error handling

Consider wrapping the expected-to-fail operation in a transaction or using DO block with exception handling:

 -- postgres can't drop supabase_etl_admin's event triggers
 set role postgres;
-drop event trigger et;
+do $$
+begin
+  drop event trigger et;
+  raise exception 'Expected failure: postgres should not be able to drop supabase_etl_admin event trigger';
+exception
+  when insufficient_privilege then
+    raise notice 'Correctly prevented: postgres cannot drop supabase_etl_admin event trigger';
+end $$;
+reset role;

-set role supabase_etl_admin;
+-- cleanup as supabase_etl_admin
+set role supabase_etl_admin;
 drop event trigger et;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
-- 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;
-- postgres can't drop supabase_etl_admin's event triggers
set role postgres;
do $$
begin
drop event trigger et;
raise exception 'Expected failure: postgres should not be able to drop supabase_etl_admin event trigger';
exception
when insufficient_privilege then
raise notice 'Correctly prevented: postgres cannot drop supabase_etl_admin event trigger';
end $$;
reset role;
-- cleanup as supabase_etl_admin
set role supabase_etl_admin;
drop event trigger et;
drop function s.f();
drop schema s;
reset role;

Loading