···11+-- (c) 2021 Supabase Inc.
22+-- license: https://github.com/supabase/supabase/blob/master/LICENSE
33+-- https://github.com/supabase/supabase/blob/30b9f748fe163420375244fa350e14bcfa235a3f/docker/volumes/db/init/00-initial-schema.sql
44+55+-- Set up reatime
66+-- create publication supabase_realtime; -- defaults to empty publication
77+create publication supabase_realtime;
88+99+-- Supabase super admin
1010+create user supabase_admin;
1111+alter user supabase_admin with superuser createdb createrole replication bypassrls;
1212+1313+-- Extension namespacing
1414+create SCHEMA IF NOT exists extensions;
1515+create extension if not exists "uuid-ossp" with schema extensions;
1616+create extension if not exists pgcrypto with schema extensions;
1717+create extension if not exists pgjwt with schema extensions;
1818+1919+-- Set up auth roles for the developer
2020+create role anon nologin noinherit;
2121+create role authenticated nologin noinherit; -- "logged in" user: web_user, app_user, etc
2222+create role service_role nologin noinherit bypassrls; -- allow developers to create JWT's that bypass their policies
2323+2424+create user authenticator noinherit;
2525+grant anon to authenticator;
2626+grant authenticated to authenticator;
2727+grant service_role to authenticator;
2828+grant supabase_admin to authenticator;
2929+3030+grant usage on schema public to postgres, anon, authenticated, service_role;
3131+alter default privileges in schema public grant all on tables to postgres, anon, authenticated, service_role;
3232+alter default privileges in schema public grant all on functions to postgres, anon, authenticated, service_role;
3333+alter default privileges in schema public grant all on sequences to postgres, anon, authenticated, service_role;
3434+3535+-- Allow Extensions to be used in the API
3636+grant usage on schema extensions to postgres, anon, authenticated, service_role;
3737+3838+-- Set up namespacing
3939+alter user supabase_admin SET search_path TO public, extensions; -- don't include the "auth" schema
4040+4141+-- These are required so that the users receive grants whenever "supabase_admin" creates tables/function
4242+alter default privileges for user supabase_admin in schema public grant all
4343+ on sequences to postgres, anon, authenticated, service_role;
4444+alter default privileges for user supabase_admin in schema public grant all
4545+ on tables to postgres, anon, authenticated, service_role;
4646+alter default privileges for user supabase_admin in schema public grant all
4747+ on functions to postgres, anon, authenticated, service_role;
4848+4949+-- Set short statement/query timeouts for API roles
5050+alter role anon set statement_timeout = '3s';
5151+alter role authenticated set statement_timeout = '8s';
+123
supabase/initdb.d/01-auth-schema.sql
···11+-- (c) 2021 Supabase Inc.
22+-- license: https://github.com/supabase/supabase/blob/master/LICENSE
33+-- https://github.com/supabase/supabase/blob/30b9f748fe163420375244fa350e14bcfa235a3f/docker/volumes/db/init/01-auth-schema.sql
44+55+CREATE SCHEMA IF NOT EXISTS auth AUTHORIZATION supabase_admin;
66+77+-- auth.users definition
88+99+CREATE TABLE auth.users (
1010+ instance_id uuid NULL,
1111+ id uuid NOT NULL UNIQUE,
1212+ aud varchar(255) NULL,
1313+ "role" varchar(255) NULL,
1414+ email varchar(255) NULL UNIQUE,
1515+ encrypted_password varchar(255) NULL,
1616+ confirmed_at timestamptz NULL,
1717+ invited_at timestamptz NULL,
1818+ confirmation_token varchar(255) NULL,
1919+ confirmation_sent_at timestamptz NULL,
2020+ recovery_token varchar(255) NULL,
2121+ recovery_sent_at timestamptz NULL,
2222+ email_change_token varchar(255) NULL,
2323+ email_change varchar(255) NULL,
2424+ email_change_sent_at timestamptz NULL,
2525+ last_sign_in_at timestamptz NULL,
2626+ raw_app_meta_data jsonb NULL,
2727+ raw_user_meta_data jsonb NULL,
2828+ is_super_admin bool NULL,
2929+ created_at timestamptz NULL,
3030+ updated_at timestamptz NULL,
3131+ CONSTRAINT users_pkey PRIMARY KEY (id)
3232+);
3333+CREATE INDEX users_instance_id_email_idx ON auth.users USING btree (instance_id, email);
3434+CREATE INDEX users_instance_id_idx ON auth.users USING btree (instance_id);
3535+comment on table auth.users is 'Auth: Stores user login data within a secure schema.';
3636+3737+-- auth.refresh_tokens definition
3838+3939+CREATE TABLE auth.refresh_tokens (
4040+ instance_id uuid NULL,
4141+ id bigserial NOT NULL,
4242+ "token" varchar(255) NULL,
4343+ user_id varchar(255) NULL,
4444+ revoked bool NULL,
4545+ created_at timestamptz NULL,
4646+ updated_at timestamptz NULL,
4747+ CONSTRAINT refresh_tokens_pkey PRIMARY KEY (id)
4848+);
4949+CREATE INDEX refresh_tokens_instance_id_idx ON auth.refresh_tokens USING btree (instance_id);
5050+CREATE INDEX refresh_tokens_instance_id_user_id_idx ON auth.refresh_tokens USING btree (instance_id, user_id);
5151+CREATE INDEX refresh_tokens_token_idx ON auth.refresh_tokens USING btree (token);
5252+comment on table auth.refresh_tokens is 'Auth: Store of tokens used to refresh JWT tokens once they expire.';
5353+5454+-- auth.instances definition
5555+5656+CREATE TABLE auth.instances (
5757+ id uuid NOT NULL,
5858+ uuid uuid NULL,
5959+ raw_base_config text NULL,
6060+ created_at timestamptz NULL,
6161+ updated_at timestamptz NULL,
6262+ CONSTRAINT instances_pkey PRIMARY KEY (id)
6363+);
6464+comment on table auth.instances is 'Auth: Manages users across multiple sites.';
6565+6666+-- auth.audit_log_entries definition
6767+6868+CREATE TABLE auth.audit_log_entries (
6969+ instance_id uuid NULL,
7070+ id uuid NOT NULL,
7171+ payload json NULL,
7272+ created_at timestamptz NULL,
7373+ CONSTRAINT audit_log_entries_pkey PRIMARY KEY (id)
7474+);
7575+CREATE INDEX audit_logs_instance_id_idx ON auth.audit_log_entries USING btree (instance_id);
7676+comment on table auth.audit_log_entries is 'Auth: Audit trail for user actions.';
7777+7878+-- auth.schema_migrations definition
7979+8080+CREATE TABLE auth.schema_migrations (
8181+ "version" varchar(255) NOT NULL,
8282+ CONSTRAINT schema_migrations_pkey PRIMARY KEY ("version")
8383+);
8484+comment on table auth.schema_migrations is 'Auth: Manages updates to the auth system.';
8585+8686+INSERT INTO auth.schema_migrations (version)
8787+VALUES ('20171026211738'),
8888+ ('20171026211808'),
8989+ ('20171026211834'),
9090+ ('20180103212743'),
9191+ ('20180108183307'),
9292+ ('20180119214651'),
9393+ ('20180125194653');
9494+9595+-- Gets the User ID from the request cookie
9696+create or replace function auth.uid() returns uuid as $$
9797+ select nullif(current_setting('request.jwt.claim.sub', true), '')::uuid;
9898+$$ language sql stable;
9999+100100+-- Gets the User ID from the request cookie
101101+create or replace function auth.role() returns text as $$
102102+ select nullif(current_setting('request.jwt.claim.role', true), '')::text;
103103+$$ language sql stable;
104104+105105+-- Gets the User email
106106+create or replace function auth.email() returns text as $$
107107+ select nullif(current_setting('request.jwt.claim.email', true), '')::text;
108108+$$ language sql stable;
109109+110110+-- usage on auth functions to API roles
111111+GRANT USAGE ON SCHEMA auth TO anon, authenticated, service_role;
112112+113113+-- Supabase super admin
114114+CREATE USER supabase_auth_admin NOINHERIT CREATEROLE LOGIN NOREPLICATION;
115115+GRANT ALL PRIVILEGES ON SCHEMA auth TO supabase_auth_admin;
116116+GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA auth TO supabase_auth_admin;
117117+GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA auth TO supabase_auth_admin;
118118+ALTER USER supabase_auth_admin SET search_path = "auth";
119119+ALTER table "auth".users OWNER TO supabase_auth_admin;
120120+ALTER table "auth".refresh_tokens OWNER TO supabase_auth_admin;
121121+ALTER table "auth".audit_log_entries OWNER TO supabase_auth_admin;
122122+ALTER table "auth".instances OWNER TO supabase_auth_admin;
123123+ALTER table "auth".schema_migrations OWNER TO supabase_auth_admin;
+120
supabase/initdb.d/02-storage-schema.sql
···11+-- (c) 2021 Supabase Inc.
22+-- license: https://github.com/supabase/supabase/blob/master/LICENSE
33+-- https://github.com/supabase/supabase/blob/30b9f748fe163420375244fa350e14bcfa235a3f/docker/volumes/db/init/02-storage-schema.sql
44+55+CREATE SCHEMA IF NOT EXISTS storage AUTHORIZATION supabase_admin;
66+77+grant usage on schema storage to postgres, anon, authenticated, service_role;
88+alter default privileges in schema storage grant all on tables to postgres, anon, authenticated, service_role;
99+alter default privileges in schema storage grant all on functions to postgres, anon, authenticated, service_role;
1010+alter default privileges in schema storage grant all on sequences to postgres, anon, authenticated, service_role;
1111+1212+CREATE TABLE "storage"."buckets" (
1313+ "id" text not NULL,
1414+ "name" text NOT NULL,
1515+ "owner" uuid,
1616+ "created_at" timestamptz DEFAULT now(),
1717+ "updated_at" timestamptz DEFAULT now(),
1818+ CONSTRAINT "buckets_owner_fkey" FOREIGN KEY ("owner") REFERENCES "auth"."users"("id"),
1919+ PRIMARY KEY ("id")
2020+);
2121+CREATE UNIQUE INDEX "bname" ON "storage"."buckets" USING BTREE ("name");
2222+2323+CREATE TABLE "storage"."objects" (
2424+ "id" uuid NOT NULL DEFAULT extensions.uuid_generate_v4(),
2525+ "bucket_id" text,
2626+ "name" text,
2727+ "owner" uuid,
2828+ "created_at" timestamptz DEFAULT now(),
2929+ "updated_at" timestamptz DEFAULT now(),
3030+ "last_accessed_at" timestamptz DEFAULT now(),
3131+ "metadata" jsonb,
3232+ CONSTRAINT "objects_bucketId_fkey" FOREIGN KEY ("bucket_id") REFERENCES "storage"."buckets"("id"),
3333+ CONSTRAINT "objects_owner_fkey" FOREIGN KEY ("owner") REFERENCES "auth"."users"("id"),
3434+ PRIMARY KEY ("id")
3535+);
3636+CREATE UNIQUE INDEX "bucketid_objname" ON "storage"."objects" USING BTREE ("bucket_id","name");
3737+CREATE INDEX name_prefix_search ON storage.objects(name text_pattern_ops);
3838+3939+ALTER TABLE storage.objects ENABLE ROW LEVEL SECURITY;
4040+4141+CREATE FUNCTION storage.foldername(name text)
4242+ RETURNS text[]
4343+ LANGUAGE plpgsql
4444+AS $function$
4545+DECLARE
4646+_parts text[];
4747+BEGIN
4848+ select string_to_array(name, '/') into _parts;
4949+ return _parts[1:array_length(_parts,1)-1];
5050+END
5151+$function$;
5252+5353+CREATE FUNCTION storage.filename(name text)
5454+ RETURNS text
5555+ LANGUAGE plpgsql
5656+AS $function$
5757+DECLARE
5858+_parts text[];
5959+BEGIN
6060+ select string_to_array(name, '/') into _parts;
6161+ return _parts[array_length(_parts,1)];
6262+END
6363+$function$;
6464+6565+CREATE FUNCTION storage.extension(name text)
6666+ RETURNS text
6767+ LANGUAGE plpgsql
6868+AS $function$
6969+DECLARE
7070+_parts text[];
7171+_filename text;
7272+BEGIN
7373+ select string_to_array(name, '/') into _parts;
7474+ select _parts[array_length(_parts,1)] into _filename;
7575+ -- @todo return the last part instead of 2
7676+ return split_part(_filename, '.', 2);
7777+END
7878+$function$;
7979+8080+CREATE FUNCTION storage.search(prefix text, bucketname text, limits int DEFAULT 100, levels int DEFAULT 1, offsets int DEFAULT 0)
8181+ RETURNS TABLE (
8282+ name text,
8383+ id uuid,
8484+ updated_at TIMESTAMPTZ,
8585+ created_at TIMESTAMPTZ,
8686+ last_accessed_at TIMESTAMPTZ,
8787+ metadata jsonb
8888+ )
8989+ LANGUAGE plpgsql
9090+AS $function$
9191+DECLARE
9292+_bucketId text;
9393+BEGIN
9494+ -- will be replaced by migrations when server starts
9595+ -- saving space for cloud-init
9696+END
9797+$function$;
9898+9999+-- create migrations table
100100+-- https://github.com/ThomWright/postgres-migrations/blob/master/src/migrations/0_create-migrations-table.sql
101101+-- we add this table here and not let it be auto-created so that the permissions are properly applied to it
102102+CREATE TABLE IF NOT EXISTS storage.migrations (
103103+ id integer PRIMARY KEY,
104104+ name varchar(100) UNIQUE NOT NULL,
105105+ hash varchar(40) NOT NULL, -- sha1 hex encoded hash of the file name and contents, to ensure it hasn't been altered since applying the migration
106106+ executed_at timestamp DEFAULT current_timestamp
107107+);
108108+109109+CREATE USER supabase_storage_admin NOINHERIT CREATEROLE LOGIN NOREPLICATION;
110110+GRANT ALL PRIVILEGES ON SCHEMA storage TO supabase_storage_admin;
111111+GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA storage TO supabase_storage_admin;
112112+GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA storage TO supabase_storage_admin;
113113+ALTER USER supabase_storage_admin SET search_path = "storage";
114114+ALTER table "storage".objects owner to supabase_storage_admin;
115115+ALTER table "storage".buckets owner to supabase_storage_admin;
116116+ALTER table "storage".migrations OWNER TO supabase_storage_admin;
117117+ALTER function "storage".foldername(text) owner to supabase_storage_admin;
118118+ALTER function "storage".filename(text) owner to supabase_storage_admin;
119119+ALTER function "storage".extension(text) owner to supabase_storage_admin;
120120+ALTER function "storage".search(text,text,int,int,int) owner to supabase_storage_admin;
+72
supabase/initdb.d/03-post-setup.sql
···11+-- (c) 2021 Supabase Inc.
22+-- license: https://github.com/supabase/supabase/blob/master/LICENSE
33+-- https://github.com/supabase/supabase/blob/30b9f748fe163420375244fa350e14bcfa235a3f/docker/volumes/db/init/03-post-setup.sql
44+55+ALTER ROLE postgres SET search_path TO "\$user",public,extensions;
66+CREATE OR REPLACE FUNCTION extensions.notify_api_restart()
77+RETURNS event_trigger
88+LANGUAGE plpgsql
99+AS $$
1010+BEGIN
1111+ NOTIFY ddl_command_end;
1212+END;
1313+$$;
1414+CREATE EVENT TRIGGER api_restart ON ddl_command_end
1515+EXECUTE PROCEDURE extensions.notify_api_restart();
1616+COMMENT ON FUNCTION extensions.notify_api_restart IS 'Sends a notification to the API to restart. If your database schema has changed, this is required so that Supabase can rebuild the relationships.';
1717+1818+-- Trigger for pg_cron
1919+CREATE OR REPLACE FUNCTION extensions.grant_pg_cron_access()
2020+RETURNS event_trigger
2121+LANGUAGE plpgsql
2222+AS $$
2323+DECLARE
2424+ schema_is_cron bool;
2525+BEGIN
2626+ schema_is_cron = (
2727+ SELECT n.nspname = 'cron'
2828+ FROM pg_event_trigger_ddl_commands() AS ev
2929+ LEFT JOIN pg_catalog.pg_namespace AS n
3030+ ON ev.objid = n.oid
3131+ );
3232+3333+ IF schema_is_cron
3434+ THEN
3535+ grant usage on schema cron to postgres with grant option;
3636+3737+ alter default privileges in schema cron grant all on tables to postgres with grant option;
3838+ alter default privileges in schema cron grant all on functions to postgres with grant option;
3939+ alter default privileges in schema cron grant all on sequences to postgres with grant option;
4040+4141+ alter default privileges for user supabase_admin in schema cron grant all
4242+ on sequences to postgres with grant option;
4343+ alter default privileges for user supabase_admin in schema cron grant all
4444+ on tables to postgres with grant option;
4545+ alter default privileges for user supabase_admin in schema cron grant all
4646+ on functions to postgres with grant option;
4747+4848+ grant all privileges on all tables in schema cron to postgres with grant option;
4949+5050+ END IF;
5151+5252+END;
5353+$$;
5454+CREATE EVENT TRIGGER issue_pg_cron_access ON ddl_command_end WHEN TAG in ('CREATE SCHEMA')
5555+EXECUTE PROCEDURE extensions.grant_pg_cron_access();
5656+COMMENT ON FUNCTION extensions.grant_pg_cron_access IS 'Grants access to pg_cron';
5757+5858+-- Supabase dashboard user
5959+CREATE ROLE dashboard_user NOSUPERUSER CREATEDB CREATEROLE REPLICATION;
6060+GRANT ALL ON DATABASE postgres TO dashboard_user;
6161+GRANT ALL ON SCHEMA auth TO dashboard_user;
6262+GRANT ALL ON SCHEMA extensions TO dashboard_user;
6363+GRANT ALL ON SCHEMA storage TO dashboard_user;
6464+GRANT ALL ON ALL TABLES IN SCHEMA auth TO dashboard_user;
6565+GRANT ALL ON ALL TABLES IN SCHEMA extensions TO dashboard_user;
6666+-- GRANT ALL ON ALL TABLES IN SCHEMA storage TO dashboard_user;
6767+GRANT ALL ON ALL SEQUENCES IN SCHEMA auth TO dashboard_user;
6868+GRANT ALL ON ALL SEQUENCES IN SCHEMA storage TO dashboard_user;
6969+GRANT ALL ON ALL SEQUENCES IN SCHEMA extensions TO dashboard_user;
7070+GRANT ALL ON ALL ROUTINES IN SCHEMA auth TO dashboard_user;
7171+GRANT ALL ON ALL ROUTINES IN SCHEMA storage TO dashboard_user;
7272+GRANT ALL ON ALL ROUTINES IN SCHEMA extensions TO dashboard_user;
+13
supabase/initdb.d/99-example.sql
···11+ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL PRIVILEGES ON TABLES FROM anon, authenticated;
22+33+CREATE TABLE users (
44+ uuid UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
55+ role NAME NOT NULL DEFAULT current_user,
66+ name TEXT
77+);
88+99+GRANT ALL PRIVILEGES (name) ON users TO authenticated;
1010+GRANT SELECT ON users TO anon, authenticated;
1111+1212+ALTER TABLE users ENABLE ROW LEVEL SECURITY;
1313+CREATE POLICY users_policy ON users USING (role = current_user);