diff --git a/migrations/db/init-scripts/README.md b/migrations/db/init-scripts/README.md new file mode 100644 index 000000000..c12fe3b8f --- /dev/null +++ b/migrations/db/init-scripts/README.md @@ -0,0 +1,7 @@ + +The effects of these migrations are tested on: + +- [nix/tests/sql/auth.out](../../../nix/tests/expected/auth.out) +- [nix/tests/sql/storage.out](../../../nix/tests/expected/storage.out) +- [nix/tests/sql/roles.out](../../../nix/tests/expected/roles.out) +- [nix/tests/sql/evtrigs.out](../../../nix/tests/expected/evtrigs.out) diff --git a/nix/tests/expected/auth.out b/nix/tests/expected/auth.out index d3277513a..22c983c00 100644 --- a/nix/tests/expected/auth.out +++ b/nix/tests/expected/auth.out @@ -13,33 +13,6 @@ where auth | supabase_admin (1 row) --- attributes of the supabase_auth_admin -select - rolcreaterole , - rolcanlogin , - rolsuper , - rolinherit , - rolcreatedb , - rolreplication , - rolconnlimit , - rolbypassrls , - rolvaliduntil -from pg_roles r -where r.rolname = 'supabase_auth_admin'; - rolcreaterole | rolcanlogin | rolsuper | rolinherit | rolcreatedb | rolreplication | rolconnlimit | rolbypassrls | rolvaliduntil ----------------+-------------+----------+------------+-------------+----------------+--------------+--------------+--------------- - t | t | f | f | f | f | -1 | f | -(1 row) - -select - rolconfig -from pg_roles r -where r.rolname = 'supabase_auth_admin'; - rolconfig ---------------------------------------------------------------------------------- - {search_path=auth,idle_in_transaction_session_timeout=60000,log_statement=none} -(1 row) - -- auth schema tables with owners and rls policies select ns.nspname as schema_name, @@ -129,52 +102,3 @@ order by auth | uid | supabase_auth_admin (3 rows) --- roles which have USAGE on the auth schema -select - n.nspname as schema_name, - r.rolname as role_name, - a.privilege_type -from - pg_namespace n -cross join lateral aclexplode(n.nspacl) as a -join - pg_roles r on a.grantee = r.oid -where - n.nspname = 'auth' - and a.privilege_type = 'USAGE' -order by - r.rolname; - schema_name | role_name | privilege_type --------------+---------------------+---------------- - auth | anon | USAGE - auth | authenticated | USAGE - auth | dashboard_user | USAGE - auth | postgres | USAGE - auth | service_role | USAGE - auth | supabase_admin | USAGE - auth | supabase_auth_admin | USAGE -(7 rows) - --- roles which have CREATE on the auth schema -select - n.nspname as schema_name, - r.rolname as role_name, - a.privilege_type -from - pg_namespace n -cross join lateral aclexplode(n.nspacl) as a -join - pg_roles r on a.grantee = r.oid -where - n.nspname = 'auth' - and a.privilege_type = 'CREATE' -order by - r.rolname; - schema_name | role_name | privilege_type --------------+---------------------+---------------- - auth | dashboard_user | CREATE - auth | postgres | CREATE - auth | supabase_admin | CREATE - auth | supabase_auth_admin | CREATE -(4 rows) - diff --git a/nix/tests/expected/default_privs.out b/nix/tests/expected/default_privs.out deleted file mode 100644 index 862d10087..000000000 --- a/nix/tests/expected/default_privs.out +++ /dev/null @@ -1,12 +0,0 @@ --- this tests the outcome of doing ALTER DEFAULT PRIVILEGES.. -select defaclrole::regrole, defaclnamespace::regnamespace, defaclobjtype from pg_default_acl where defaclnamespace = 'public'::regnamespace::oid order by defaclrole::regrole, defaclobjtype; - defaclrole | defaclnamespace | defaclobjtype -----------------+-----------------+--------------- - supabase_admin | public | S - supabase_admin | public | f - supabase_admin | public | r - postgres | public | S - postgres | public | f - postgres | public | r -(6 rows) - diff --git a/nix/tests/expected/roles.out b/nix/tests/expected/roles.out new file mode 100644 index 000000000..b4188512b --- /dev/null +++ b/nix/tests/expected/roles.out @@ -0,0 +1,580 @@ +-- all roles and attributes +select + rolname, + rolcreaterole , + rolcanlogin , + rolsuper , + rolinherit , + rolcreatedb , + rolreplication , + rolconnlimit , + rolbypassrls , + rolvaliduntil +from pg_roles r +-- TODO: this exclusion is to maintain compat with pg17, we should cover it +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_functions_admin | t | t | f | f | 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, + rolconfig +from pg_roles r +-- TODO: this exclusion is to maintain compat with pg17, we should cover it +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=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_functions_admin | + supabase_read_only_user | + supabase_replication_admin | + supabase_storage_admin | {search_path=storage,log_statement=none} +(29 rows) + +-- all role memberships +select + r.rolname as member, + g.rolname as "member_of (can become)", + m.admin_option +from + pg_roles r +left join + pg_auth_members m on r.oid = m.member +left join + pg_roles g on m.roleid = g.oid +-- TODO: this exclusion is to maintain compat with pg17, we should cover it +where r.rolname not in ('pg_create_subscription', 'pg_maintain', 'pg_use_reserved_connections') +order by + r.rolname, g.rolname; + member | member_of (can become) | admin_option +----------------------------+------------------------+-------------- + anon | | + authenticated | | + authenticator | anon | f + authenticator | authenticated | f + authenticator | service_role | f + dashboard_user | | + pg_checkpoint | | + pg_database_owner | | + pg_execute_server_program | | + pg_monitor | pg_read_all_settings | f + pg_monitor | pg_read_all_stats | f + pg_monitor | pg_stat_scan_tables | f + 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 | f + pgsodium_keyiduser | | + pgsodium_keymaker | pgsodium_keyholder | f + pgsodium_keymaker | pgsodium_keyiduser | f + pgtle_admin | | + postgres | anon | f + postgres | authenticated | f + postgres | pg_monitor | f + postgres | pg_read_all_data | f + postgres | pg_signal_backend | f + postgres | pgtle_admin | f + postgres | service_role | f + postgres | supabase_auth_admin | f + postgres | supabase_storage_admin | f + service_role | | + supabase_admin | | + supabase_auth_admin | | + supabase_functions_admin | | + supabase_read_only_user | pg_read_all_data | f + supabase_replication_admin | | + supabase_storage_admin | authenticator | f +(42 rows) + +-- Check all privileges of the roles on the schemas +select schema_name, privilege_type, grantee, default_for +from ( + -- ALTER DEFAULT privileges on schemas + select + n.nspname as schema_name, + a.privilege_type, + r.rolname as grantee, + d.defaclrole::regrole as default_for, + case when n.nspname = 'public' then 0 else 1 end as schema_order + from + pg_default_acl d + join + pg_namespace n on d.defaclnamespace = n.oid + cross join lateral aclexplode(d.defaclacl) as a + join + pg_roles r on a.grantee = r.oid + where + a.privilege_type != 'MAINTAIN' -- TODO: this is to maintain compat with pg17, we should cover it + union all + -- explicit grant usage and create on the schemas + select + n.nspname as schema_name, + a.privilege_type, + r.rolname as grantee, + n.nspowner::regrole as default_for, + case when n.nspname = 'public' then 0 else 1 end as schema_order + from + pg_namespace n + cross join lateral aclexplode(n.nspacl) as a + join + pg_roles r on a.grantee = r.oid + where + a.privilege_type in ('CREATE', 'USAGE') +) sub +order by schema_order, schema_name, privilege_type, grantee, default_for; + schema_name | privilege_type | grantee | default_for +--------------------+----------------+--------------------------+--------------------- + public | CREATE | pg_database_owner | pg_database_owner + public | DELETE | anon | supabase_admin + public | DELETE | anon | postgres + public | DELETE | authenticated | supabase_admin + public | DELETE | authenticated | postgres + public | DELETE | postgres | supabase_admin + public | DELETE | postgres | postgres + public | DELETE | service_role | supabase_admin + public | DELETE | service_role | postgres + public | EXECUTE | anon | supabase_admin + public | EXECUTE | anon | postgres + public | EXECUTE | authenticated | supabase_admin + public | EXECUTE | authenticated | postgres + public | EXECUTE | postgres | supabase_admin + public | EXECUTE | postgres | postgres + public | EXECUTE | service_role | supabase_admin + public | EXECUTE | service_role | postgres + public | INSERT | anon | supabase_admin + public | INSERT | anon | postgres + public | INSERT | authenticated | supabase_admin + public | INSERT | authenticated | postgres + public | INSERT | postgres | supabase_admin + public | INSERT | postgres | postgres + public | INSERT | service_role | supabase_admin + public | INSERT | service_role | postgres + public | REFERENCES | anon | supabase_admin + public | REFERENCES | anon | postgres + public | REFERENCES | authenticated | supabase_admin + public | REFERENCES | authenticated | postgres + public | REFERENCES | postgres | supabase_admin + public | REFERENCES | postgres | postgres + public | REFERENCES | service_role | supabase_admin + public | REFERENCES | service_role | postgres + public | SELECT | anon | supabase_admin + public | SELECT | anon | supabase_admin + public | SELECT | anon | postgres + public | SELECT | anon | postgres + public | SELECT | authenticated | supabase_admin + public | SELECT | authenticated | supabase_admin + public | SELECT | authenticated | postgres + public | SELECT | authenticated | postgres + public | SELECT | postgres | supabase_admin + public | SELECT | postgres | supabase_admin + public | SELECT | postgres | postgres + public | SELECT | postgres | postgres + public | SELECT | service_role | supabase_admin + public | SELECT | service_role | supabase_admin + public | SELECT | service_role | postgres + public | SELECT | service_role | postgres + public | TRIGGER | anon | supabase_admin + public | TRIGGER | anon | postgres + public | TRIGGER | authenticated | supabase_admin + public | TRIGGER | authenticated | postgres + public | TRIGGER | postgres | supabase_admin + public | TRIGGER | postgres | postgres + public | TRIGGER | service_role | supabase_admin + public | TRIGGER | service_role | postgres + public | TRUNCATE | anon | supabase_admin + public | TRUNCATE | anon | postgres + public | TRUNCATE | authenticated | supabase_admin + public | TRUNCATE | authenticated | postgres + public | TRUNCATE | postgres | supabase_admin + public | TRUNCATE | postgres | postgres + public | TRUNCATE | service_role | supabase_admin + public | TRUNCATE | service_role | postgres + public | UPDATE | anon | supabase_admin + public | UPDATE | anon | supabase_admin + public | UPDATE | anon | postgres + public | UPDATE | anon | postgres + public | UPDATE | authenticated | supabase_admin + public | UPDATE | authenticated | supabase_admin + public | UPDATE | authenticated | postgres + public | UPDATE | authenticated | postgres + public | UPDATE | postgres | supabase_admin + public | UPDATE | postgres | supabase_admin + public | UPDATE | postgres | postgres + public | UPDATE | postgres | postgres + public | UPDATE | service_role | supabase_admin + public | UPDATE | service_role | supabase_admin + public | UPDATE | service_role | postgres + public | UPDATE | service_role | postgres + public | USAGE | anon | supabase_admin + public | USAGE | anon | pg_database_owner + public | USAGE | anon | postgres + public | USAGE | authenticated | supabase_admin + public | USAGE | authenticated | pg_database_owner + public | USAGE | authenticated | postgres + public | USAGE | pg_database_owner | pg_database_owner + public | USAGE | postgres | supabase_admin + public | USAGE | postgres | pg_database_owner + public | USAGE | postgres | postgres + public | USAGE | service_role | supabase_admin + public | USAGE | service_role | pg_database_owner + public | USAGE | service_role | postgres + auth | CREATE | dashboard_user | supabase_admin + auth | CREATE | postgres | supabase_admin + auth | CREATE | supabase_admin | supabase_admin + auth | CREATE | supabase_auth_admin | supabase_admin + auth | DELETE | dashboard_user | supabase_auth_admin + auth | DELETE | postgres | supabase_auth_admin + auth | EXECUTE | dashboard_user | supabase_auth_admin + auth | EXECUTE | postgres | supabase_auth_admin + auth | INSERT | dashboard_user | supabase_auth_admin + auth | INSERT | postgres | supabase_auth_admin + auth | REFERENCES | dashboard_user | supabase_auth_admin + auth | REFERENCES | postgres | supabase_auth_admin + auth | SELECT | dashboard_user | supabase_auth_admin + auth | SELECT | dashboard_user | supabase_auth_admin + auth | SELECT | postgres | supabase_auth_admin + auth | SELECT | postgres | supabase_auth_admin + auth | TRIGGER | dashboard_user | supabase_auth_admin + auth | TRIGGER | postgres | supabase_auth_admin + auth | TRUNCATE | dashboard_user | supabase_auth_admin + auth | TRUNCATE | postgres | supabase_auth_admin + auth | UPDATE | dashboard_user | supabase_auth_admin + auth | UPDATE | dashboard_user | supabase_auth_admin + auth | UPDATE | postgres | supabase_auth_admin + auth | UPDATE | postgres | supabase_auth_admin + auth | USAGE | anon | supabase_admin + auth | USAGE | authenticated | supabase_admin + auth | USAGE | dashboard_user | supabase_admin + auth | USAGE | dashboard_user | supabase_auth_admin + auth | USAGE | postgres | supabase_admin + auth | USAGE | postgres | supabase_auth_admin + auth | USAGE | service_role | supabase_admin + auth | USAGE | supabase_admin | supabase_admin + auth | USAGE | supabase_auth_admin | supabase_admin + extensions | CREATE | dashboard_user | postgres + extensions | CREATE | postgres | postgres + extensions | DELETE | postgres | supabase_admin + extensions | EXECUTE | postgres | supabase_admin + extensions | INSERT | postgres | supabase_admin + extensions | REFERENCES | postgres | supabase_admin + extensions | SELECT | postgres | supabase_admin + extensions | SELECT | postgres | supabase_admin + extensions | TRIGGER | postgres | supabase_admin + extensions | TRUNCATE | postgres | supabase_admin + extensions | UPDATE | postgres | supabase_admin + extensions | UPDATE | postgres | supabase_admin + extensions | USAGE | anon | postgres + extensions | USAGE | authenticated | postgres + extensions | USAGE | dashboard_user | postgres + extensions | USAGE | postgres | supabase_admin + extensions | USAGE | postgres | postgres + extensions | USAGE | service_role | postgres + graphql | CREATE | supabase_admin | supabase_admin + graphql | DELETE | anon | supabase_admin + graphql | DELETE | authenticated | supabase_admin + graphql | DELETE | postgres | supabase_admin + graphql | DELETE | service_role | supabase_admin + graphql | EXECUTE | anon | supabase_admin + graphql | EXECUTE | authenticated | supabase_admin + graphql | EXECUTE | postgres | supabase_admin + graphql | EXECUTE | service_role | supabase_admin + graphql | INSERT | anon | supabase_admin + graphql | INSERT | authenticated | supabase_admin + graphql | INSERT | postgres | supabase_admin + graphql | INSERT | service_role | supabase_admin + graphql | REFERENCES | anon | supabase_admin + graphql | REFERENCES | authenticated | supabase_admin + graphql | REFERENCES | postgres | supabase_admin + graphql | REFERENCES | service_role | supabase_admin + graphql | SELECT | anon | supabase_admin + graphql | SELECT | anon | supabase_admin + graphql | SELECT | authenticated | supabase_admin + graphql | SELECT | authenticated | supabase_admin + graphql | SELECT | postgres | supabase_admin + graphql | SELECT | postgres | supabase_admin + graphql | SELECT | service_role | supabase_admin + graphql | SELECT | service_role | supabase_admin + graphql | TRIGGER | anon | supabase_admin + graphql | TRIGGER | authenticated | supabase_admin + graphql | TRIGGER | postgres | supabase_admin + graphql | TRIGGER | service_role | supabase_admin + graphql | TRUNCATE | anon | supabase_admin + graphql | TRUNCATE | authenticated | supabase_admin + graphql | TRUNCATE | postgres | supabase_admin + graphql | TRUNCATE | service_role | supabase_admin + graphql | UPDATE | anon | supabase_admin + graphql | UPDATE | anon | supabase_admin + graphql | UPDATE | authenticated | supabase_admin + graphql | UPDATE | authenticated | supabase_admin + graphql | UPDATE | postgres | supabase_admin + graphql | UPDATE | postgres | supabase_admin + graphql | UPDATE | service_role | supabase_admin + graphql | UPDATE | service_role | supabase_admin + graphql | USAGE | anon | supabase_admin + graphql | USAGE | anon | supabase_admin + graphql | USAGE | authenticated | supabase_admin + graphql | USAGE | authenticated | supabase_admin + graphql | USAGE | postgres | supabase_admin + graphql | USAGE | postgres | supabase_admin + graphql | USAGE | service_role | supabase_admin + graphql | USAGE | service_role | supabase_admin + graphql | USAGE | supabase_admin | supabase_admin + graphql_public | CREATE | supabase_admin | supabase_admin + graphql_public | DELETE | anon | supabase_admin + graphql_public | DELETE | authenticated | supabase_admin + graphql_public | DELETE | postgres | supabase_admin + graphql_public | DELETE | service_role | supabase_admin + graphql_public | EXECUTE | anon | supabase_admin + graphql_public | EXECUTE | authenticated | supabase_admin + graphql_public | EXECUTE | postgres | supabase_admin + graphql_public | EXECUTE | service_role | supabase_admin + graphql_public | INSERT | anon | supabase_admin + graphql_public | INSERT | authenticated | supabase_admin + graphql_public | INSERT | postgres | supabase_admin + graphql_public | INSERT | service_role | supabase_admin + graphql_public | REFERENCES | anon | supabase_admin + graphql_public | REFERENCES | authenticated | supabase_admin + graphql_public | REFERENCES | postgres | supabase_admin + graphql_public | REFERENCES | service_role | supabase_admin + graphql_public | SELECT | anon | supabase_admin + graphql_public | SELECT | anon | supabase_admin + graphql_public | SELECT | authenticated | supabase_admin + graphql_public | SELECT | authenticated | supabase_admin + graphql_public | SELECT | postgres | supabase_admin + graphql_public | SELECT | postgres | supabase_admin + graphql_public | SELECT | service_role | supabase_admin + graphql_public | SELECT | service_role | supabase_admin + graphql_public | TRIGGER | anon | supabase_admin + graphql_public | TRIGGER | authenticated | supabase_admin + graphql_public | TRIGGER | postgres | supabase_admin + graphql_public | TRIGGER | service_role | supabase_admin + graphql_public | TRUNCATE | anon | supabase_admin + graphql_public | TRUNCATE | authenticated | supabase_admin + graphql_public | TRUNCATE | postgres | supabase_admin + graphql_public | TRUNCATE | service_role | supabase_admin + graphql_public | UPDATE | anon | supabase_admin + graphql_public | UPDATE | anon | supabase_admin + graphql_public | UPDATE | authenticated | supabase_admin + graphql_public | UPDATE | authenticated | supabase_admin + graphql_public | UPDATE | postgres | supabase_admin + graphql_public | UPDATE | postgres | supabase_admin + graphql_public | UPDATE | service_role | supabase_admin + graphql_public | UPDATE | service_role | supabase_admin + graphql_public | USAGE | anon | supabase_admin + graphql_public | USAGE | anon | supabase_admin + graphql_public | USAGE | authenticated | supabase_admin + graphql_public | USAGE | authenticated | supabase_admin + graphql_public | USAGE | postgres | supabase_admin + graphql_public | USAGE | postgres | supabase_admin + graphql_public | USAGE | service_role | supabase_admin + graphql_public | USAGE | service_role | supabase_admin + graphql_public | USAGE | supabase_admin | supabase_admin + information_schema | CREATE | supabase_admin | supabase_admin + information_schema | USAGE | supabase_admin | supabase_admin + net | CREATE | supabase_admin | supabase_admin + net | USAGE | anon | supabase_admin + net | USAGE | authenticated | supabase_admin + net | USAGE | postgres | supabase_admin + net | USAGE | service_role | supabase_admin + net | USAGE | supabase_admin | supabase_admin + net | USAGE | supabase_functions_admin | supabase_admin + pg_catalog | CREATE | supabase_admin | supabase_admin + pg_catalog | USAGE | supabase_admin | supabase_admin + pgmq | CREATE | supabase_admin | supabase_admin + pgmq | SELECT | pg_monitor | supabase_admin + pgmq | SELECT | pg_monitor | supabase_admin + pgmq | USAGE | pg_monitor | supabase_admin + pgmq | USAGE | supabase_admin | supabase_admin + pgsodium | CREATE | supabase_admin | supabase_admin + pgsodium | DELETE | pgsodium_keyholder | supabase_admin + pgsodium | INSERT | pgsodium_keyholder | supabase_admin + pgsodium | REFERENCES | pgsodium_keyholder | supabase_admin + pgsodium | SELECT | pgsodium_keyholder | supabase_admin + pgsodium | SELECT | pgsodium_keyholder | supabase_admin + pgsodium | TRIGGER | pgsodium_keyholder | supabase_admin + pgsodium | TRUNCATE | pgsodium_keyholder | supabase_admin + pgsodium | UPDATE | pgsodium_keyholder | supabase_admin + pgsodium | UPDATE | pgsodium_keyholder | supabase_admin + pgsodium | USAGE | pgsodium_keyholder | supabase_admin + pgsodium | USAGE | supabase_admin | supabase_admin + pgsodium_masks | CREATE | supabase_admin | supabase_admin + pgsodium_masks | DELETE | pgsodium_keyiduser | supabase_admin + pgsodium_masks | EXECUTE | pgsodium_keyiduser | supabase_admin + pgsodium_masks | INSERT | pgsodium_keyiduser | supabase_admin + pgsodium_masks | REFERENCES | pgsodium_keyiduser | supabase_admin + pgsodium_masks | SELECT | pgsodium_keyiduser | supabase_admin + pgsodium_masks | SELECT | pgsodium_keyiduser | supabase_admin + pgsodium_masks | TRIGGER | pgsodium_keyiduser | supabase_admin + pgsodium_masks | TRUNCATE | pgsodium_keyiduser | supabase_admin + pgsodium_masks | UPDATE | pgsodium_keyiduser | supabase_admin + pgsodium_masks | UPDATE | pgsodium_keyiduser | supabase_admin + pgsodium_masks | USAGE | pgsodium_keyiduser | supabase_admin + pgsodium_masks | USAGE | pgsodium_keyiduser | supabase_admin + pgsodium_masks | USAGE | supabase_admin | supabase_admin + pgtle | CREATE | pgtle_admin | supabase_admin + pgtle | CREATE | supabase_admin | supabase_admin + pgtle | USAGE | pgtle_admin | supabase_admin + pgtle | USAGE | supabase_admin | supabase_admin + realtime | CREATE | supabase_admin | supabase_admin + realtime | DELETE | dashboard_user | supabase_admin + realtime | DELETE | postgres | supabase_admin + realtime | EXECUTE | dashboard_user | supabase_admin + realtime | EXECUTE | postgres | supabase_admin + realtime | INSERT | dashboard_user | supabase_admin + realtime | INSERT | postgres | supabase_admin + realtime | REFERENCES | dashboard_user | supabase_admin + realtime | REFERENCES | postgres | supabase_admin + realtime | SELECT | dashboard_user | supabase_admin + realtime | SELECT | dashboard_user | supabase_admin + realtime | SELECT | postgres | supabase_admin + realtime | SELECT | postgres | supabase_admin + realtime | TRIGGER | dashboard_user | supabase_admin + realtime | TRIGGER | postgres | supabase_admin + realtime | TRUNCATE | dashboard_user | supabase_admin + realtime | TRUNCATE | postgres | supabase_admin + realtime | UPDATE | dashboard_user | supabase_admin + realtime | UPDATE | dashboard_user | supabase_admin + realtime | UPDATE | postgres | supabase_admin + realtime | UPDATE | postgres | supabase_admin + realtime | USAGE | dashboard_user | supabase_admin + realtime | USAGE | postgres | supabase_admin + realtime | USAGE | postgres | supabase_admin + realtime | USAGE | supabase_admin | supabase_admin + repack | CREATE | postgres | supabase_admin + repack | CREATE | supabase_admin | supabase_admin + repack | DELETE | postgres | supabase_admin + repack | INSERT | postgres | supabase_admin + repack | REFERENCES | postgres | supabase_admin + repack | SELECT | postgres | supabase_admin + repack | SELECT | postgres | supabase_admin + repack | TRIGGER | postgres | supabase_admin + repack | TRUNCATE | postgres | supabase_admin + repack | UPDATE | postgres | supabase_admin + repack | UPDATE | postgres | supabase_admin + repack | USAGE | postgres | supabase_admin + repack | USAGE | postgres | supabase_admin + repack | USAGE | supabase_admin | supabase_admin + storage | CREATE | dashboard_user | supabase_admin + storage | CREATE | postgres | supabase_admin + storage | CREATE | supabase_admin | supabase_admin + storage | CREATE | supabase_storage_admin | supabase_admin + storage | DELETE | anon | postgres + storage | DELETE | authenticated | postgres + storage | DELETE | postgres | postgres + storage | DELETE | service_role | postgres + storage | EXECUTE | anon | postgres + storage | EXECUTE | authenticated | postgres + storage | EXECUTE | postgres | postgres + storage | EXECUTE | service_role | postgres + storage | INSERT | anon | postgres + storage | INSERT | authenticated | postgres + storage | INSERT | postgres | postgres + storage | INSERT | service_role | postgres + storage | REFERENCES | anon | postgres + storage | REFERENCES | authenticated | postgres + storage | REFERENCES | postgres | postgres + storage | REFERENCES | service_role | postgres + storage | SELECT | anon | postgres + storage | SELECT | anon | postgres + storage | SELECT | authenticated | postgres + storage | SELECT | authenticated | postgres + storage | SELECT | postgres | postgres + storage | SELECT | postgres | postgres + storage | SELECT | service_role | postgres + storage | SELECT | service_role | postgres + storage | TRIGGER | anon | postgres + storage | TRIGGER | authenticated | postgres + storage | TRIGGER | postgres | postgres + storage | TRIGGER | service_role | postgres + storage | TRUNCATE | anon | postgres + storage | TRUNCATE | authenticated | postgres + storage | TRUNCATE | postgres | postgres + storage | TRUNCATE | service_role | postgres + storage | UPDATE | anon | postgres + storage | UPDATE | anon | postgres + storage | UPDATE | authenticated | postgres + storage | UPDATE | authenticated | postgres + storage | UPDATE | postgres | postgres + storage | UPDATE | postgres | postgres + storage | UPDATE | service_role | postgres + storage | UPDATE | service_role | postgres + storage | USAGE | anon | supabase_admin + storage | USAGE | anon | postgres + storage | USAGE | authenticated | supabase_admin + storage | USAGE | authenticated | postgres + storage | USAGE | dashboard_user | supabase_admin + storage | USAGE | postgres | supabase_admin + storage | USAGE | postgres | postgres + storage | USAGE | service_role | supabase_admin + storage | USAGE | service_role | postgres + storage | USAGE | supabase_admin | supabase_admin + storage | USAGE | supabase_storage_admin | supabase_admin + topology | CREATE | supabase_admin | supabase_admin + topology | USAGE | supabase_admin | supabase_admin + vault | CREATE | supabase_admin | supabase_admin + vault | USAGE | postgres | supabase_admin + vault | USAGE | supabase_admin | supabase_admin +(390 rows) + diff --git a/nix/tests/expected/storage.out b/nix/tests/expected/storage.out index 755e6c516..018b98aae 100644 --- a/nix/tests/expected/storage.out +++ b/nix/tests/expected/storage.out @@ -13,33 +13,6 @@ where storage | supabase_admin (1 row) --- attributes of the supabase_storage_admin -select - rolcreaterole , - rolcanlogin , - rolsuper , - rolinherit , - rolcreatedb , - rolreplication , - rolconnlimit , - rolbypassrls , - rolvaliduntil -from pg_roles r -where r.rolname = 'supabase_storage_admin'; - rolcreaterole | rolcanlogin | rolsuper | rolinherit | rolcreatedb | rolreplication | rolconnlimit | rolbypassrls | rolvaliduntil ----------------+-------------+----------+------------+-------------+----------------+--------------+--------------+--------------- - t | t | f | f | f | f | -1 | f | -(1 row) - -select - rolconfig -from pg_roles r -where r.rolname = 'supabase_storage_admin'; - rolconfig ------------------------------------------- - {search_path=storage,log_statement=none} -(1 row) - -- storage schema tables with owners and rls policies select ns.nspname as schema_name, @@ -123,52 +96,3 @@ order by storage | search | supabase_storage_admin (4 rows) --- roles which have USAGE on the storage schema -select - n.nspname as schema_name, - r.rolname as role_name, - a.privilege_type -from - pg_namespace n -cross join lateral aclexplode(n.nspacl) as a -join - pg_roles r on a.grantee = r.oid -where - n.nspname = 'storage' - and a.privilege_type = 'USAGE' -order by - r.rolname; - schema_name | role_name | privilege_type --------------+------------------------+---------------- - storage | anon | USAGE - storage | authenticated | USAGE - storage | dashboard_user | USAGE - storage | postgres | USAGE - storage | service_role | USAGE - storage | supabase_admin | USAGE - storage | supabase_storage_admin | USAGE -(7 rows) - --- roles which have CREATE on the storage schema -select - n.nspname as schema_name, - r.rolname as role_name, - a.privilege_type -from - pg_namespace n -cross join lateral aclexplode(n.nspacl) as a -join - pg_roles r on a.grantee = r.oid -where - n.nspname = 'storage' - and a.privilege_type = 'CREATE' -order by - r.rolname; - schema_name | role_name | privilege_type --------------+------------------------+---------------- - storage | dashboard_user | CREATE - storage | postgres | CREATE - storage | supabase_admin | CREATE - storage | supabase_storage_admin | CREATE -(4 rows) - diff --git a/nix/tests/sql/auth.sql b/nix/tests/sql/auth.sql index 47e2931ae..051d6e638 100644 --- a/nix/tests/sql/auth.sql +++ b/nix/tests/sql/auth.sql @@ -9,25 +9,6 @@ join where n.nspname = 'auth'; --- attributes of the supabase_auth_admin -select - rolcreaterole , - rolcanlogin , - rolsuper , - rolinherit , - rolcreatedb , - rolreplication , - rolconnlimit , - rolbypassrls , - rolvaliduntil -from pg_roles r -where r.rolname = 'supabase_auth_admin'; - -select - rolconfig -from pg_roles r -where r.rolname = 'supabase_auth_admin'; - -- auth schema tables with owners and rls policies select ns.nspname as schema_name, @@ -87,35 +68,3 @@ where n.nspname = 'auth' order by p.proname; - --- roles which have USAGE on the auth schema -select - n.nspname as schema_name, - r.rolname as role_name, - a.privilege_type -from - pg_namespace n -cross join lateral aclexplode(n.nspacl) as a -join - pg_roles r on a.grantee = r.oid -where - n.nspname = 'auth' - and a.privilege_type = 'USAGE' -order by - r.rolname; - --- roles which have CREATE on the auth schema -select - n.nspname as schema_name, - r.rolname as role_name, - a.privilege_type -from - pg_namespace n -cross join lateral aclexplode(n.nspacl) as a -join - pg_roles r on a.grantee = r.oid -where - n.nspname = 'auth' - and a.privilege_type = 'CREATE' -order by - r.rolname; diff --git a/nix/tests/sql/default_privs.sql b/nix/tests/sql/default_privs.sql deleted file mode 100644 index 5df2629b9..000000000 --- a/nix/tests/sql/default_privs.sql +++ /dev/null @@ -1,2 +0,0 @@ --- this tests the outcome of doing ALTER DEFAULT PRIVILEGES.. -select defaclrole::regrole, defaclnamespace::regnamespace, defaclobjtype from pg_default_acl where defaclnamespace = 'public'::regnamespace::oid order by defaclrole::regrole, defaclobjtype; diff --git a/nix/tests/sql/roles.sql b/nix/tests/sql/roles.sql new file mode 100644 index 000000000..9e68a171a --- /dev/null +++ b/nix/tests/sql/roles.sql @@ -0,0 +1,77 @@ +-- all roles and attributes +select + rolname, + rolcreaterole , + rolcanlogin , + rolsuper , + rolinherit , + rolcreatedb , + rolreplication , + rolconnlimit , + rolbypassrls , + rolvaliduntil +from pg_roles r +-- TODO: this exclusion is to maintain compat with pg17, we should cover it +where rolname not in ('pg_create_subscription', 'pg_maintain', 'pg_use_reserved_connections') +order by rolname; + +select + rolname, + rolconfig +from pg_roles r +-- TODO: this exclusion is to maintain compat with pg17, we should cover it +where rolname not in ('pg_create_subscription', 'pg_maintain', 'pg_use_reserved_connections') +order by rolname; + +-- all role memberships +select + r.rolname as member, + g.rolname as "member_of (can become)", + m.admin_option +from + pg_roles r +left join + pg_auth_members m on r.oid = m.member +left join + pg_roles g on m.roleid = g.oid +-- TODO: this exclusion is to maintain compat with pg17, we should cover it +where r.rolname not in ('pg_create_subscription', 'pg_maintain', 'pg_use_reserved_connections') +order by + r.rolname, g.rolname; + +-- Check all privileges of the roles on the schemas +select schema_name, privilege_type, grantee, default_for +from ( + -- ALTER DEFAULT privileges on schemas + select + n.nspname as schema_name, + a.privilege_type, + r.rolname as grantee, + d.defaclrole::regrole as default_for, + case when n.nspname = 'public' then 0 else 1 end as schema_order + from + pg_default_acl d + join + pg_namespace n on d.defaclnamespace = n.oid + cross join lateral aclexplode(d.defaclacl) as a + join + pg_roles r on a.grantee = r.oid + where + a.privilege_type != 'MAINTAIN' -- TODO: this is to maintain compat with pg17, we should cover it + union all + -- explicit grant usage and create on the schemas + select + n.nspname as schema_name, + a.privilege_type, + r.rolname as grantee, + n.nspowner::regrole as default_for, + case when n.nspname = 'public' then 0 else 1 end as schema_order + from + pg_namespace n + cross join lateral aclexplode(n.nspacl) as a + join + pg_roles r on a.grantee = r.oid + where + a.privilege_type in ('CREATE', 'USAGE') +) sub +order by schema_order, schema_name, privilege_type, grantee, default_for; diff --git a/nix/tests/sql/storage.sql b/nix/tests/sql/storage.sql index 5dfd5f0bb..8e52dda6f 100644 --- a/nix/tests/sql/storage.sql +++ b/nix/tests/sql/storage.sql @@ -9,25 +9,6 @@ join where n.nspname = 'storage'; --- attributes of the supabase_storage_admin -select - rolcreaterole , - rolcanlogin , - rolsuper , - rolinherit , - rolcreatedb , - rolreplication , - rolconnlimit , - rolbypassrls , - rolvaliduntil -from pg_roles r -where r.rolname = 'supabase_storage_admin'; - -select - rolconfig -from pg_roles r -where r.rolname = 'supabase_storage_admin'; - -- storage schema tables with owners and rls policies select ns.nspname as schema_name, @@ -87,35 +68,3 @@ where n.nspname = 'storage' order by p.proname; - --- roles which have USAGE on the storage schema -select - n.nspname as schema_name, - r.rolname as role_name, - a.privilege_type -from - pg_namespace n -cross join lateral aclexplode(n.nspacl) as a -join - pg_roles r on a.grantee = r.oid -where - n.nspname = 'storage' - and a.privilege_type = 'USAGE' -order by - r.rolname; - --- roles which have CREATE on the storage schema -select - n.nspname as schema_name, - r.rolname as role_name, - a.privilege_type -from - pg_namespace n -cross join lateral aclexplode(n.nspacl) as a -join - pg_roles r on a.grantee = r.oid -where - n.nspname = 'storage' - and a.privilege_type = 'CREATE' -order by - r.rolname;