Skip to content

test: role privileges on auth/storage db objects #1577

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 30, 2025
Merged
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
132 changes: 132 additions & 0 deletions nix/tests/expected/auth.out
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,138 @@ order by
auth | users | supabase_auth_admin | f |
(5 rows)

-- auth schema objects with roles privileges
select
ns.nspname as schema_name,
c.relname as table_name,
r.rolname as role_name,
a.privilege_type,
a.is_grantable
from
pg_class c
join
pg_namespace ns on c.relnamespace = ns.oid
cross join lateral
aclexplode(c.relacl) as a
join
pg_roles r on a.grantee = r.oid
where
ns.nspname = 'auth'
and c.relkind in ('r', 'v', 'm')
and a.privilege_type <> 'MAINTAIN'
order by
c.relname,
r.rolname,
a.privilege_type;
schema_name | table_name | role_name | privilege_type | is_grantable
-------------+-------------------+---------------------+----------------+--------------
auth | audit_log_entries | dashboard_user | DELETE | f
auth | audit_log_entries | dashboard_user | INSERT | f
auth | audit_log_entries | dashboard_user | REFERENCES | f
auth | audit_log_entries | dashboard_user | SELECT | f
auth | audit_log_entries | dashboard_user | TRIGGER | f
auth | audit_log_entries | dashboard_user | TRUNCATE | f
auth | audit_log_entries | dashboard_user | UPDATE | f
Comment on lines +70 to +78
Copy link
Member Author

@steve-chavez steve-chavez Apr 30, 2025

Choose a reason for hiding this comment

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

Note: these privileges could be compressed to a single line with array_agg, like:

 schema_name |    table_name     |      role_name      |                      privilege_types                      |  is_grantable   
-------------+-------------------+---------------------+-----------------------------------------------------------+-----------------
 auth        | audit_log_entries | dashboard_user      | {DELETE,INSERT,REFERENCES,SELECT,TRIGGER,TRUNCATE,UPDATE} | {f,f,f,f,f,f,f}
 auth        | audit_log_entries | postgres            | {DELETE,INSERT,REFERENCES,SELECT,TRIGGER,TRUNCATE,UPDATE} | {f,f,f,f,f,f,f}
 auth        | audit_log_entries | supabase_auth_admin | {DELETE,INSERT,REFERENCES,SELECT,TRIGGER,TRUNCATE,UPDATE} | {f,f,f,f,f,f,f}

But then once a test fails is hard to visualize the privileges diff. (case in point: just happened to me with the new MAINTAIN privilege on pg 17, had a previous version with compressed privs and that was hard to visualize, wasted some time there).

auth | audit_log_entries | postgres | DELETE | f
auth | audit_log_entries | postgres | INSERT | f
auth | audit_log_entries | postgres | REFERENCES | f
auth | audit_log_entries | postgres | SELECT | f
auth | audit_log_entries | postgres | TRIGGER | f
auth | audit_log_entries | postgres | TRUNCATE | f
auth | audit_log_entries | postgres | UPDATE | f
auth | audit_log_entries | supabase_auth_admin | DELETE | f
auth | audit_log_entries | supabase_auth_admin | INSERT | f
auth | audit_log_entries | supabase_auth_admin | REFERENCES | f
auth | audit_log_entries | supabase_auth_admin | SELECT | f
auth | audit_log_entries | supabase_auth_admin | TRIGGER | f
auth | audit_log_entries | supabase_auth_admin | TRUNCATE | f
auth | audit_log_entries | supabase_auth_admin | UPDATE | f
auth | instances | dashboard_user | DELETE | f
auth | instances | dashboard_user | INSERT | f
auth | instances | dashboard_user | REFERENCES | f
auth | instances | dashboard_user | SELECT | f
auth | instances | dashboard_user | TRIGGER | f
auth | instances | dashboard_user | TRUNCATE | f
auth | instances | dashboard_user | UPDATE | f
auth | instances | postgres | DELETE | f
auth | instances | postgres | INSERT | f
auth | instances | postgres | REFERENCES | f
auth | instances | postgres | SELECT | f
auth | instances | postgres | TRIGGER | f
auth | instances | postgres | TRUNCATE | f
auth | instances | postgres | UPDATE | f
auth | instances | supabase_auth_admin | DELETE | f
auth | instances | supabase_auth_admin | INSERT | f
auth | instances | supabase_auth_admin | REFERENCES | f
auth | instances | supabase_auth_admin | SELECT | f
auth | instances | supabase_auth_admin | TRIGGER | f
auth | instances | supabase_auth_admin | TRUNCATE | f
auth | instances | supabase_auth_admin | UPDATE | f
auth | refresh_tokens | dashboard_user | DELETE | f
auth | refresh_tokens | dashboard_user | INSERT | f
auth | refresh_tokens | dashboard_user | REFERENCES | f
auth | refresh_tokens | dashboard_user | SELECT | f
auth | refresh_tokens | dashboard_user | TRIGGER | f
auth | refresh_tokens | dashboard_user | TRUNCATE | f
auth | refresh_tokens | dashboard_user | UPDATE | f
auth | refresh_tokens | postgres | DELETE | f
auth | refresh_tokens | postgres | INSERT | f
auth | refresh_tokens | postgres | REFERENCES | f
auth | refresh_tokens | postgres | SELECT | f
auth | refresh_tokens | postgres | TRIGGER | f
auth | refresh_tokens | postgres | TRUNCATE | f
auth | refresh_tokens | postgres | UPDATE | f
auth | refresh_tokens | supabase_auth_admin | DELETE | f
auth | refresh_tokens | supabase_auth_admin | INSERT | f
auth | refresh_tokens | supabase_auth_admin | REFERENCES | f
auth | refresh_tokens | supabase_auth_admin | SELECT | f
auth | refresh_tokens | supabase_auth_admin | TRIGGER | f
auth | refresh_tokens | supabase_auth_admin | TRUNCATE | f
auth | refresh_tokens | supabase_auth_admin | UPDATE | f
auth | schema_migrations | dashboard_user | DELETE | f
auth | schema_migrations | dashboard_user | INSERT | f
auth | schema_migrations | dashboard_user | REFERENCES | f
auth | schema_migrations | dashboard_user | SELECT | f
auth | schema_migrations | dashboard_user | TRIGGER | f
auth | schema_migrations | dashboard_user | TRUNCATE | f
auth | schema_migrations | dashboard_user | UPDATE | f
auth | schema_migrations | postgres | DELETE | f
auth | schema_migrations | postgres | INSERT | f
auth | schema_migrations | postgres | REFERENCES | f
auth | schema_migrations | postgres | SELECT | f
auth | schema_migrations | postgres | TRIGGER | f
auth | schema_migrations | postgres | TRUNCATE | f
auth | schema_migrations | postgres | UPDATE | f
auth | schema_migrations | supabase_auth_admin | DELETE | f
auth | schema_migrations | supabase_auth_admin | INSERT | f
auth | schema_migrations | supabase_auth_admin | REFERENCES | f
auth | schema_migrations | supabase_auth_admin | SELECT | f
auth | schema_migrations | supabase_auth_admin | TRIGGER | f
auth | schema_migrations | supabase_auth_admin | TRUNCATE | f
auth | schema_migrations | supabase_auth_admin | UPDATE | f
auth | users | dashboard_user | DELETE | f
auth | users | dashboard_user | INSERT | f
auth | users | dashboard_user | REFERENCES | f
auth | users | dashboard_user | SELECT | f
auth | users | dashboard_user | TRIGGER | f
auth | users | dashboard_user | TRUNCATE | f
auth | users | dashboard_user | UPDATE | f
auth | users | postgres | DELETE | f
auth | users | postgres | INSERT | f
auth | users | postgres | REFERENCES | f
auth | users | postgres | SELECT | f
auth | users | postgres | TRIGGER | f
auth | users | postgres | TRUNCATE | f
auth | users | postgres | UPDATE | f
auth | users | supabase_auth_admin | DELETE | f
auth | users | supabase_auth_admin | INSERT | f
auth | users | supabase_auth_admin | REFERENCES | f
auth | users | supabase_auth_admin | SELECT | f
auth | users | supabase_auth_admin | TRIGGER | f
auth | users | supabase_auth_admin | TRUNCATE | f
auth | users | supabase_auth_admin | UPDATE | f
(105 rows)

-- auth indexes with owners
select
ns.nspname as table_schema,
Expand Down
132 changes: 132 additions & 0 deletions nix/tests/expected/storage.out
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,138 @@ order by
storage | objects | supabase_storage_admin | t |
(3 rows)

-- storage schema objects with roles privileges
select
ns.nspname as schema_name,
c.relname as table_name,
r.rolname as role_name,
a.privilege_type,
a.is_grantable
from
pg_class c
join
pg_namespace ns on c.relnamespace = ns.oid
cross join lateral
aclexplode(c.relacl) as a
join
pg_roles r on a.grantee = r.oid
where
ns.nspname = 'storage'
and c.relkind in ('r', 'v', 'm')
and a.privilege_type <> 'MAINTAIN'
order by
c.relname,
r.rolname,
a.privilege_type;
schema_name | table_name | role_name | privilege_type | is_grantable
-------------+------------+------------------------+----------------+--------------
storage | buckets | anon | DELETE | f
storage | buckets | anon | INSERT | f
storage | buckets | anon | REFERENCES | f
storage | buckets | anon | SELECT | f
storage | buckets | anon | TRIGGER | f
storage | buckets | anon | TRUNCATE | f
storage | buckets | anon | UPDATE | f
storage | buckets | authenticated | DELETE | f
storage | buckets | authenticated | INSERT | f
storage | buckets | authenticated | REFERENCES | f
storage | buckets | authenticated | SELECT | f
storage | buckets | authenticated | TRIGGER | f
storage | buckets | authenticated | TRUNCATE | f
storage | buckets | authenticated | UPDATE | f
storage | buckets | postgres | DELETE | f
storage | buckets | postgres | INSERT | f
storage | buckets | postgres | REFERENCES | f
storage | buckets | postgres | SELECT | f
storage | buckets | postgres | TRIGGER | f
storage | buckets | postgres | TRUNCATE | f
storage | buckets | postgres | UPDATE | f
storage | buckets | service_role | DELETE | f
storage | buckets | service_role | INSERT | f
storage | buckets | service_role | REFERENCES | f
storage | buckets | service_role | SELECT | f
storage | buckets | service_role | TRIGGER | f
storage | buckets | service_role | TRUNCATE | f
storage | buckets | service_role | UPDATE | f
storage | buckets | supabase_storage_admin | DELETE | f
storage | buckets | supabase_storage_admin | INSERT | f
storage | buckets | supabase_storage_admin | REFERENCES | f
storage | buckets | supabase_storage_admin | SELECT | f
storage | buckets | supabase_storage_admin | TRIGGER | f
storage | buckets | supabase_storage_admin | TRUNCATE | f
storage | buckets | supabase_storage_admin | UPDATE | f
storage | migrations | anon | DELETE | f
storage | migrations | anon | INSERT | f
storage | migrations | anon | REFERENCES | f
storage | migrations | anon | SELECT | f
storage | migrations | anon | TRIGGER | f
storage | migrations | anon | TRUNCATE | f
storage | migrations | anon | UPDATE | f
storage | migrations | authenticated | DELETE | f
storage | migrations | authenticated | INSERT | f
storage | migrations | authenticated | REFERENCES | f
storage | migrations | authenticated | SELECT | f
storage | migrations | authenticated | TRIGGER | f
storage | migrations | authenticated | TRUNCATE | f
storage | migrations | authenticated | UPDATE | f
storage | migrations | postgres | DELETE | f
storage | migrations | postgres | INSERT | f
storage | migrations | postgres | REFERENCES | f
storage | migrations | postgres | SELECT | f
storage | migrations | postgres | TRIGGER | f
storage | migrations | postgres | TRUNCATE | f
storage | migrations | postgres | UPDATE | f
storage | migrations | service_role | DELETE | f
storage | migrations | service_role | INSERT | f
storage | migrations | service_role | REFERENCES | f
storage | migrations | service_role | SELECT | f
storage | migrations | service_role | TRIGGER | f
storage | migrations | service_role | TRUNCATE | f
storage | migrations | service_role | UPDATE | f
storage | migrations | supabase_storage_admin | DELETE | f
storage | migrations | supabase_storage_admin | INSERT | f
storage | migrations | supabase_storage_admin | REFERENCES | f
storage | migrations | supabase_storage_admin | SELECT | f
storage | migrations | supabase_storage_admin | TRIGGER | f
storage | migrations | supabase_storage_admin | TRUNCATE | f
storage | migrations | supabase_storage_admin | UPDATE | f
storage | objects | anon | DELETE | f
storage | objects | anon | INSERT | f
storage | objects | anon | REFERENCES | f
storage | objects | anon | SELECT | f
storage | objects | anon | TRIGGER | f
storage | objects | anon | TRUNCATE | f
storage | objects | anon | UPDATE | f
storage | objects | authenticated | DELETE | f
storage | objects | authenticated | INSERT | f
storage | objects | authenticated | REFERENCES | f
storage | objects | authenticated | SELECT | f
storage | objects | authenticated | TRIGGER | f
storage | objects | authenticated | TRUNCATE | f
storage | objects | authenticated | UPDATE | f
storage | objects | postgres | DELETE | f
storage | objects | postgres | INSERT | f
storage | objects | postgres | REFERENCES | f
storage | objects | postgres | SELECT | f
storage | objects | postgres | TRIGGER | f
storage | objects | postgres | TRUNCATE | f
storage | objects | postgres | UPDATE | f
storage | objects | service_role | DELETE | f
storage | objects | service_role | INSERT | f
storage | objects | service_role | REFERENCES | f
storage | objects | service_role | SELECT | f
storage | objects | service_role | TRIGGER | f
storage | objects | service_role | TRUNCATE | f
storage | objects | service_role | UPDATE | f
storage | objects | supabase_storage_admin | DELETE | f
storage | objects | supabase_storage_admin | INSERT | f
storage | objects | supabase_storage_admin | REFERENCES | f
storage | objects | supabase_storage_admin | SELECT | f
storage | objects | supabase_storage_admin | TRIGGER | f
storage | objects | supabase_storage_admin | TRUNCATE | f
storage | objects | supabase_storage_admin | UPDATE | f
(105 rows)

-- storage indexes with owners
select
ns.nspname as table_schema,
Expand Down
24 changes: 24 additions & 0 deletions nix/tests/sql/auth.sql
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,30 @@ group by
order by
c.relname;

-- auth schema objects with roles privileges
select
ns.nspname as schema_name,
c.relname as table_name,
r.rolname as role_name,
a.privilege_type,
a.is_grantable
from
pg_class c
join
pg_namespace ns on c.relnamespace = ns.oid
cross join lateral
aclexplode(c.relacl) as a
join
pg_roles r on a.grantee = r.oid
where
ns.nspname = 'auth'
and c.relkind in ('r', 'v', 'm')
and a.privilege_type <> 'MAINTAIN'
order by
c.relname,
r.rolname,
a.privilege_type;

-- auth indexes with owners
select
ns.nspname as table_schema,
Expand Down
24 changes: 24 additions & 0 deletions nix/tests/sql/storage.sql
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,30 @@ group by
order by
c.relname;

-- storage schema objects with roles privileges
select
ns.nspname as schema_name,
c.relname as table_name,
r.rolname as role_name,
a.privilege_type,
a.is_grantable
from
pg_class c
join
pg_namespace ns on c.relnamespace = ns.oid
cross join lateral
aclexplode(c.relacl) as a
join
pg_roles r on a.grantee = r.oid
where
ns.nspname = 'storage'
and c.relkind in ('r', 'v', 'm')
and a.privilege_type <> 'MAINTAIN'
order by
c.relname,
r.rolname,
a.privilege_type;

-- storage indexes with owners
select
ns.nspname as table_schema,
Expand Down
Loading