[{"data":1,"prerenderedAt":664},["ShallowReactive",2],{"blog-es-rotate-supabase-service-role-key":3,"blog-index-es":423},{"id":4,"title":5,"body":6,"category":380,"cover":381,"coverAlt":382,"description":383,"draft":384,"extension":385,"faq":386,"image":401,"keywords":402,"meta":411,"navigation":412,"ogTitle":413,"path":414,"published":415,"seo":416,"stem":417,"tldr":418,"updated":415,"__hash__":422},"blog_es\u002Fblog\u002Frotate-supabase-service-role-key.md","Cómo rotar una clave service_role de Supabase filtrada",{"type":7,"value":8,"toc":365},"minimark",[9,24,27,30,33,41,52,55,70,81,85,88,95,101,104,110,114,120,123,148,151,154,161,170,176,206,218,223,231,241,245,248,265,275,281,285,288,291,294,304,308,311,314,320,324,355],[10,11,12,13,17,18,23],"p",{},"Alguien te ha dicho que tu clave ",[14,15,16],"code",{},"service_role"," de Supabase está en tu app,\ndonde cualquiera puede leerla. Antes de cambiar nada, asegúrate de que es esa la\nclave que encontraron: ",[19,20,22],"a",{"href":21},"\u002F#scan","nuestro escaneo gratuito"," lee tu sitio en\nproducción igual que lo leería un desconocido y te dice qué clave de Supabase ve\nahí de verdad. Sin cuenta y sin instalar nada.",[10,25,26],{},"El consejo que sigue a un hallazgo así es casi siempre una palabra: rota. Luego\nbuscas cómo se hace y las fuentes se contradicen. La propia documentación de\nSupabase abre su guía de rotación diciéndote que arregles la causa de la fuga\nantes de empezar. Media docena de guías de terceros te dicen que rotes de\ninmediato y preguntes después.",[10,28,29],{},"Esta es la parte que ninguna de las dos escribe: las dos tienen razón en\nsituaciones distintas, y la pregunta que las separa es adónde se filtró la\nclave.",[10,31,32],{},"Una cosa clara antes de todo. Borrar la clave de tu código quita tu propia copia\ndel llavero. Rotarla cambia la cerradura. Solo lo segundo alcanza las copias que\notros ya tienen.",[34,35,37,38,40],"h2",{"id":36},"es-de-verdad-la-clave-service_role","¿Es de verdad la clave ",[14,39,16],{},"?",[10,42,43,44,47,48,51],{},"En un proyecto nuevo lo responden los primeros caracteres. ",[14,45,46],{},"sb_secret_"," al\nprincipio es la secreta. ",[14,49,50],{},"sb_publishable_"," es la clave que debe estar en tu app,\ny encontrarla ahí no es ningún hallazgo.",[10,53,54],{},"Asegúrate antes de hacer nada drástico, porque la clave que aparece en una app\nhecha con vibe coding suele ser la que sí pertenece a ese sitio.",[10,56,57,58,61,62,64,65,69],{},"Los proyectos antiguos entregan otro par, ",[14,59,60],{},"anon"," y ",[14,63,16],{},", y las dos se\nparecen muchísimo: mismo formato, misma longitud, ningún prefijo que leer. La\nsección central de una de esas claves no está cifrada en absoluto. Se decodifica\nen unas líneas de texto plano, y una de ellas indica el rol.\n",[19,66,68],{"href":67},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Qué claves de API son seguras en tu frontend","\nrecorre las dos comprobaciones.",[10,71,72,73,75,76,80],{},"El motivo para asegurarte es que esto es más raro de lo que sugieren las\nadvertencias. Escaneamos 30.998 apps hechas con vibe coding en agosto de 2026 y\nencontramos una clave ",[14,74,16],{}," publicada en 3 de ellas. Una clave de API\nde Google, que suele ser inofensiva y a menudo está limitada a un dominio,\napareció en 1.142.\n",[19,77,79],{"href":78},"\u002Fresearch\u002Fvibe-coded-app-security-2026","El recuento completo está aquí",".",[34,82,84],{"id":83},"rotar-primero-o-cerrar-la-fuga-primero","¿Rotar primero o cerrar la fuga primero?",[10,86,87],{},"Depende de si la clave ya es pública, y la línea entre los dos casos es limpia.",[10,89,90,94],{},[91,92,93],"strong",{},"Si la clave está en el JavaScript que descargan tus visitantes, ya es\npública."," Cualquiera que cargara tu sitio mientras estaba activa tiene una\ncopia, y también la tiene cualquier rastreador automático que fuera buscando\nexactamente esa cadena. Nada de lo que cambies en tu código alcanza esas copias.\nRota primero y después cierra la fuente.",[10,96,97,100],{},[91,98,99],{},"Si solo llegó a un repositorio privado, un archivo de registro, una variable\nde CI o un chat, la exposición está acotada."," Si aquí rotas primero, lo harás\ndos veces, porque el siguiente despliegue vuelve a sacar el valor viejo de\naquello que lo produjo y tu clave nueva sale detrás de la vieja. Cierra la\nfuente y luego rota.",[10,102,103],{},"La guía de Supabase está escrita para el segundo caso. Las guías urgentes están\nescritas para el primero. Si estás leyendo esto porque un escáner encontró la\nclave en tu URL en producción, estás en el primer caso.",[105,106],"diagram",{"alt":107,"caption":108,"src":109},"Dos carriles. El de arriba empieza en una ventana de navegador y pasa por el paso uno, una llave con una flecha de rotación, y luego el paso dos, un par de corchetes angulares. El de abajo empieza en un archivo y recorre los mismos dos pasos en orden inverso, primero los corchetes y después la llave.","Las mismas dos tareas, en orden inverso. Lo que lo decide es si la copia filtrada ya anda suelta por el mundo.","\u002Fblog\u002Frotate-supabase-service-role-key\u002Ftwo-orders-1600x640.png",[34,111,113],{"id":112},"cómo-rotar-una-clave-secreta-de-supabase","Cómo rotar una clave secreta de Supabase",[10,115,116,117,119],{},"Si tu proyecto tiene claves ",[14,118,46],{},", esto es cosa del panel y sin caída de\nservicio.",[10,121,122],{},"Un proyecto puede tener varias claves secretas a la vez, cada una con su nombre,\ny eso es lo que lo hace seguro: añades la nueva antes de quitar la vieja, así\nque entre medias no hay nada roto.",[124,125,126,134,142,145],"ol",{},[127,128,129,130,133],"li",{},"Abre tu proyecto, ve a ",[91,131,132],{},"Settings → API Keys"," y crea una clave secreta\nnueva.",[127,135,136,137,141],{},"Ponla en todos los sitios donde se usaba la vieja, que deberían estar todos\nen un servidor: edge functions, webhooks, tareas programadas, un backend\npropio. ",[19,138,140],{"href":139},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Dónde viven esos valores"," si\nnunca has abierto esa página.",[127,143,144],{},"Despliega y luego recorre las partes de tu app que leen y escriben datos. Una\nclave secreta incorrecta falla de forma ruidosa e inmediata, que es el caso\nbueno.",[127,146,147],{},"Solo entonces borra la clave comprometida.",[10,149,150],{},"El paso 4 es permanente. Supabase borra una clave secreta del todo: sin deshacer,\nsin reactivar, sin copia aparcada que puedas recuperar. Por eso va al final.",[10,152,153],{},"Borrar una clave secreta no cierra la sesión de tus usuarios. Una clave de API\ndice qué aplicación está llamando a tu base de datos, y el token de sesión de un\nvisitante dice qué usuario es. Lo segundo se comprueba contra la clave de firma\nde tu proyecto, y ese es un valor aparte que no has tocado.",[34,155,157,158,160],{"id":156},"por-qué-una-clave-service_role-antigua-de-supabase-no-se-puede-rotar","Por qué una clave ",[14,159,16],{}," antigua de Supabase no se puede rotar",[10,162,163,164,166,167,169],{},"Porque no hay botón para ello. La nota de resolución de problemas de Supabase\ndice que la rotación directa de los secretos antiguos ",[14,165,60],{},", ",[14,168,16],{}," y\nJWT ya no está soportada, y te remite a las claves nuevas.",[10,171,172,173,175],{},"Así que invalidar una clave ",[14,174,16],{}," antigua filtrada es una migración y\nno una rotación:",[124,177,178,189,195,200],{},[127,179,180,183,184,61,186,188],{},[91,181,182],{},"Crea las claves nuevas."," Esto añade ",[14,185,50],{},[14,187,46],{}," junto\nal par antiguo. Los dos sistemas funcionan a la vez y no se rompe nada.",[127,190,191,194],{},[91,192,193],{},"Mueve tu frontend a la clave publicable."," En Lovable o Bolt esto suele ser\nun valor en los ajustes de tu proyecto y no una línea de código.",[127,196,197],{},[91,198,199],{},"Mueve todo uso del lado del servidor a la clave secreta.",[127,201,202,205],{},[91,203,204],{},"Desactiva las claves antiguas"," en los ajustes de tu proyecto.",[10,207,208,209,211,212,214,215,217],{},"El paso 4 es un solo interruptor y afecta a las dos claves antiguas. ",[14,210,60],{}," y\n",[14,213,16],{}," son JWT firmados con el mismo secreto, así que el interruptor que\nrevoca una revoca la otra, y un frontend que todavía lleve la clave ",[14,216,60],{}," vieja\ndeja de funcionar en el momento en que lo accionas. Por eso el paso 2 va antes.",[105,219],{"alt":220,"caption":221,"src":222},"Un panel de ajustes con cuatro filas. Las dos de arriba, sb_publishable_ y sb_secret_, llevan cada una un punto relleno y un valor que se puede leer. Bajo un separador, anon y service_role aparecen apagadas con sus valores enmascarados como puntos, y una llave de corchete une esas dos filas a un único interruptor en posición de apagado.","Desactivar las claves antiguas es un solo control para las dos. La clave anon que usa tu app se va junto con la clave service_role que quieres invalidar.","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fone-switch-two-keys-1600x720.png",[10,224,225,226,230],{},"Desactivar es reversible, que es la única buena noticia de esta sección: si algo\nque olvidaste resulta que todavía usa una clave antigua, puedes volver a\nencenderlas mientras lo arreglas.\n",[19,227,229],{"href":228},"\u002Fblog\u002Fsupabase-new-api-keys","Qué implica la migración"," lo cuenta con más\ndetalle.",[232,233,235],"callout",{"type":234},"warn",[10,236,237,240],{},[91,238,239],{},"Hasta el paso 4, la clave filtrada sigue funcionando."," Los pasos 1 a 3 añaden\nuna segunda vía de entrada; no quitan nada. En un proyecto donde la clave ya es\npública, eso es lo que hace incómodo este orden, y es el motivo para hacer los\ncuatro pasos seguidos. Una migración a medias deja la clave vieja activa y tu\napp funcionando con dos sistemas de claves a la vez.",[34,242,244],{"id":243},"de-dónde-se-filtró-la-clave-y-cómo-cerrarlo","De dónde se filtró la clave, y cómo cerrarlo",[10,246,247],{},"Tres causas explican casi todo, y las tres están dentro de tu propio proyecto.",[10,249,250,260,261,264],{},[91,251,252,253,256,257,80],{},"Un prefijo ",[14,254,255],{},"VITE_"," o ",[14,258,259],{},"NEXT_PUBLIC_"," No son un ajuste de seguridad que\nalguien olvidó activar. Son una instrucción para la compilación: mete este valor\nen el bundle. Una variable llamada ",[14,262,263],{},"VITE_SUPABASE_SERVICE_ROLE_KEY"," se compiló\nen tu JavaScript a propósito, por una herramienta que hizo exactamente lo que se\nle dijo.",[10,266,267,270,271,274],{},[91,268,269],{},"Un valor pegado directamente en un componente."," Sin prefijo de por medio y\nsin archivo ",[14,272,273],{},".env",", solo la clave en una línea de código porque era la forma más\nrápida de que una consulta devolviera algo.",[10,276,277,280],{},[91,278,279],{},"Trabajo que pertenece a un servidor."," Borrar una cuenta, escribir en una\ntabla en la que tus usuarios no pueden escribir, leer filas de todo el mundo. Se\nechó mano de la clave porque el navegador no podía hacer el trabajo, y la\nsolución es mover el trabajo: una edge function, una ruta serverless, cualquier\ncosa que tus visitantes no descarguen.",[34,282,284],{"id":283},"cómo-sé-si-alguien-la-usó","¿Cómo sé si alguien la usó?",[10,286,287],{},"Normalmente no puedes estar seguro. Lo que sí puedes hacer es acotar la ventana\ny mirar dentro.",[10,289,290],{},"La ventana se abre con el despliegue que publicó la clave por primera vez y se\ncierra cuando la desactivaste. Tu proyecto de Supabase guarda registros de la\nAPI y de la base de datos, y ese es el rango al que hay que filtrarlos. Lo que\nbuscas son lecturas y escrituras que no puedas justificar: peticiones a tablas\nque tu app nunca toca, tráfico a horas en las que nadie la estaba usando,\nborrados que no hizo nadie.",[10,292,293],{},"Después revisa los datos en sí. Recuentos de filas frente a lo que esperas, tus\npropios registros de cuenta, cualquier cosa con una marca de tiempo que se movió\nmientras nadie trabajaba. Un mensaje de soporte sobre datos que cambiaron solos\nes como se descubren de verdad la mayoría de estos casos, y llega semanas\ndespués.",[10,295,296,297,299,300,80],{},"Una clave ",[14,298,16],{}," no alcanza a tu proveedor de pagos ni a tu envío de\ncorreo. Aun así conviene saber si era la única clave de tu bundle, porque las\nque gastan dinero se filtran por el mismo camino:\n",[19,301,303],{"href":302},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","qué publicaron 30.998 apps",[34,305,307],{"id":306},"revisa-tu-app-en-producción-antes-de-darlo-por-hecho","Revisa tu app en producción antes de darlo por hecho",[10,309,310],{},"Carga tu sitio en una ventana privada, abre el JavaScript que descargó tu\nnavegador y busca en él el valor viejo. Busca después el nuevo, que tampoco\ndebería estar ahí.",[10,312,313],{},"Dos cosas hacen que valga la pena comprobarlo a mano. Una compilación puede\nservir un bundle cacheado un rato después de que despliegues, así que el archivo\nque recibe un visitante no siempre es el que acabas de construir. Y una clave\npuede estar en más de un sitio: un segundo punto de entrada, un service worker,\nuna compilación vieja que todavía se sirve desde una ruta que nadie enlaza.",[10,315,316,317,80],{},"Nuestro escaneo gratuito hace esta parte desde fuera, sobre la URL que usan tus\nvisitantes de verdad, y decodifica una clave de Supabase lo suficiente para leer\nel rol, así que una clave publicable vuelve con una marca de correcto. Tarda\nunos veinte segundos y no necesita cuenta: ",[19,318,319],{"href":21},"escanea tu app",[34,321,323],{"id":322},"qué-hacer-ahora","Qué hacer ahora",[325,326,327],"key-takeaways",{},[328,329,330,340,343,346,349,352],"ul",{},[127,331,332,333,335,336,339],{},"Confirma primero la clave. ",[14,334,46],{}," al principio, o ",[14,337,338],{},"\"role\": \"service_role\""," dentro de una más antigua. Una clave publicable en tu frontend no es un hallazgo.",[127,341,342],{},"Si está en el bundle que descargan tus visitantes, rótala antes de cambiar código. Editar tu app no alcanza las copias que ya circulan.",[127,344,345],{},"Si solo se filtró a un repositorio, un registro o un chat, cierra primero la fuente, para que tu siguiente despliegue no vuelva a sacar la clave nueva.",[127,347,348],{},"En un proyecto nuevo: crea una segunda clave secreta, mueve el código de tu servidor a ella, despliega y luego borra la vieja. Borrar es permanente.",[127,350,351],{},"En un proyecto antiguo no hay botón de rotar. Crea las claves nuevas, mueve tu frontend y tu servidor a ellas, y después desactiva el par antiguo con el único interruptor que afecta a los dos.",[127,353,354],{},"Busca luego en tu bundle en producción. Una compilación cacheada puede servir el valor viejo un rato después de que despliegues.",[10,356,296,357,359,360,364],{},[14,358,16],{}," lee y escribe cada fila de tu base de datos. La peor\nversión de esta historia acaba con una tabla vacía, y que esas filas vuelvan\ndepende de\n",[19,361,363],{"href":362},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","qué estabas respaldando"," antes\nde que ocurriera todo esto.",{"title":366,"searchDepth":367,"depth":367,"links":368},"",3,[369,372,373,374,376,377,378,379],{"id":36,"depth":370,"text":371},2,"¿Es de verdad la clave service_role?",{"id":83,"depth":370,"text":84},{"id":112,"depth":370,"text":113},{"id":156,"depth":370,"text":375},"Por qué una clave service_role antigua de Supabase no se puede rotar",{"id":243,"depth":370,"text":244},{"id":283,"depth":370,"text":284},{"id":306,"depth":370,"text":307},{"id":322,"depth":370,"text":323},"Fundamentos de seguridad","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcover-1200x630.png","Un candado con dos llaves idénticas al lado, dibujadas del mismo tamaño, una brillante y otra apagada.","Supabase dice que primero cierres la fuga. Otras guías dicen que rotes ya. Cuál es lo correcto depende de dónde se filtró tu clave service_role.",false,"md",[387,390,393,396,398],{"q":388,"a":389},"¿Rotar la clave rompe mi app en producción?","No si lo haces en orden. En un proyecto con las claves nuevas añades una segunda clave secreta, mueves el código de tu servidor a ella, despliegas y solo entonces borras la vieja, así que nunca hay un momento sin una clave que funcione. En un proyecto antiguo el riesgo es otro: desactivar el par antiguo también desactiva la clave anon que usa tu frontend, así que tu app se cae salvo que ya esté con la clave publicable cuando acciones ese interruptor.",{"q":391,"a":392},"¿Puedo rotar las claves antiguas anon y service_role?","No. La documentación de resolución de problemas de Supabase dice que la rotación directa de los secretos antiguos anon, service_role y JWT ya no está soportada. Invalidar una clave antigua filtrada significa crear las nuevas claves sb_publishable_ y sb_secret_, mover tu app y el código de tu servidor a ellas, y después desactivar el par antiguo en los ajustes de tu proyecto.",{"q":394,"a":395},"¿Borro la clave vieja o la desactivo?","No puedes elegir, porque los dos sistemas de claves se comportan distinto. Una clave sb_secret_ nueva se borra, de forma permanente, sin manera de recuperarla. El par antiguo se desactiva, y desactivar sí es reversible: si algo que olvidaste resulta que todavía usa una clave vieja, puedes volver a encenderlas mientras lo arreglas.",{"q":284,"a":397},"Normalmente no puedes estar seguro. Redúcelo a una ventana de tiempo: la clave fue utilizable desde el despliegue que la publicó por primera vez hasta el momento en que la desactivaste. Filtra los registros de la API y de la base de datos de tu proyecto de Supabase a ese rango y busca lecturas y escrituras que no puedas justificar; después revisa tus datos en busca de recuentos de filas y marcas de tiempo que no cuadren con nada que hicieras.",{"q":399,"a":400},"¿Tengo que rotar también mi clave anon?","En un proyecto antiguo no puedes elegir: desactivar el par antiguo se lleva las dos claves a la vez, así que tu frontend necesita la clave publicable nueva antes de que acciones el interruptor. En un proyecto nuevo la clave publicable está pensada para ser pública y no hay motivo para tocarla. Lo que sí conviene revisar en ambos casos es Row Level Security, porque es lo único que se interpone entre una clave publicable y toda tu base de datos.","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",[403,404,405,406,407,408,409,410],"rotar clave service role supabase","cómo rotar la service role key en supabase","clave service role de supabase filtrada","clave service role de supabase expuesta","rotación de claves supabase","revocar clave api supabase","desactivar claves api antiguas supabase","service role key en el frontend",{},true,"Rota una clave service_role filtrada, en el orden correcto","\u002Fblog\u002Frotate-supabase-service-role-key","2026-09-08",{"title":5,"description":383},"blog\u002Frotate-supabase-service-role-key",[419,420,421],"Si tu clave service_role de Supabase está en el JavaScript que descarga un navegador, rótala antes de arreglar nada. La copia que ya circula no caduca.","Si solo llegó a un repositorio privado o a un registro, cierra primero la fuente, o tu clave nueva saldrá detrás de la vieja en el siguiente despliegue.","Una clave service_role antigua no se puede rotar. Invalidarla significa crear las nuevas claves sb_secret_, mover tu app a ellas y desactivar el par antiguo con un interruptor que afecta a los dos.","Jomk05IJT2d6v3VI_H_VeHK3YGly4W-fD40KA2oMegc",[424,431,437,443,449,455,461,467,473,479,485,491,497,503,509,515,516,522,528,534,540,546,551,557,563,569,575,580,586,592,598,604,610,616,622,628,633,638,644,650,655,660],{"path":425,"title":426,"description":427,"published":428,"category":429,"image":430,"draft":384},"\u002Fblog\u002Fsupabase-backup-auth-users","Por qué tu dump de Supabase no tiene usuarios dentro","Ejecuta supabase db dump por sí solo y obtienes la forma de tu base de datos y ninguna de sus filas, sin el esquema auth donde viven tus usuarios.","2026-09-23","Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":432,"title":433,"description":434,"published":435,"category":380,"image":436,"draft":384},"\u002Fblog\u002Fdomain-and-certificate-expiry","Dominio caducado, web caída: qué pasa a partir de ahora","Tu dominio caducó y tu web está caída. Aquí tienes el reloj que acaba de arrancar, por qué el certificado es el menor problema, y cómo comprobar ambos.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":438,"title":439,"description":440,"published":441,"category":380,"image":442,"draft":384},"\u002Fblog\u002Fis-lovable-safe","¿Es seguro Lovable? Lo que vimos en 18.554 aplicaciones Lovable","¿Es seguro Lovable? Pasamos 18.554 aplicaciones Lovable por nueve comprobaciones. La plataforma fue la más limpia de cinco. Los hallazgos estaban dentro.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":444,"title":445,"description":446,"published":447,"category":380,"image":448,"draft":384},"\u002Fblog\u002Fvibe-coded-app-security-checklist","La lista de seguridad del vibe coding, en nueve comprobaciones","Una lista de seguridad del vibe coding con nueve puntos, cada uno verificable en tu app desde fuera por cualquiera, y cada uno con una prueba de una línea.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":450,"title":451,"description":452,"published":453,"category":380,"image":454,"draft":384},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Una clave secreta de Stripe en tu frontend puede mover dinero","Una clave secreta de Stripe expuesta en tu frontend puede reembolsar, cobrar y leer cada ficha de cliente que tienes. Tu clave pk_live_ sí debe estar ahí.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":456,"title":457,"description":458,"published":459,"category":380,"image":460,"draft":384},"\u002Fblog\u002Fvite-and-next-public-env-vars","Variables de entorno de Vite expuestas: el prefijo dice publica esto","Variables de entorno de Vite expuestas en tu app: hicieron lo que pedía el prefijo. VITE_ y NEXT_PUBLIC_ significan publica esto, y la IA nunca supo el coste.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":462,"title":463,"description":464,"published":465,"category":380,"image":466,"draft":384},"\u002Fblog\u002Fbase44-source-maps","Seguridad en Base44: qué marca un escaneo y qué te toca arreglar a ti","Seguridad en Base44 en 5.438 apps escaneadas: tres hallazgos en casi todas son de la plataforma, el source map es la insignia de Base44 y lo tuyo es poco.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":468,"title":469,"description":470,"published":471,"category":380,"image":472,"draft":384},"\u002Fblog\u002Fis-cursor-ai-safe","¿Es seguro Cursor AI? El editor, el código y la app que publicaste","¿Es seguro Cursor AI? Tres preguntas en una búsqueda: qué guarda Cursor, en qué falla el código que escribe y si la app que publicaste está abierta.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":474,"title":475,"description":476,"published":477,"category":380,"image":478,"draft":384},"\u002Fblog\u002Fis-replit-safe","¿Es seguro Replit? Lo que vimos en 3.042 aplicaciones Replit en vivo","¿Es seguro Replit? Pasamos 3.042 aplicaciones Replit en vivo por nueve comprobaciones externas. Los hallazgos estaban en la aplicación publicada, no en el host.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":480,"title":481,"description":482,"published":483,"category":429,"image":484,"draft":384},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: tu copia de la base no tiene archivos","Un Supabase storage backup es una tarea aparte. Las copias de la base guardan la lista de tus archivos y ninguno de ellos, así que cada upload queda roto.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":486,"title":487,"description":488,"published":489,"category":429,"image":490,"draft":384},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery de Supabase: precio y límites","El point-in-time recovery de Supabase rebobina tu base de datos a cualquier segundo de la última semana. Cuesta $100 al mes sobre Pro y solo cubre la base.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":492,"title":493,"description":494,"published":495,"category":429,"image":496,"draft":384},"\u002Fblog\u002Fsupabase-project-paused-recover","¿Proyecto de Supabase pausado? Tus datos siguen ahí","Supabase pausó tu proyecto tras una semana sin actividad. No se ha borrado nada, Restaurar está junto al nombre y tienes un año antes de que eso cambie.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":498,"title":499,"description":500,"published":501,"category":380,"image":502,"draft":384},"\u002Fblog\u002Fsafest-ai-app-builder","¿Qué builder de apps con IA es más seguro? 30.998 apps escaneadas","¿Qué builder de apps con IA es más seguro? Escaneamos 30.998 apps activas de Lovable, Base44, Replit, v0 y Bolt. El builder no es lo que decide tu nota.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":504,"title":505,"description":506,"published":507,"category":380,"image":508,"draft":384},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Activa Row Level Security en cada tabla de Supabase y compruébalo","Activar Row Level Security en Supabase sin política cierra la tabla del todo. Una política sin el interruptor no hace nada. Aquí tienes el SQL y la prueba.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":510,"title":511,"description":512,"published":513,"category":380,"image":514,"draft":384},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": lo que el aviso no ve","Supabase marca \"RLS disabled in public\" como error. No dice nada de la política de lectura que deja tu tabla igual de abierta a cualquiera.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":414,"title":5,"description":383,"published":415,"category":380,"image":401,"draft":384},{"path":517,"title":518,"description":519,"published":520,"category":380,"image":521,"draft":384},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Escáneres de seguridad vibe coding comparados, el nuestro incluido","El mejor escáner de seguridad para vibe coding depende de tres preguntas que ninguna lista de funciones responde. Diez herramientas, con precios.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":523,"title":524,"description":525,"published":526,"category":380,"image":527,"draft":384},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: haz tú mismo las cinco comprobaciones","Un Supabase security checker lee tu app publicada en lugar de la configuración de tu proyecto. Estas son las cinco comprobaciones y cómo hacer cada una.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":529,"title":530,"description":531,"published":532,"category":380,"image":533,"draft":384},"\u002Fblog\u002Fvibe-coding-security-scanner","Escáner de seguridad para vibe coding: qué se le escapa","Un escáner de seguridad para vibe coding lee tu app en vivo desde fuera. Qué cubre eso, las cuatro cosas que no puede ver y cómo leer el resultado.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":535,"title":536,"description":537,"published":538,"category":380,"image":539,"draft":384},"\u002Fblog\u002Fmissing-security-headers","Faltan cabeceras de seguridad: cuándo importa de verdad","Que falten cabeceras de seguridad es el hallazgo que más imprime nuestro escáner. Contra qué protegen y cuándo son la línea menos urgente de tu informe.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":541,"title":542,"description":543,"published":544,"category":380,"image":545,"draft":384},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Tu clave de API de OpenAI está expuesta en tu frontend. Rótala.","Una clave de API de OpenAI expuesta en tu frontend no se puede atar a un dominio. Rótala hoy, mueve la llamada a tu servidor y limita el gasto.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":302,"title":547,"description":548,"published":549,"category":380,"image":550,"draft":384},"Clave de API expuesta en el frontend: qué llevan 30.998 apps","Una clave de API expuesta en tu frontend suele ser una clave de Google Maps. Escaneamos 30.998 apps vibe-coded y contamos qué secretos se filtran de verdad.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":552,"title":553,"description":554,"published":555,"category":429,"image":556,"draft":384},"\u002Fblog\u002Fsupabase-backup-tools-compared","Herramientas de backup de Supabase comparadas, la nuestra incluida","Cuatro tipos de herramienta de backup de Supabase, qué copia cada una y cuándo una GitHub Action gratuita le gana a pagar a cualquiera, nosotros incluidos.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":558,"title":559,"description":560,"published":561,"category":380,"image":562,"draft":384},"\u002Fblog\u002Freplit-secrets-explained","Cómo usar secrets en Replit, y qué se publica de todos modos","Cómo usar secrets en Replit: añadir uno, leerlo y arreglar las dos causas del undefined. Y las claves que la herramienta Secrets no puede mantener privadas.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":564,"title":565,"description":566,"published":567,"category":429,"image":568,"draft":384},"\u002Fblog\u002Fback-up-supabase-free-tier","Backups del plan gratuito de Supabase: cómo hacer uno sin terminal","No hay backups en el plan gratuito de Supabase: la copia tienes que hacerla tú. Cómo sacarla desde el panel y qué deja fuera la vía CSV.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":570,"title":571,"description":572,"published":573,"category":380,"image":574,"draft":384},"\u002Fblog\u002Fis-supabase-secure","¿Supabase es seguro? Sí. Tu proyecto es otra pregunta","¿Supabase es seguro? La plataforma está auditada, cifrada y sometida a pentests. Su propia documentación dice dónde termina eso y empiezan tus ajustes.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":139,"title":576,"description":577,"published":578,"category":380,"image":579,"draft":384},"Dónde están tus claves API de Supabase: anon, service_role y URL","La URL del proyecto, la clave anon y la clave service_role están en una sola página del panel. Aquí tienes dónde está, y cuál de los cuatro va en tu app.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":581,"title":582,"description":583,"published":584,"category":380,"image":585,"draft":384},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","New row violates row-level security policy en Supabase. ¿Y ahora?","\"New row violates row-level security policy\" significa que Supabase rechazó una escritura. El arreglo rápido vuelve a abrir la tabla para cualquiera.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":587,"title":588,"description":589,"published":590,"category":380,"image":591,"draft":384},"\u002Fblog\u002Fcors-wildcard-security-risk","¿Es un comodín CORS un riesgo de seguridad? Casi nunca.","¿Es un comodín CORS un riesgo de seguridad? Casi siempre es el ajuste por defecto de tu builder y no entrega nada que tu servidor no diera ya a cualquiera.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":593,"title":594,"description":595,"published":596,"category":429,"image":597,"draft":384},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Supabase branching no es un backup. Solo va hacia adelante.","Por qué el branching de Supabase no es un backup: una rama arranca sin tus datos y un merge solo mueve el esquema. Para qué sirve y qué usar en su lugar.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":599,"title":600,"description":601,"published":602,"category":429,"image":603,"draft":384},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Cómo restaurar un backup de Supabase, y qué se rompe después","Cómo restaurar un backup de Supabase desde el panel o desde un archivo de volcado, qué reemplaza la restauración y por qué tu app puede seguir rota al terminar.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":605,"title":606,"description":607,"published":608,"category":380,"image":609,"draft":384},"\u002Fblog\u002Fsupabase-storage-bucket-public","Tu bucket de Supabase Storage es público. ¿Es un problema?","Un bucket público de Supabase Storage significa que quien tenga la URL de un archivo puede abrirlo. No significa que alguien pueda listar lo que hay dentro.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":611,"title":612,"description":613,"published":614,"category":380,"image":615,"draft":384},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","¿Es un problema una clave de API de Google en tu frontend?","Una clave de API de Google en tu frontend es la clave que más encuentra nuestro escáner, y casi siempre no pasa nada. Un ajuste gratuito decide cuál es cuál.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":617,"title":618,"description":619,"published":620,"category":429,"image":621,"draft":384},"\u002Fblog\u002Fai-agent-deleted-my-database","Un agente de IA borró mis datos de Supabase. ¿Qué puedo recuperar?","Un agente de IA borró datos de tu base. Lo que puedes recuperar ya estaba decidido antes de que se ejecutara, y los próximos minutos deciden el resto.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":623,"title":624,"description":625,"published":626,"category":380,"image":627,"draft":384},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","¿Puede cualquiera leer tu base de datos Supabase? 3.680 apps","¿Puede cualquiera leer tu base de datos Supabase sin iniciar sesión? Escaneamos 30.998 apps activas hechas con builders de IA y medimos cuántas dicen que sí.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":629,"title":630,"description":631,"published":626,"category":380,"image":632,"draft":384},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source maps expuestos: tu app está publicando su código original","Un source map expuesto deja que cualquiera lea el código original de tu app, comentarios incluidos. La comprobación de 30 segundos y lo que de verdad importa.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":228,"title":634,"description":635,"published":636,"category":380,"image":637,"draft":384},"Las nuevas claves de API de Supabase: ¿cuál va en tu app?","Supabase sustituyó anon y service_role por claves publicables y secretas. ¿Cuál pertenece a tu app y cuál no debe estar nunca?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":639,"title":640,"description":641,"published":642,"category":429,"image":643,"draft":384},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","¿Supabase respalda mi base de datos? Depende de tu plan.","¿Supabase respalda tu base de datos? A diario en los planes de pago, y nada en el gratuito. Cómo saber cuál tienes y qué es lo que esa copia no cubre.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":645,"title":646,"description":647,"published":648,"category":380,"image":649,"draft":384},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","Supabase Row Level Security está activado. Tu tabla sigue pública.","Activar Supabase Row Level Security no protege una tabla. Lo hacen tus políticas, y la que arregló tu app rota puede dejar entrar a cualquiera.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":651,"title":652,"description":653,"published":648,"category":429,"image":654,"draft":384},"\u002Fblog\u002Fversion-history-is-not-a-backup","El historial de versiones no es un backup. No recupera una tabla.","Lovable y Bolt guardan un historial de versiones de tu código. Tu base de datos es un servicio aparte, y volver atrás no te devuelve tus datos.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":362,"title":656,"description":657,"published":658,"category":429,"image":659,"draft":384},"Tres formas de respaldar una base Supabase, y qué falta en cada una","El panel, pg_dump y un servicio gestionado. Qué guarda de verdad cada uno, qué deja fuera sin avisar y cuál sobrevive a perder la cuenta.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":67,"title":661,"description":662,"published":658,"category":380,"image":663,"draft":384},"Qué claves de API son seguras en el navegador y cuáles no","Tu clave anon de Supabase está pensada para ser pública. Tu clave service_role no, y se salta todas las reglas que pongas. Cómo distinguirlas.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1790150954097]