---
title: "Supabase exposed schemas: qué abre la lista"
description: "¿Es seguro su proyecto de Supabase? Qué significa Exposed schemas, cómo mi verificador puntúa los esquemas extra y una consulta SQL que halla tablas sin RLS."
url: "https://madsalt.tech/es/notes/supabase-exposed-schemas/"
author: "Denys Zaichenko"
language: "es"
published: 2026-10-22
---

# Supabase exposed schemas: qué abre la lista

En resumen

La lista Exposed schemas de Supabase decide qué esquemas sirve la Data API a cualquiera que tenga su clave pública. Por defecto son `public` y `graphql_public`. Cada tabla, vista y función de un esquema de esa lista necesita sus propios grants y su RLS, así que cada esquema extra es más superficie que defender. Mantenga la lista corta y revísela primero.

Construí un [verificador de seguridad de Supabase](https://madsalt.tech/es/tools/supabase-security-check/) gratuito, y la lista de Exposed schemas es una de las primeras cosas que lee. Cuando alguien me pregunta qué tan seguro es un proyecto de Supabase, empiezo por este ajuste.

## ¿Qué significa exponer un esquema en Supabase?

Supabase sirve su base de datos por REST con PostgREST. PostgREST solo responde por los esquemas de su lista `db_schema`, que se edita en el Dashboard en Project Settings → Data API → Exposed schemas. En la configuración de proyecto que miré, el valor era `public,graphql_public`, y la [guía de esquemas personalizados](https://supabase.com/docs/guides/api/using-custom-schemas) de Supabase dice que `public` está expuesto por defecto. Una petición a un esquema fuera de la lista se rechaza, y [PostgREST](https://docs.postgrest.org/en/stable/references/api/schemas.html) nunca permite `pg_catalog` ni `information_schema` en ella.

## ¿Por qué importa la lista para la seguridad?

Todo lo que hay dentro de un esquema expuesto es accesible con la clave pública: tablas, vistas y funciones. La [guía de RLS](https://supabase.com/docs/guides/database/postgres/row-level-security) de Supabase es directa: una tabla de un esquema expuesto sin RLS puede leerla y escribirla cualquier rol con un grant sobre ella. Un esquema que no está en la lista no se alcanza por la API de ninguna manera.

Así que un esquema extra no es un cambio neutro. Añada `storage` o `vault` a la lista y habrá puesto tablas internas al alcance de la Data API. Añada su propio esquema y cada tabla de él necesita el mismo cuidado que `public`.

![Qué abre un esquema expuesto de más. Una petición anon, antes y después de recortar la lista. Antes: hay un esquema extra expuesto: petición anon → Data API → esquema extra → tabla sin RLS legible; Después: solo public y graphql_public: petición anon → Data API → solo esquemas por defecto → RLS en cada tabla.](https://madsalt.tech/charts/es/supabase-exposed-schemas.svg)

*De las reglas del verificador de seguridad de Supabase y la documentación de la Data API de Supabase, 22 de octubre de 2026.*

## ¿Cómo califica el verificador los esquemas extra?

La comprobación se llama `extra_exposed_schemas`. Todo lo que no sea `public` ni `graphql_public` cuenta como extra, y entonces:

- Un esquema interno de Supabase en la lista (`auth`, `storage`, `realtime`, `vault`, `extensions` y similares) es un **problema de gravedad alta**.
- Solo esquemas propios, por ejemplo `api`, dan una **advertencia de gravedad media**.
- Sin extras, la comprobación pasa.

La misma lista alimenta otras comprobaciones. Las tablas sin RLS, los grants de escritura para anon, las políticas siempre verdaderas, las vistas sin `security_invoker` y las funciones `SECURITY DEFINER` que anon puede llamar solo se reportan en los esquemas expuestos, porque ahí es donde la clave pública llega a ellas.

## ¿Cómo usar un esquema propio de forma segura?

Un esquema propio es un patrón legítimo: la guía [Securing your API](https://supabase.com/docs/guides/api/securing-your-api) de Supabase describe un esquema dedicado como `api` como una forma de que la superficie expuesta sea más fácil de identificar y auditar, con las tablas internas en esquemas que no se exponen. Dos pasos lo hacen funcionar, y la [guía de esquemas personalizados](https://supabase.com/docs/guides/api/using-custom-schemas) da los dos: añadir el esquema a Exposed schemas y luego conceder `usage` sobre él a `anon`, `authenticated` y `service_role`, además de privilegios sobre sus objetos.

El ejemplo de la guía concede `ALL` sobre cada tabla. Yo no copiaría esa línea tal cual. La guía Securing your API dice que se dé a cada rol el mínimo que necesita y que se active RLS en cada tabla que se exponga. Los grants deciden si un rol puede tocar una tabla, las políticas deciden qué filas.

Un cambio aparte: Supabase [deja de conceder automáticamente las tablas nuevas de `public` a la Data API](https://supabase.com/changelog/45329-breaking-change-tables-not-exposed-to-data-and-graphql-api-automatically). Es el comportamiento por defecto de los proyectos nuevos desde el 30 de mayo de 2026 y se aplicará a los proyectos existentes el 30 de octubre de 2026, y las tablas existentes conservan sus grants. Esa es la capa de los grants. No cambia qué esquemas están en la lista.

## ¿Es seguro su proyecto de Supabase? Cómo comprobarlo

Abra Project Settings → Data API y lea Exposed schemas. Si hay más que `public` y `graphql_public`, pregúntese para qué sirve cada esquema extra.

Después liste las tablas de esos esquemas que tienen RLS desactivado, y si `anon` ya puede leerlas:

```sql
select n.nspname as schema,
       c.relname as "table",
       has_table_privilege('anon', c.oid, 'select') as anon_can_select
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where n.nspname in ('public', 'api')  -- your Exposed schemas
  and c.relkind in ('r', 'p')
  and not c.relrowsecurity
order by 1, 2;
```

La ejecuté en un Postgres 17 desechable con un esquema `api` que tenía una tabla con RLS y otra sin él, más una tabla `public` sin RLS. Devolvió solo las dos sin RLS:

```text
 schema | table  | anon_can_select
--------+--------+-----------------
 api    | orders | t
 public | logs   | t
```

Cada fila con `anon_can_select` en true es una tabla que cualquiera con su clave pública puede leer, hasta que active RLS o revoque el grant. La consulta cubre solo tablas. Las vistas y las funciones necesitan su propia revisión, que recorre mi [lista de seguridad para apps Lovable](https://madsalt.tech/es/blog/lovable-app-security-checklist/), y [cómo pruebo el RLS de Supabase](https://madsalt.tech/es/blog/how-to-test-supabase-rls/) muestra cómo demostrar que las políticas funcionan.
