¿Es segura tu app de Windsurf?
¿Sirve Windsurf para una app en producción? El código generado suele estar bien. Lo que se cuela es el cambio que nadie leyó, en un archivo que nadie abrió.

Los logotipos son propiedad de sus respectivos dueños y se muestran solo para indicar compatibilidad.
En resumen
- Una app de Windsurf suele ser segura por el lado del código. Lo que se cuela es el cambio que nadie leyó, así que revisa resultados en vez de diffs.
- Busca service_role y sk_live_ en tu salida de compilación. Eso cubre todos los archivos que tocó el asistente, los abrieras o no.
- Row Level Security es la única comprobación que sobrevive al código que nunca leíste, porque toda petición tiene que pasar por la base de datos.
Windsurf puede cambiar mucho de tu proyecto en un solo paso: varios archivos, una migración, una configuración, todo a la vez y todo funcionando. El resultado suele ser bueno. El problema es la revisión: un cambio repartido por muchos archivos no se lee como uno que toca solo uno, y las dos cosas que merece la pena atrapar ocupan cada una una línea.
Aquí está lo que guía tras guía cuenta mal: la respuesta no es leer con más cuidado. A la velocidad a la que trabajan estas herramientas, leer con cuidado no escala. Lo que escala es comprobar los dos resultados que importan, desde fuera y a posteriori.
La mitad de tu app que es pública pase lo que pase
Toda su fachada.
Piénsalo como una tienda. Todo lo que Windsurf construye en tu interfaz es el escaparate, y el escaparate se le entrega entero a cada visitante: un navegador no puede mostrar una página que no le enviaron. Detrás está el almacén, tu base de datos, un edificio aparte en internet con su propia dirección y su propia cerradura.
La distinción importa porque leer código te habla de intención, y la intención no es lo que se publica. Lo que se publica es la salida de compilación: un paquete de JavaScript, montado a partir de cada archivo editado, entregado a cualquiera que cargue tu web. Ese paquete es lo que merece inspección, y es mucho más corto de buscar que el fuente del que salió.
¿Es un problema una clave en el bundle de tu app de Windsurf?
Normalmente no. Depende de cuál sea, y las dos se parecen casi por completo.
Una clave publicable nombra tu proyecto y no hace nada más:
sb_publishable_… en los proyectos nuevos de Supabase, anon en los antiguos.
Está pensada para poder leerse, y encontrarla no es un hallazgo. Una clave
secreta, sb_secret_… o la antigua service_role, se salta todas las reglas
que hayas escrito y lee y escribe cada fila de cada tabla.
Cómo llega la segunda merece conocerse, porque no es descuido. A un asistente al
que le pides que un componente del navegador hable con tu base de datos escribe
código que funciona, y si ese código necesita una clave secreta, la clave va a
donde el código se ejecuta. Vite dice sin rodeos que un valor con prefijo VITE_
se empaqueta en tu fuente al compilar; Next.js hace lo mismo con NEXT_PUBLIC_.
Nada te avisa, porque desde el punto de vista de la herramienta pediste
exactamente esto.
Leer qué clave tienes lleva
alrededor de un minuto.
La única regla que sobrevive al código que no has leído
Row Level Security, si tus datos están en Supabase: un interruptor por tabla que decide fila a fila quién puede leer qué.
Por eso es la comprobación que merece la pena. Toda petición llega a la base de datos, la haya hecho el archivo que la haya hecho y la escribiera quien la escribiera. Una regla aplicada ahí vale para todas a la vez, incluido el código del cambio que ojeaste. Ninguna cantidad de código sin revisar cambia lo que recibe de vuelta una petición sin autenticar.
Dos cosas deciden si la tienes. Supabase activa Row Level Security por defecto en las tablas creadas en el Table Editor del panel, y no en las creadas ejecutando SQL, que es como las crea una migración generada. Y el interruptor es solo la mitad del asunto: una política que permite a todo el mundo deja la tabla abierta mientras el panel la declara asegurada.
Cómo revisar tu propio proyecto de Windsurf en unos diez minutos
Busca en la compilación, no en el fuente. Compila el proyecto y luego busca
en los archivos de salida service_role, sb_secret_ y sk_live_. Un comando,
y cubre todos los archivos que tocó el asistente, los abrieras o no.
Lee las variables con prefijo. Todo lo que se llame VITE_… o
NEXT_PUBLIC_… está publicado. Para cada una, pregúntate si la pondrías en tu
página de inicio.
Abre Authentication → Policies en Supabase. Cualquier tabla listada con Row Level Security desactivado le responde a quien tenga la dirección de tu proyecto, y esa dirección está en tu app.
Y luego mira desde fuera. Las tres comprobaciones de arriba te dicen qué está configurado. A qué llega de verdad un desconocido es otra pregunta, y es la que responde nuestro escaneo gratuito: lee tu web en vivo como un visitante y te da una nota en unos 20 segundos, sin cuenta: escanea tu app.
Qué hacer
- Revisa por resultado, no por diff. A esta velocidad, leer cada línea cambiada no es un plan.
- Lo que se publica es el bundle compilado. Buscarlo es más rápido y más veraz que leer el fuente del que salió.
- Una clave publicable en el navegador es correcta.
sb_secret_…yservice_roleson las que hay que renovar. - Un asistente pone una clave donde el código que escribió la necesita. Mantenerla fuera del navegador nunca formó parte de la petición.
- Row Level Security es la comprobación que sobrevive al código que nunca leíste, porque toda petición tiene que pasar por la base de datos.
Compila tu proyecto y busca service_role y sk_live_ en la salida: lleva un
minuto y da una respuesta sin dudas sobre el cambio que no leíste. Después, la
lista de seguridad en 10 minutos cubre el resto.
Qué puede salir mal de verdad con una app creada con Windsurf
Nada de esto significa que hicieras algo mal: son los efectos secundarios normales de un agente que escribe mucho código deprisa. Esto es lo que conviene comprobar:
Una clave secreta que el agente conectó por ti
Para que una integración funcione a la primera, el agente a veces escribe la clave directamente en el código, y si ese archivo se ejecuta en el navegador, cualquiera puede leerla. Algunas claves están hechas para ser públicas y eso está bien. Reeve lee el código cargado de tu app, encuentra las claves y te dice cuáles son seguras y cuáles deben moverse al servidor.
Un .env subido o una carpeta .git expuesta
Las claves van en un archivo .env que nunca se publica. Pero un cambio que toca decenas de archivos se acepta fácil sin leer todas sus rutas: el .env acaba subido, o la carpeta oculta .git desplegada, y todo tu historial, claves incluidas, queda a una descarga. Reeve comprueba si alguno de los dos es accesible desde fuera.
Tu base de datos abierta (RLS desactivado)
Si tu app guarda datos (normalmente en Supabase u otro Postgres), es Row Level Security quien decide quién puede leer o cambiar cada fila. Desactivarlo es una forma rápida de hacer que algo funcione mientras construyes, y suele quedarse así. Reeve lo comprueba contando filas, nunca leyéndolas.
Almacenamiento de archivos público
Lo que se sube acaba en "buckets" de almacenamiento, y un bucket público deja que cualquiera liste y descargue lo que hay dentro: facturas, documentos de identidad, fotos privadas. Reeve comprueba si tus buckets se pueden listar; nunca descarga los archivos de nadie.
Source maps activados
Un source map le entrega a quien mire una copia legible de tu código original. Útil mientras construyes y un regalo para un desconocido una vez estás en producción, porque hace más fácil encontrar cualquier otro fallo. Reeve comprueba si los tuyos salieron con la build.
Cabeceras de seguridad ausentes y endpoints abiertos
Unos cuantos ajustes le dicen al navegador cómo proteger a tus visitantes; aparte está la cuestión de si tus endpoints de datos responden a cualquiera, desde cualquier web. Por separado son pequeños; juntos deciden cuánto puede hacer un desconocido con lo que encuentre. Reeve señala lo que falta.
Qué es Reeve, y qué no
Reeve es una comprobación gratuita, de solo lectura y desde fuera, como un inspector que prueba las puertas sin entrar. Es rápida y detecta los errores comunes de alto impacto. No es una auditoría de seguridad completa, y una nota limpia no es garantía. Significa que las puertas obvias están cerradas.
Windsurf es un editor, no un alojamiento: escribe y ejecuta código contigo, pero no despliega tu app ni la vigila después. Esa parte depende de ti y de lo que el agente haya producido. Revisar un cambio grande antes de aceptarlo es aquí la mejor costumbre, y si usas Supabase su propio advisor avisa de problemas de base de datos. Lo que añade Reeve es la mirada desde fuera: qué expone de verdad la app que publicaste, en palabras claras sobre las que puedes actuar. Y si prefieres no pensar en ello, podemos vigilarla por ti.
¿Quieres que se gestione, no solo que se compruebe?
Reeve Care sigue vigilando tu app, respalda tus datos y te ayuda a arreglar cosas cuando se rompen, para que puedas seguir creando en vez de preocuparte.
Conoce Reeve CarePreguntas frecuentes
¿Es seguro el código que escribe el agente de Windsurf?
Suele ser buen código, pero "lo escribió el agente" no significa "alguien comprobó que fuera seguro". Los cambios agénticos optimizan un resultado que funcione, y para eso a veces dejan una clave en el sitio equivocado o desactivan una regla de la base de datos para saltarse un error. La única forma de saberlo es mirar qué queda expuesto. Reeve lo hace gratis en unos 20 segundos.
Cascade cambió muchos archivos a la vez, ¿cómo sé qué quedó expuesto?
Leyendo, casi nunca puedes. Esa es la respuesta honesta, y por eso ayuda mirar desde fuera: en vez de auditar un diff, Reeve mira la app que realmente desplegaste e informa de lo que puede alcanzar un desconocido: claves en el navegador, una base de datos abierta, archivos descargables, un .env expuesto.
¿Cómo sé si mi app de Windsurf está filtrando claves de API?
La causa habitual es una clave escrita en código que se ejecuta en el navegador, donde "oculto" no existe. Reeve lee el código cargado de tu app, encuentra las claves y te dice cuáles pueden ser públicas y cuáles deben moverse al servidor, sin guardar nunca los valores reales.
¿Analizar mi app de Windsurf cambiará algo?
No. Reeve solo mira lo que ya es público desde fuera. Nunca inicia sesión, nunca cambia nada y nunca descarga tus archivos. Solo lectura, como comprobar si una puerta está cerrada sin entrar.
Un agente cambió archivos que nunca abrí. ¿Cómo se supone que reviso eso?
Línea a línea no, y esa es la respuesta honesta. Revisa por resultado: compila el proyecto y busca en la salida las formas de clave secreta, y luego mira qué devuelve tu base de datos a una petición sin sesión iniciada. Las dos cosas llevan minutos y las dos atrapan los dos fallos que de verdad importan, cambiaran los archivos que cambiaran.
¿Un asistente de IA mete secretos en mi frontend a propósito?
Los mete donde el código que escribió los necesita. Si un componente que se ejecuta en el navegador se escribió para llamar a algo que exige una clave secreta, la clave tiene que estar en el navegador para que ese código funcione, así que el asistente hace que funcione. La instrucción de mantenerla en un servidor nunca estuvo en la petición.
¿Qué comprobación única me dice más sobre mi app?
Si Row Level Security está activado en todas las tablas, y si las políticas restringen de verdad a alguien. Es la única regla que se aplica a toda petición venga del archivo que venga, así que sobrevive a cualquier cantidad de código que no hayas leído.