---
number: 34270
slug: 34270-restricting-access-on-auth-storage-and-realtime-schemas-on-april-21-2025
published: 2025-03-18
discussion: https://github.com/orgs/supabase/discussions/34270
labels:
  - auth
  - storage
  - realtime
page: https://supabase.com/changelog/34270-restricting-access-on-auth-storage-and-realtime-schemas-on-april-21-2025
---

# Restricting Access on Auth, Storage, and Realtime Schemas on April 21, 2025

On April 21, we are restricting certain SQL actions you can perform in your database’s `auth`, `storage`, and `realtime` schemas.

## Why are we making these restrictions?

Supabase Auth, Storage, and Realtime services each rely on their respective schemas in order to function properly.

These restrictions prevent unintended side effects like third-party tooling and user defined changes altering schemas or their objects, such as migration tables and database functions, that could disrupt or break functionality.

## What this means for your project

On April 21, you will no longer be able to perform the following actions on the `auth`, `storage`, and `realtime` schemas:

- Create tables and database functions
- Drop existing tables or database functions
- Create indexes on existing tables
- Perform destructive actions (i.e. `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE`) on the following migration tables:
    - `auth.schema_migrations`
    - `storage.migrations`
    - `realtime.schema_migrations`
- Revoking privileges on tables in these schemas from API roles (e.g. `anon`)

However, you will still have permissions to perform the following actions:

- Create foreign keys referencing tables in the `auth`, `storage`, and `realtime` schemas
- Create RLS policies and database triggers on the following tables:
    - `auth.audit_log_entries`
    - `auth.identities`
    - `auth.refresh_tokens`
    - `auth.sessions`
    - `auth.users`
    - `storage.buckets`
    - `storage.migrations`
    - `storage.objects`
    - `storage.s3_multipart_uploads`
    - `storage.s3_multipart_uploads_parts`
    - `realtime.messages`

## How to determine if you’re affected?

- Run the following query to check if you created any tables in the `auth`, `storage`, and `realtime` schemas:
    
```sql
SET search_path = '';
SELECT oid::regclass AS table_name
FROM pg_class  
WHERE  
    (relnamespace = 'auth'::regnamespace AND relowner != 'supabase_auth_admin'::regrole)  
    OR (relnamespace = 'storage'::regnamespace AND relowner != 'supabase_storage_admin'::regrole)  
    OR (  
        relnamespace = 'realtime'::regnamespace
        AND relowner NOT IN (  
            SELECT oid  
            FROM pg_roles  
            WHERE rolname IN ('supabase_admin', 'supabase_realtime_admin')  
        )  
    );
```
    
- Run the following query to check if you created any database functions in the `auth`, `storage`, and `realtime` schemas:
    
 ```sql
SET search_path = '';
SELECT pg_catalog.format('%s(%s)', oid::regproc, pg_get_function_identity_arguments(oid::regproc)) AS function_name
FROM pg_proc  
WHERE  
    (pronamespace = 'auth'::regnamespace AND proowner != 'supabase_auth_admin'::regrole)  
    OR (pronamespace = 'storage'::regnamespace AND proowner != 'supabase_storage_admin'::regrole)  
    OR (  
        pronamespace = 'realtime'::regnamespace  
        AND proowner NOT IN (  
            SELECT oid  
            FROM pg_roles  
            WHERE rolname IN ('supabase_admin', 'supabase_realtime_admin')  
        )  
    );
```

## What you need to do

If any of the above queries return a result, you must move them to either the `public` schema or a schema that you’ve created. Otherwise, they will be deleted.

- Here’s how you can move a table to another schema:

```sql
CREATE SCHEMA IF NOT EXISTS my_custom_schema;
ALTER TABLE storage.my_custom_table SET SCHEMA my_custom_schema;
```

- Here’s how you can move a database function to another schema:

```sql
CREATE SCHEMA IF NOT EXISTS my_custom_schema;
ALTER FUNCTION storage.custom_function() SET SCHEMA my_custom_schema;
```

Additionally, if you're using [Migrations](https://supabase.com/docs/guides/deployment/database-migrations) or [Branching](https://supabase.com/docs/guides/deployment/branching), you'll need to patch your migrations to move these objects to your own schemas. E.g. if you have a migration `20250101000000_add_custom_table.sql` like so:

```sql
-- ...
CREATE TABLE auth.my_custom_table (
  -- id int8 ...
);
-- ...
```

Then you need to edit it locally into:

```sql
-- ...
CREATE SCHEMA IF NOT EXISTS my_custom_schema;
CREATE TABLE my_custom_schema.my_custom_table (
  -- id int8 ...
);
-- ...
```

Then you'll need to repair the migration history on the linked project:

```sh
supabase migration repair --status reverted 20250101000000
supabase migration repair --status applied 20250101000000
```
