Skip to content
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
4 changes: 2 additions & 2 deletions bin/installcheck
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export PGDATABASE=postgres
export PGTZ=UTC
export PG_COLOR=auto

#PATH=~/.pgrx/16.6/pgrx-install/bin/:$PATH
# PATH=~/.pgrx/16.6/pgrx-install/bin/:$PATH

####################
# Ensure Clean Env #
Expand Down Expand Up @@ -52,7 +52,7 @@ else
fi

# Execute the test fixtures
psql -v ON_ERROR_STOP= -f test/fixtures.sql -f lints/0001*.sql -f lints/0002*.sql -f lints/0003*.sql -f lints/0004*.sql -f lints/0005*.sql -f lints/0006*.sql -f lints/0007*.sql -f lints/0008*.sql -f lints/0009*.sql -f lints/0010*.sql -f lints/0011*.sql -f lints/0013*.sql -f lints/0014*.sql -f lints/0015*.sql -f lints/0016*.sql -f lints/0017*.sql -f lints/0018*.sql -f lints/0019*.sql -f lints/0020*.sql -d contrib_regression
psql -v ON_ERROR_STOP= -f test/fixtures.sql -f lints/0001*.sql -f lints/0002*.sql -f lints/0003*.sql -f lints/0004*.sql -f lints/0005*.sql -f lints/0006*.sql -f lints/0007*.sql -f lints/0008*.sql -f lints/0009*.sql -f lints/0010*.sql -f lints/0011*.sql -f lints/0013*.sql -f lints/0014*.sql -f lints/0015*.sql -f lints/0016*.sql -f lints/0017*.sql -f lints/0018*.sql -f lints/0019*.sql -f lints/0020*.sql -f lints/0021*.sql -d contrib_regression

# Run tests
${REGRESS} --use-existing --dbname=contrib_regression --inputdir=${TESTDIR} ${TESTS}
Expand Down
18 changes: 18 additions & 0 deletions docs/0021_fkey_to_auth_unique.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Level: ERROR

### Rationale

Supabase Auth does not support user-defined foreign keys that reference non-primary key unique constraints in the `auth` schema. These unique constraints are scheduled for removal, and any foreign keys referencing them will block Supabase Auth's database migrations from completing successfully. If Supabase Auth is unable to upgrade, it prevents the rollout of new features and critical security updates.

### How to Resolve

To ensure successful migrations and continued updates:

1. Drop Foreign Keys: Remove any foreign key constraints that reference unique constraints in the `auth` schema.

```sql
alter table public.some_tablee
drop constraint some_foreign_key;
```

2. Reference Primary Keys Instead: If applicable, replace references to unique constraints with references to the corresponding table's primary key.
43 changes: 43 additions & 0 deletions lints/0021_fkey_to_auth_unique.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
create view lint."0021_fkey_to_auth_unique" as

select
'fkey_to_auth_unique' as name,
'Foreign Key to Auth Unique Constraint' as title,
'ERROR' as level,
'EXTERNAL' as facing,
array['SECURITY'] as categories,
'Detects user defined foreign keys to unique constraints in the auth schema.' as description,
format(
'Table `%s`.`%s` has a foreign key `%s` referencing an auth unique constraint',
n.nspname, -- referencing schema
c_rel.relname, -- referencing table
c.conname -- fkey name
) as detail,
'Drop the foreign key constraint that references the auth schema.' as remediation,
jsonb_build_object(
'schema', n.nspname,
'name', c_rel.relname,
'foreign_key', c.conname
) as metadata,
format(
'fkey_to_auth_unique_%s_%s_%s',
n.nspname, -- referencing schema
c_rel.relname, -- referencing table
c.conname
) as cache_key
from
pg_catalog.pg_constraint c
join pg_catalog.pg_class c_rel
on c.conrelid = c_rel.oid
join pg_catalog.pg_namespace n
on c_rel.relnamespace = n.oid
join pg_catalog.pg_class ref_rel
on c.confrelid = ref_rel.oid
join pg_catalog.pg_namespace cn
on ref_rel.relnamespace = cn.oid
join pg_catalog.pg_index i
on c.conindid = i.indexrelid
where c.contype = 'f'
and cn.nspname = 'auth'
and i.indisunique
and not i.indisprimary;
45 changes: 44 additions & 1 deletion splinter.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1065,4 +1065,47 @@ where
and raw_waste > (20 * 1024 * 1024) -- filter for waste > 200 MB
order by
schemaname,
object_name)
object_name)
union all
(
select
'fkey_to_auth_unique' as name,
'Foreign Key to Auth Unique Constraint' as title,
'ERROR' as level,
'EXTERNAL' as facing,
array['SECURITY'] as categories,
'Detects user defined foreign keys to unique constraints in the auth schema.' as description,
format(
'Table `%s`.`%s` has a foreign key `%s` referencing an auth unique constraint',
n.nspname, -- referencing schema
c_rel.relname, -- referencing table
c.conname -- fkey name
) as detail,
'Drop the foreign key constraint that references the auth schema.' as remediation,
jsonb_build_object(
'schema', n.nspname,
'name', c_rel.relname,
'foreign_key', c.conname
) as metadata,
format(
'fkey_to_auth_unique_%s_%s_%s',
n.nspname, -- referencing schema
c_rel.relname, -- referencing table
c.conname
) as cache_key
from
pg_catalog.pg_constraint c
join pg_catalog.pg_class c_rel
on c.conrelid = c_rel.oid
join pg_catalog.pg_namespace n
on c_rel.relnamespace = n.oid
join pg_catalog.pg_class ref_rel
on c.confrelid = ref_rel.oid
join pg_catalog.pg_namespace cn
on ref_rel.relnamespace = cn.oid
join pg_catalog.pg_index i
on c.conindid = i.indexrelid
where c.contype = 'f'
and cn.nspname = 'auth'
and i.indisunique
and not i.indisprimary)
41 changes: 41 additions & 0 deletions test/expected/0021_fkey_to_auth_unique.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
begin;
-- 0 issues
select * from lint."0021_fkey_to_auth_unique";
name | title | level | facing | categories | description | detail | remediation | metadata | cache_key
------+-------+-------+--------+------------+-------------+--------+-------------+----------+-----------
(0 rows)

-- Satisfy all failure conditions
create table public.foo(
id uuid primary key,
un text not null references auth.users(username)
);
-- 1 issue - fkey ref to unique constraint
select * from lint."0021_fkey_to_auth_unique";
name | title | level | facing | categories | description | detail | remediation | metadata | cache_key
---------------------+---------------------------------------+-------+----------+------------+-----------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+------------------------------------------------------------------+-------------------------------------------------------------------+--------------------------------------------
fkey_to_auth_unique | Foreign Key to Auth Unique Constraint | ERROR | EXTERNAL | {SECURITY} | Detects user defined foreign keys to unique constraints in the auth schema. | Table `public`.`foo` has a foreign key `foo_un_fkey` referencing an auth unique constraint | Drop the foreign key constraint that references the auth schema. | {"name": "foo", "schema": "public", "foreign_key": "foo_un_fkey"} | fkey_to_auth_unique_public_foo_foo_un_fkey
(1 row)

-- Alter the table adding another fkey based on id
-- this is the primary key, so it is allowed and should not show up
-- in the lint
alter table public.foo
add constraint fk_foo_user_id
foreign key (id)
references auth.users(id);
-- 1 issue - still only 1 issue because the pkey constraint is okay
select * from lint."0021_fkey_to_auth_unique";
name | title | level | facing | categories | description | detail | remediation | metadata | cache_key
---------------------+---------------------------------------+-------+----------+------------+-----------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+------------------------------------------------------------------+-------------------------------------------------------------------+--------------------------------------------
fkey_to_auth_unique | Foreign Key to Auth Unique Constraint | ERROR | EXTERNAL | {SECURITY} | Detects user defined foreign keys to unique constraints in the auth schema. | Table `public`.`foo` has a foreign key `foo_un_fkey` referencing an auth unique constraint | Drop the foreign key constraint that references the auth schema. | {"name": "foo", "schema": "public", "foreign_key": "foo_un_fkey"} | fkey_to_auth_unique_public_foo_foo_un_fkey
(1 row)

drop table public.foo;
-- 0 issue - still only 1 issue because the pkey constraint is okay
select * from lint."0021_fkey_to_auth_unique";
name | title | level | facing | categories | description | detail | remediation | metadata | cache_key
------+-------+-------+--------+------------+-------------+--------+-------------+----------+-----------
(0 rows)

rollback;
8 changes: 7 additions & 1 deletion test/fixtures.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ create schema lint;
create schema extensions;

create schema auth;
create table auth.users (id uuid primary key);

create table auth.users (
id uuid primary key,
username text not null,
constraint users_username_key unique (username)
);

create function auth.uid() returns uuid language sql as $$select gen_random_uuid()$$;
create function auth.jwt() returns jsonb language sql as $$select jsonb_build_object()$$;
create function auth.role() returns text language sql as $$select ''$$;
Expand Down
31 changes: 31 additions & 0 deletions test/sql/0021_fkey_to_auth_unique.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
begin;

-- 0 issues
select * from lint."0021_fkey_to_auth_unique";

-- Satisfy all failure conditions
create table public.foo(
id uuid primary key,
un text not null references auth.users(username)
);

-- 1 issue - fkey ref to unique constraint
select * from lint."0021_fkey_to_auth_unique";

-- Alter the table adding another fkey based on id
-- this is the primary key, so it is allowed and should not show up
-- in the lint
alter table public.foo
add constraint fk_foo_user_id
foreign key (id)
references auth.users(id);

-- 1 issue - still only 1 issue because the pkey constraint is okay
select * from lint."0021_fkey_to_auth_unique";

drop table public.foo;

-- 0 issue - still only 1 issue because the pkey constraint is okay
select * from lint."0021_fkey_to_auth_unique";

rollback;