From 0b4c7c44541058f149f4142d8a84465d7299e484 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Thu, 17 Sep 2026 18:36:39 +0530 Subject: [PATCH 1/3] feat: add supabase_integrations_admin role --- .../files/postgresql_config/supautils.conf.j2 | 4 +- .../00000000000000-initial-schema.sql | 4 + .../cli-config/postgresql.conf.template | 2 +- nix/tests/expected/roles.out | 138 +++++++++--------- nix/tools/postgresql_schema.sql | 1 + testinfra/test_ami_nix.py | 1 + 6 files changed, 79 insertions(+), 71 deletions(-) diff --git a/ansible/files/postgresql_config/supautils.conf.j2 b/ansible/files/postgresql_config/supautils.conf.j2 index 63c10761b5..f0569840d7 100644 --- a/ansible/files/postgresql_config/supautils.conf.j2 +++ b/ansible/files/postgresql_config/supautils.conf.j2 @@ -13,6 +13,6 @@ supautils.restrict_extension_versions = 'warn' supautils.privileged_extensions_superuser = 'supabase_admin' supautils.privileged_role = 'supabase_privileged_role' supautils.privileged_role_allowed_configs = 'auto_explain.*, deadlock_timeout, log_duration, log_lock_waits, log_min_duration_statement, log_min_error_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*, supabase_privileged_role' +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, supabase_integrations_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, supabase_integrations_admin, dashboard_user, pgbouncer, service_role*, authenticator*, authenticated*, anon*, supabase_privileged_role' supautils.hint_roles = 'anon, authenticated, service_role' diff --git a/migrations/db/init-scripts/00000000000000-initial-schema.sql b/migrations/db/init-scripts/00000000000000-initial-schema.sql index b32db6b939..39c9225255 100644 --- a/migrations/db/init-scripts/00000000000000-initial-schema.sql +++ b/migrations/db/init-scripts/00000000000000-initial-schema.sql @@ -19,6 +19,10 @@ grant create on database postgres to supabase_etl_admin; create role supabase_read_only_user with login bypassrls; grant pg_read_all_data to supabase_read_only_user; +-- Supabase integrations user (catch-all role for first-party integrations, e.g. Issue Inbox) +create user supabase_integrations_admin with login; +grant create on database postgres to supabase_integrations_admin; + -- Extension namespacing create schema if not exists extensions; create extension if not exists "uuid-ossp" with schema extensions; diff --git a/nix/packages/cli-config/postgresql.conf.template b/nix/packages/cli-config/postgresql.conf.template index 7c4fba5d4f..e7317cab4e 100644 --- a/nix/packages/cli-config/postgresql.conf.template +++ b/nix/packages/cli-config/postgresql.conf.template @@ -39,5 +39,5 @@ shared_preload_libraries = 'pg_stat_statements, pg_cron, pg_net, pgsodium, supab #vault.getkey_script = '/path/to/pgsodium_getkey.sh' # Supautils configuration -supautils.reserved_roles = 'supabase_admin,supabase_auth_admin,supabase_storage_admin,supabase_read_only_user,supabase_replication_admin,supabase_realtime_admin,supabase_functions_admin' +supautils.reserved_roles = 'supabase_admin,supabase_auth_admin,supabase_storage_admin,supabase_read_only_user,supabase_replication_admin,supabase_realtime_admin,supabase_functions_admin,supabase_integrations_admin' supautils.reserved_memberships = 'pg_read_server_files,pg_write_server_files,pg_execute_server_program' diff --git a/nix/tests/expected/roles.out b/nix/tests/expected/roles.out index 78a60dc24d..1fec6fb3df 100644 --- a/nix/tests/expected/roles.out +++ b/nix/tests/expected/roles.out @@ -19,40 +19,41 @@ select from pg_roles r where rolname not in ('pg_create_subscription', 'pg_maintain', 'pg_use_reserved_connections') order by rolname; - rolname | rolcreaterole | rolcanlogin | rolsuper | rolinherit | rolcreatedb | rolreplication | rolconnlimit | rolbypassrls | rolvaliduntil -----------------------------+---------------+-------------+----------+------------+-------------+----------------+--------------+--------------+--------------- - anon | f | f | f | t | f | f | -1 | f | - authenticated | f | f | f | t | f | f | -1 | f | - authenticator | f | t | f | f | f | f | -1 | f | - dashboard_user | t | f | f | t | t | t | -1 | f | - pg_checkpoint | f | f | f | t | f | f | -1 | f | - pg_database_owner | f | f | f | t | f | f | -1 | f | - pg_execute_server_program | f | f | f | t | f | f | -1 | f | - pg_monitor | f | f | f | t | f | f | -1 | f | - pg_read_all_data | f | f | f | t | f | f | -1 | f | - pg_read_all_settings | f | f | f | t | f | f | -1 | f | - pg_read_all_stats | f | f | f | t | f | f | -1 | f | - pg_read_server_files | f | f | f | t | f | f | -1 | f | - pg_signal_backend | f | f | f | t | f | f | -1 | f | - pg_stat_scan_tables | f | f | f | t | f | f | -1 | f | - pg_write_all_data | f | f | f | t | f | f | -1 | f | - pg_write_server_files | f | f | f | t | f | f | -1 | f | - pgbouncer | f | t | f | t | f | f | -1 | f | - pgsodium_keyholder | f | f | f | t | f | f | -1 | f | - pgsodium_keyiduser | f | f | f | t | f | f | -1 | f | - pgsodium_keymaker | f | f | f | t | f | f | -1 | f | - pgtle_admin | f | f | f | t | f | f | -1 | f | - postgres | t | t | f | t | t | t | -1 | t | - service_role | f | f | f | t | f | f | -1 | t | - supabase_admin | t | t | t | t | t | t | -1 | t | - supabase_auth_admin | t | t | f | f | f | f | -1 | f | - supabase_etl_admin | f | t | f | t | f | t | -1 | t | - supabase_functions_admin | t | t | f | f | f | f | -1 | f | - supabase_privileged_role | f | f | f | t | f | f | -1 | f | - 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 | -(31 rows) + rolname | rolcreaterole | rolcanlogin | rolsuper | rolinherit | rolcreatedb | rolreplication | rolconnlimit | rolbypassrls | rolvaliduntil +-----------------------------+---------------+-------------+----------+------------+-------------+----------------+--------------+--------------+--------------- + anon | f | f | f | t | f | f | -1 | f | + authenticated | f | f | f | t | f | f | -1 | f | + authenticator | f | t | f | f | f | f | -1 | f | + dashboard_user | t | f | f | t | t | t | -1 | f | + pg_checkpoint | f | f | f | t | f | f | -1 | f | + pg_database_owner | f | f | f | t | f | f | -1 | f | + pg_execute_server_program | f | f | f | t | f | f | -1 | f | + pg_monitor | f | f | f | t | f | f | -1 | f | + pg_read_all_data | f | f | f | t | f | f | -1 | f | + pg_read_all_settings | f | f | f | t | f | f | -1 | f | + pg_read_all_stats | f | f | f | t | f | f | -1 | f | + pg_read_server_files | f | f | f | t | f | f | -1 | f | + pg_signal_backend | f | f | f | t | f | f | -1 | f | + pg_stat_scan_tables | f | f | f | t | f | f | -1 | f | + pg_write_all_data | f | f | f | t | f | f | -1 | f | + pg_write_server_files | f | f | f | t | f | f | -1 | f | + pgbouncer | f | t | f | t | f | f | -1 | f | + pgsodium_keyholder | f | f | f | t | f | f | -1 | f | + pgsodium_keyiduser | f | f | f | t | f | f | -1 | f | + pgsodium_keymaker | f | f | f | t | f | f | -1 | f | + pgtle_admin | f | f | f | t | f | f | -1 | f | + postgres | t | t | f | t | t | t | -1 | t | + service_role | f | f | f | t | f | f | -1 | t | + supabase_admin | t | t | t | t | t | t | -1 | t | + supabase_auth_admin | t | t | f | f | f | f | -1 | f | + supabase_etl_admin | f | t | f | t | f | t | -1 | t | + supabase_functions_admin | t | t | f | f | f | f | -1 | f | + supabase_integrations_admin | f | t | f | t | f | f | -1 | f | + supabase_privileged_role | f | f | f | t | f | f | -1 | f | + 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 | +(32 rows) select rolname, @@ -60,40 +61,41 @@ select from pg_roles r where rolname not in ('pg_create_subscription', 'pg_maintain', 'pg_use_reserved_connections') order by rolname; - rolname | rolconfig -----------------------------+------------------------------------------------------------------------------------------ - anon | {statement_timeout=3s} - authenticated | {statement_timeout=8s} - authenticator | {"session_preload_libraries=supautils, safeupdate",statement_timeout=8s,lock_timeout=8s} - dashboard_user | - pg_checkpoint | - pg_database_owner | - pg_execute_server_program | - pg_monitor | - pg_read_all_data | - pg_read_all_settings | - pg_read_all_stats | - pg_read_server_files | - pg_signal_backend | - pg_stat_scan_tables | - pg_write_all_data | - pg_write_server_files | - pgbouncer | - pgsodium_keyholder | - pgsodium_keyiduser | - pgsodium_keymaker | - pgtle_admin | - postgres | {"search_path=\"\\$user\", public, extensions"} - service_role | - supabase_admin | {"search_path=\"$user\", public, auth, extensions",log_statement=none} - supabase_auth_admin | {search_path=auth,idle_in_transaction_session_timeout=60000,log_statement=none} - supabase_etl_admin | - supabase_functions_admin | - supabase_privileged_role | - supabase_read_only_user | {default_transaction_read_only=on} - supabase_replication_admin | - supabase_storage_admin | {search_path=storage,log_statement=none} -(31 rows) + rolname | rolconfig +-----------------------------+------------------------------------------------------------------------------------------ + anon | {statement_timeout=3s} + authenticated | {statement_timeout=8s} + authenticator | {"session_preload_libraries=supautils, safeupdate",statement_timeout=8s,lock_timeout=8s} + dashboard_user | + pg_checkpoint | + pg_database_owner | + pg_execute_server_program | + pg_monitor | + pg_read_all_data | + pg_read_all_settings | + pg_read_all_stats | + pg_read_server_files | + pg_signal_backend | + pg_stat_scan_tables | + pg_write_all_data | + pg_write_server_files | + pgbouncer | + pgsodium_keyholder | + pgsodium_keyiduser | + pgsodium_keymaker | + pgtle_admin | + postgres | {"search_path=\"\\$user\", public, extensions"} + service_role | + supabase_admin | {"search_path=\"$user\", public, auth, extensions",log_statement=none} + supabase_auth_admin | {search_path=auth,idle_in_transaction_session_timeout=60000,log_statement=none} + supabase_etl_admin | + supabase_functions_admin | + supabase_integrations_admin | + supabase_privileged_role | + supabase_read_only_user | {default_transaction_read_only=on} + supabase_replication_admin | + supabase_storage_admin | {search_path=storage,log_statement=none} +(32 rows) -- Check all privileges of the roles on the schemas select schema_name, privilege_type, grantee, default_for diff --git a/nix/tools/postgresql_schema.sql b/nix/tools/postgresql_schema.sql index 7c2ae21a9b..693c8a2797 100644 --- a/nix/tools/postgresql_schema.sql +++ b/nix/tools/postgresql_schema.sql @@ -9,4 +9,5 @@ ALTER USER supabase_storage_admin WITH PASSWORD 'postgres'; ALTER USER supabase_replication_admin WITH PASSWORD 'postgres'; ALTER USER supabase_etl_admin WITH PASSWORD 'postgres'; ALTER ROLE supabase_read_only_user WITH PASSWORD 'postgres'; +ALTER USER supabase_integrations_admin WITH PASSWORD 'postgres'; ALTER ROLE supabase_admin SET search_path TO "$user",public,auth,extensions; diff --git a/testinfra/test_ami_nix.py b/testinfra/test_ami_nix.py index cfd77554d6..30ec605861 100644 --- a/testinfra/test_ami_nix.py +++ b/testinfra/test_ami_nix.py @@ -35,6 +35,7 @@ ALTER USER supabase_replication_admin WITH PASSWORD 'postgres'; ALTER USER supabase_etl_admin WITH PASSWORD 'postgres'; ALTER ROLE supabase_read_only_user WITH PASSWORD 'postgres'; +ALTER USER supabase_integrations_admin WITH PASSWORD 'postgres'; ALTER ROLE supabase_admin SET search_path TO "$user",public,auth,extensions; """ realtime_env_content = "" From b30d5803af3a355b2c4aec37d5d019589bf70135 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Thu, 17 Sep 2026 19:27:36 +0530 Subject: [PATCH 2/3] fix: a failing test --- .../z_multigres-orioledb-17_roles.out | 126 +++++++++--------- 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/nix/tests/expected/z_multigres-orioledb-17_roles.out b/nix/tests/expected/z_multigres-orioledb-17_roles.out index 9e530eee17..d83462b177 100644 --- a/nix/tests/expected/z_multigres-orioledb-17_roles.out +++ b/nix/tests/expected/z_multigres-orioledb-17_roles.out @@ -19,37 +19,38 @@ select from pg_roles r where rolname not in ('pg_create_subscription', 'pg_maintain', 'pg_use_reserved_connections') order by rolname; - rolname | rolcreaterole | rolcanlogin | rolsuper | rolinherit | rolcreatedb | rolreplication | rolconnlimit | rolbypassrls | rolvaliduntil -----------------------------+---------------+-------------+----------+------------+-------------+----------------+--------------+--------------+--------------- - anon | f | f | f | t | f | f | -1 | f | - authenticated | f | f | f | t | f | f | -1 | f | - authenticator | f | t | f | f | f | f | -1 | f | - dashboard_user | t | f | f | t | t | t | -1 | f | - pg_checkpoint | f | f | f | t | f | f | -1 | f | - pg_database_owner | f | f | f | t | f | f | -1 | f | - pg_execute_server_program | f | f | f | t | f | f | -1 | f | - pg_monitor | f | f | f | t | f | f | -1 | f | - pg_read_all_data | f | f | f | t | f | f | -1 | f | - pg_read_all_settings | f | f | f | t | f | f | -1 | f | - pg_read_all_stats | f | f | f | t | f | f | -1 | f | - pg_read_server_files | f | f | f | t | f | f | -1 | f | - pg_signal_backend | f | f | f | t | f | f | -1 | f | - pg_stat_scan_tables | f | f | f | t | f | f | -1 | f | - pg_write_all_data | f | f | f | t | f | f | -1 | f | - pg_write_server_files | f | f | f | t | f | f | -1 | f | - pgbouncer | f | t | f | t | f | f | -1 | f | - pgtle_admin | f | f | f | t | f | f | -1 | f | - postgres | t | t | f | t | t | t | -1 | t | - service_role | f | f | f | t | f | f | -1 | t | - supabase_admin | t | t | t | t | t | t | -1 | t | - supabase_auth_admin | t | t | f | f | f | f | -1 | f | - supabase_etl_admin | f | t | f | t | f | t | -1 | t | - supabase_functions_admin | t | t | f | f | f | f | -1 | f | - supabase_privileged_role | f | f | f | t | f | f | -1 | f | - 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 | -(28 rows) + rolname | rolcreaterole | rolcanlogin | rolsuper | rolinherit | rolcreatedb | rolreplication | rolconnlimit | rolbypassrls | rolvaliduntil +-----------------------------+---------------+-------------+----------+------------+-------------+----------------+--------------+--------------+--------------- + anon | f | f | f | t | f | f | -1 | f | + authenticated | f | f | f | t | f | f | -1 | f | + authenticator | f | t | f | f | f | f | -1 | f | + dashboard_user | t | f | f | t | t | t | -1 | f | + pg_checkpoint | f | f | f | t | f | f | -1 | f | + pg_database_owner | f | f | f | t | f | f | -1 | f | + pg_execute_server_program | f | f | f | t | f | f | -1 | f | + pg_monitor | f | f | f | t | f | f | -1 | f | + pg_read_all_data | f | f | f | t | f | f | -1 | f | + pg_read_all_settings | f | f | f | t | f | f | -1 | f | + pg_read_all_stats | f | f | f | t | f | f | -1 | f | + pg_read_server_files | f | f | f | t | f | f | -1 | f | + pg_signal_backend | f | f | f | t | f | f | -1 | f | + pg_stat_scan_tables | f | f | f | t | f | f | -1 | f | + pg_write_all_data | f | f | f | t | f | f | -1 | f | + pg_write_server_files | f | f | f | t | f | f | -1 | f | + pgbouncer | f | t | f | t | f | f | -1 | f | + pgtle_admin | f | f | f | t | f | f | -1 | f | + postgres | t | t | f | t | t | t | -1 | t | + service_role | f | f | f | t | f | f | -1 | t | + supabase_admin | t | t | t | t | t | t | -1 | t | + supabase_auth_admin | t | t | f | f | f | f | -1 | f | + supabase_etl_admin | f | t | f | t | f | t | -1 | t | + supabase_functions_admin | t | t | f | f | f | f | -1 | f | + supabase_integrations_admin | f | t | f | t | f | f | -1 | f | + supabase_privileged_role | f | f | f | t | f | f | -1 | f | + 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 | +(29 rows) select rolname, @@ -57,37 +58,38 @@ select from pg_roles r where rolname not in ('pg_create_subscription', 'pg_maintain', 'pg_use_reserved_connections') order by rolname; - rolname | rolconfig -----------------------------+------------------------------------------------------------------------------------------ - anon | {statement_timeout=3s} - authenticated | {statement_timeout=8s} - authenticator | {"session_preload_libraries=supautils, safeupdate",statement_timeout=8s,lock_timeout=8s} - dashboard_user | - pg_checkpoint | - pg_database_owner | - pg_execute_server_program | - pg_monitor | - pg_read_all_data | - pg_read_all_settings | - pg_read_all_stats | - pg_read_server_files | - pg_signal_backend | - pg_stat_scan_tables | - pg_write_all_data | - pg_write_server_files | - pgbouncer | - pgtle_admin | - postgres | {"search_path=\"\\$user\", public, extensions"} - service_role | - supabase_admin | {"search_path=\"\\$user\", public, auth, extensions",log_statement=none} - supabase_auth_admin | {search_path=auth,idle_in_transaction_session_timeout=60000,log_statement=none} - supabase_etl_admin | - supabase_functions_admin | - supabase_privileged_role | - supabase_read_only_user | {default_transaction_read_only=on} - supabase_replication_admin | - supabase_storage_admin | {search_path=storage,log_statement=none} -(28 rows) + rolname | rolconfig +-----------------------------+------------------------------------------------------------------------------------------ + anon | {statement_timeout=3s} + authenticated | {statement_timeout=8s} + authenticator | {"session_preload_libraries=supautils, safeupdate",statement_timeout=8s,lock_timeout=8s} + dashboard_user | + pg_checkpoint | + pg_database_owner | + pg_execute_server_program | + pg_monitor | + pg_read_all_data | + pg_read_all_settings | + pg_read_all_stats | + pg_read_server_files | + pg_signal_backend | + pg_stat_scan_tables | + pg_write_all_data | + pg_write_server_files | + pgbouncer | + pgtle_admin | + postgres | {"search_path=\"\\$user\", public, extensions"} + service_role | + supabase_admin | {"search_path=\"\\$user\", public, auth, extensions",log_statement=none} + supabase_auth_admin | {search_path=auth,idle_in_transaction_session_timeout=60000,log_statement=none} + supabase_etl_admin | + supabase_functions_admin | + supabase_integrations_admin | + supabase_privileged_role | + supabase_read_only_user | {default_transaction_read_only=on} + supabase_replication_admin | + supabase_storage_admin | {search_path=storage,log_statement=none} +(29 rows) -- Check all privileges of the roles on the schemas select schema_name, privilege_type, grantee, default_for From a59b3cc8d8fd10c83fb44168dfb5d3b84d981389 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Fri, 18 Sep 2026 13:10:24 +0530 Subject: [PATCH 3/3] chore: bump AMI versions --- ansible/vars.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ansible/vars.yml b/ansible/vars.yml index 7691ba15d9..543b11de15 100644 --- a/ansible/vars.yml +++ b/ansible/vars.yml @@ -7,9 +7,9 @@ postgres_major: - "17" - orioledb-17 postgres_release: - postgresorioledb-17: "17.9.0.026-orioledb" - postgres17: "17.6.1.173" - postgres15: "15.14.1.173" + postgresorioledb-17: "17.9.0.027-orioledb-nr" + postgres17: "17.6.1.174-nr" + postgres15: "15.14.1.174-nr" supabase_admin_agent_splay: 30s ############################################################################################################### # The following block of yaml is for get_url and co throughout the playbook #