[{"data":1,"prerenderedAt":894},["ShallowReactive",2],{"blog-es-supabase-permission-denied-for-table":3,"blog-index-es":543},{"id":4,"title":5,"body":6,"category":503,"cover":504,"coverAlt":505,"description":506,"draft":507,"extension":508,"faq":509,"image":523,"keywords":524,"meta":531,"navigation":532,"ogTitle":533,"path":534,"published":535,"seo":536,"stem":537,"tldr":538,"updated":535,"__hash__":542},"blog_es\u002Fblog\u002Fsupabase-permission-denied-for-table.md","Supabase \"permission denied for table\": el grant que falta",{"type":7,"value":8,"toc":491},"minimark",[9,18,26,31,34,57,60,70,73,76,80,87,107,151,154,160,163,202,206,209,216,225,229,232,238,241,247,262,267,274,278,281,297,300,351,355,358,366,369,393,397,402,436,443,447,485],[10,11,12,13,17],"p",{},"Si tu app corre sobre Supabase, seguramente te ha llegado un email sobre el 30\nde octubre. Dice que nada cambia para las tablas que ya tienes, y a continuación\nte da tres sentencias de SQL. O ya es noviembre: le pediste a Lovable, Bolt o\nCursor una función nueva, la pantalla nueva salió vacía, y en algún lugar de la\nconsola hay un mensaje que dice ",[14,15,16],"code",{},"permission denied for table",". Las dos cosas son\nel mismo cambio de Supabase, visto desde cada lado de la fecha.",[10,19,20,21,25],{},"Aquí está lo que el email se deja fuera: ",[22,23,24],"strong",{},"el SQL que te enseña es la mitad del\narreglo."," Ejecuta esa mitad sola, en la tabla equivocada, y tu app vuelve a\nfuncionar mientras la tabla nueva entrega sus filas a cualquiera que las pida.",[27,28,30],"h2",{"id":29},"qué-significa-permission-denied-for-table-en-supabase","¿Qué significa \"permission denied for table\" en Supabase?",[10,32,33],{},"Significa que el tipo de visitante que hace la petición no tiene ningún acceso a\nesa tabla, así que la base de datos la rechazó antes de mirar una sola fila.",[10,35,36,37,40,41,44,45,48,49,52,53,56],{},"Supabase clasifica cada petición en un ",[22,38,39],{},"rol",", que es el tipo de visitante del\nque viene. ",[14,42,43],{},"anon"," es alguien que no ha iniciado sesión. ",[14,46,47],{},"authenticated"," es\nalguien que sí. ",[14,50,51],{},"service_role"," es tu propio código de servidor usando la clave\nsecreta. Un ",[22,54,55],{},"grant"," es la sentencia que da a uno de esos roles acceso a una\ntabla en Postgres, la base de datos sobre la que corre Supabase. Sin grant no\nhay acceso, escribas lo que escribas en otro sitio.",[10,58,59],{},"Cuando falta el grant, Supabase responde así, normalmente como un 401 o un 403:",[61,62,67],"pre",{"className":63,"code":65,"language":66},[64],"language-text","{\n  \"code\": \"42501\",\n  \"message\": \"permission denied for table comments\",\n  \"hint\": \"Grant the required privileges to the current role with: GRANT SELECT ON public.comments TO anon;\"\n}\n","text",[14,68,65],{"__ignoreMap":69},"",[10,71,72],{},"La pista es la parte útil. Nombra el rol que fue rechazado y la sentencia exacta\nque lo dejaría pasar.",[10,74,75],{},"Piensa en cada tabla como una habitación. El grant es la puerta, y hay una\npuerta distinta para cada rol. Row Level Security, las reglas por fila que quizá\nya conozcas, decide qué cajones puede abrir un visitante una vez dentro.\n\"Permission denied for table\" significa que alguien está delante de una puerta\ncerrada. Nunca llegó hasta tus reglas.",[27,77,79],{"id":78},"qué-cambia-el-30-de-octubre","¿Qué cambia el 30 de octubre?",[10,81,82,83,86],{},"Las tablas nuevas del esquema ",[14,84,85],{},"public",", la carpeta de tablas que usa tu builder\nsalvo que le digas otra cosa, empiezan a llegar con las puertas cerradas.",[10,88,89,90,92,93,95,96,98,99,106],{},"Hasta ahora, Supabase abría automáticamente las tres puertas de cada tabla\nnueva: leer, añadir, cambiar y borrar, para ",[14,91,43],{},", ",[14,94,47],{}," y\n",[14,97,51],{}," por igual. Una tabla era alcanzable desde tu app en cuanto\nexistía, y tus reglas de Row Level Security eran lo único entre un desconocido y\nsus filas. El\n",[100,101,105],"a",{"href":102,"rel":103},"https:\u002F\u002Fsupabase.com\u002Fchangelog\u002F45329-breaking-change-tables-not-exposed-to-data-and-graphql-api-automatically",[104],"nofollow","changelog","\nde Supabase da el motivo sin rodeos: los agentes y las plataformas de IA crean\nahora tablas sin que nadie revise el cambio, y los grants automáticos exponían\ntablas que \"a developer forgot to protect\", que alguien olvidó proteger.",[108,109,110,123],"table",{},[111,112,113],"thead",{},[114,115,116,120],"tr",{},[117,118,119],"th",{},"Fecha",[117,121,122],{},"Qué pasó o qué pasa",[124,125,126,135,143],"tbody",{},[114,127,128,132],{},[129,130,131],"td",{},"28 de abril de 2026",[129,133,134],{},"Los proyectos nuevos podían renunciar a los grants automáticos al crearse.",[114,136,137,140],{},[129,138,139],{},"30 de mayo de 2026",[129,141,142],{},"Empezó a desplegarse \"sin grants automáticos\" como opción por defecto en nuevos.",[114,144,145,148],{},[129,146,147],{},"30 de octubre de 2026",[129,149,150],{},"Los proyectos existentes también dejan de recibirlos.",[10,152,153],{},"Si tu proyecto se creó después de finales de mayo, puede que ya funcione así,\nporque Supabase fue desplegando el nuevo valor por defecto en los proyectos\nnuevos durante las semanas siguientes a esa fecha.",[155,156],"diagram",{"alt":157,"caption":158,"src":159},"Una línea de tiempo con una marca en 2026-10-30. Antes de ella, tres tablas con las puertas abiertas: dos tienen un candado sobre sus filas, y la tercera no tiene ninguno y sus filas son ámbar. Después, dos tablas nuevas con las puertas cerradas.","Las tablas que existen el 30 de octubre conservan las puertas que tienen, incluida una que estaba abierta a desconocidos. Solo las tablas creadas después empiezan con la puerta cerrada.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fbefore-and-after-october-30-1600x620.png",[10,161,162],{},"Tres detalles que conviene saber antes de la fecha:",[164,165,166,184,196],"ul",{},[167,168,169,175,176,179,180,183],"li",{},[22,170,171,172,174],{},"Solo el esquema ",[14,173,85],{},"."," Storage y el inicio de sesión guardan sus tablas\nen esquemas propios, ",[14,177,178],{},"storage"," y ",[14,181,182],{},"auth",", y Supabase dice que sus grants y sus\nvalores por defecto se quedan como están.",[167,185,186,189,190,192,193,195],{},[22,187,188],{},"La clave secreta también se rechaza."," Los grants automáticos cubrían también\na ",[14,191,51],{},", así que una edge function (código de servidor que Supabase\nejecuta por ti) que use tu clave secreta recibe el mismo error en una tabla\nnueva hasta que ",[14,194,51],{}," tenga un grant propio.",[167,197,198,201],{},[22,199,200],{},"Una tabla borrada y creada de nuevo es una tabla nueva."," Los grants\npertenecen a la propia tabla y se van con ella cuando se borra. Si tu builder\nreconstruye una tabla para cambiarla, la reconstruida empieza con la puerta\ncerrada.",[27,203,205],{"id":204},"se-romperá-mi-app-el-30-de-octubre","¿Se romperá mi app el 30 de octubre?",[10,207,208],{},"Ese día no. Se rompe la primera vez que algo crea una tabla nueva sin crear\ntambién el grant.",[10,210,211,212,215],{},"Para la mayoría de quienes leen esto, ese algo es su builder. Pides una sección\nde comentarios. El builder escribe una migración, que es el archivo de cambios\nde base de datos que ejecuta por ti, y la migración crea una tabla ",[14,213,214],{},"comments",".\nSi también escribe los grants, nunca verás este error. Si no, la pantalla de\ncomentarios no muestra nada, o guardar un comentario falla, o aparece un mensaje\nen rojo, según cómo gestione tu app un error. Todas las pantallas que ya tenías\nsiguen funcionando.",[10,217,218,219,224],{},"Supabase publica una ",[100,220,223],{"href":221,"rel":222},"https:\u002F\u002Fsupabase.com\u002Fblog\u002Fsupabase-agent-skills",[104],"agent skill","\npara herramientas de programación con IA que incluye el paso del grant. Que tu\nbuilder la use depende de tu builder, así que lo prudente es suponer que la\npróxima tabla que cree puede llegar con la puerta cerrada.",[27,226,228],{"id":227},"es-seguro-ejecutar-el-grant-que-sugiere-el-error","¿Es seguro ejecutar el GRANT que sugiere el error?",[10,230,231],{},"Solo cuando la tabla ya tiene Row Level Security activado y una regla escrita.\nEl grant decide quién cruza la puerta. Nada en él decide qué cajones abre.",[10,233,234,235,237],{},"La clave con la que tu app hace sus peticiones a Supabase viaja dentro de tu\napp, así que un grant a ",[14,236,43],{}," significa que cualquier visitante, con sesión o\nsin ella, puede pedirle filas a esa tabla. Con una regla puesta, recibe las\nfilas que la regla permite. Con Row Level Security apagado, recibe todas las\nfilas de la tabla, y nada en tu app se verá distinto.",[10,239,240],{},"El email enseña tres grants y ahí se queda. El propio changelog de Supabase\nenseña tres pasos, y dice que hay que tratarlos como una unidad (\"treat these\nthree steps as a unit\"):",[61,242,245],{"className":243,"code":244,"language":66},[64],"-- 1. quién puede llegar a la tabla\ngrant select on public.orders to authenticated;\ngrant select, insert, update, delete on public.orders to service_role;\n\n-- 2. activar las reglas por fila\nalter table public.orders enable row level security;\n\n-- 3. la regla en sí\ncreate policy \"Customers read their own orders\"\n  on public.orders\n  for select\n  to authenticated\n  using (auth.uid() = user_id);\n",[14,246,244],{"__ignoreMap":69},[10,248,249,250,252,253,258,259,261],{},"En ese ejemplo no hay ninguna línea para ",[14,251,43],{},", y es a propósito. Nadie sin\nsesión debería llegar a una tabla de pedidos, así que la puerta para\ndesconocidos se queda cerrada, y los clientes con sesión reciben solo la lectura\nque necesita su pantalla. Después la regla la reduce a sus propias filas. El\nconsejo de Supabase es\n",[100,254,257],{"href":255,"rel":256},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fapi\u002Fsecuring-your-api",[104],"dar a cada rol el mínimo que necesita",".\nUn grant a ",[14,260,43],{}," tiene sentido en una tabla cuyas filas son para todo el mundo,\ncomo los comentarios bajo una publicación pública.",[155,263],{"alt":264,"caption":265,"src":266},"Tres carriles, cada uno con una petición de anon hacia la misma tabla. En el primero la puerta está cerrada y la flecha se detiene ante ella, junto al código 42501. En el segundo la puerta está abierta, la flecha se detiene en una barra de Row Level Security y se iluminan dos filas de la tabla. En el tercero la puerta está abierta, la barra es solo un contorno discontinuo y se iluminan todas las filas en ámbar.","El grant decide si una petición llega a la tabla. Las reglas que hay detrás deciden cuánto se lleva. Una puerta abierta sin reglas detrás entrega la tabla entera.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fthe-door-and-the-rules-1600x760.png",[10,268,269,270,174],{},"Si quieres ver en qué lado de ese dibujo están tus tablas, nuestro escaneo\ngratuito le hace a tu app en producción la pregunta que haría un desconocido,\ncuenta las filas que recibiría sin descargar ninguna, y tarda unos 20 segundos\nsin cuenta: ",[100,271,273],{"href":272},"\u002Fsecurity-scanner","escanea tu app",[27,275,277],{"id":276},"por-qué-los-arreglos-de-row-level-security-no-tocan-este-error","Por qué los arreglos de Row Level Security no tocan este error",[10,279,280],{},"Porque el grant se comprueba primero. Una petición rechazada en la puerta nunca\nllega a tus reglas, así que cambiar las reglas no cambia nada del error.",[10,282,283,284,287,288,292,293,296],{},"Esto importa porque el código es compartido. ",[14,285,286],{},"42501"," es también lo que devuelve\nPostgres cuando Row Level Security rechaza un guardado, como en\n",[100,289,291],{"href":290},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","new row violates row-level security policy",".\nUn asistente que se guíe solo por el código puede recurrir a los arreglos de ese\notro error: apagar Row Level Security, o añadir una regla ",[14,294,295],{},"using (true)",", que\ndeja pasar a todo el mundo. Ninguno de los dos hace desaparecer este error. Los\ndos se quedan ahí cuando por fin entra el grant, y entonces la puerta está\nabierta a unos cajones sin cerradura.",[10,298,299],{},"Las palabras del mensaje distinguen los dos casos, aunque el número no lo haga:",[108,301,302,315],{},[111,303,304],{},[114,305,306,309,312],{},[117,307,308],{},"El mensaje dice",[117,310,311],{},"Qué cerradura rechazó",[117,313,314],{},"Qué lo arregla",[124,316,317,329,341],{},[114,318,319,323,326],{},[129,320,321],{},[14,322,16],{},[129,324,325],{},"la puerta (el grant)",[129,327,328],{},"un grant para el rol que nombra la pista",[114,330,331,335,338],{},[129,332,333],{},[14,334,291],{},[129,336,337],{},"las reglas",[129,339,340],{},"una policy que permita esa fila",[114,342,343,346,348],{},[129,344,345],{},"ningún error, y la lista sale vacía",[129,347,337],{},[129,349,350],{},"una policy de lectura para ese rol",[27,352,354],{"id":353},"lo-que-el-30-de-octubre-no-arregla","Lo que el 30 de octubre no arregla",[10,356,357],{},"Ninguna tabla que ya tengas. Cada una conserva exactamente el acceso que tiene\nhoy, incluida una tabla que un desconocido puede leer ahora mismo.",[10,359,360,361,365],{},"El cambio va de tablas que aún no existen. Hasta ahora cada tabla nueva llegaba\ncon las puertas abiertas, así que una app construida antes del 30 de octubre\npuede tener una en la que nadie puso nunca las cerraduras: Row Level Security\nnunca activado, o\n",[100,362,364],{"href":363},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","activado con una regla que deja entrar a todo el mundo",".\nEl 30 de octubre deja esas habitaciones exactamente como están.",[10,367,368],{},"Tres sitios te dicen dónde estás:",[370,371,372,378,384],"ol",{},[167,373,374,377],{},[22,375,376],{},"La página de ajustes de Data API",", que el email enlaza. En el panel está\nen Integrations y luego Data API, y muestra cuáles de tus tablas son\nalcanzables siquiera.",[167,379,380,383],{},[22,381,382],{},"El Security Advisor",", que según Supabase muestra las tablas que conviene\nrevisar antes del cambio.",[167,385,386,389,390,174],{},[22,387,388],{},"La vista desde fuera."," Ninguno de los dos anteriores te dice qué recibe un\ndesconocido. Para eso le preguntas a tu app en producción como lo haría un\ndesconocido, que es ",[100,391,392],{"href":272},"lo que hace nuestro escaneo",[27,394,396],{"id":395},"cómo-vigila-reeve-las-tablas-que-añades","Cómo vigila Reeve las tablas que añades",[10,398,399],{},[22,400,401],{},"Después del 30 de octubre, cada tabla que añada tu builder es una decisión\nnueva sobre quién cruza la puerta. Reeve comprueba la respuesta desde fuera, y\nMonitor la sigue comprobando.",[164,403,404,412,422],{},[167,405,406,409,410,174],{},[22,407,408],{},"El escaneo gratuito"," pregunta a cada tabla que nombra tu app cuántas filas\nrecibiría un visitante sin sesión, lee el recuento y se detiene ahí sin\ndescargar ninguna fila. Unos 20 segundos, sin cuenta:\n",[100,411,273],{"href":272},[167,413,414,417,418,421],{},[22,415,416],{},"Reeve Monitor"," pasa las nueve comprobaciones cada hora en hasta tres apps y\nte manda un email el día en que tu nota ",[22,419,420],{},"empeora",", así que un despliegue que\nabrió algo no espera a que vayas tú a mirar.",[167,423,424,427,428,431,432,174],{},[22,425,426],{},"Care"," pasa las mismas comprobaciones y guarda una copia cifrada de tu base\nde datos de ",[22,429,430],{},"Supabase"," fuera de tu cuenta de Supabase, así que el arreglo de\nun asistente que reconstruye una tabla tiene una copia a la que volver.\n",[100,433,435],{"href":434},"\u002Fsupabase-backups","Cómo se hace la copia y cómo se restaura",[10,437,438,439,174],{},"Lo que cubre cada plan está en la ",[100,440,442],{"href":441},"\u002Fpricing","página de precios",[27,444,446],{"id":445},"qué-hacer-antes-del-30-de-octubre","Qué hacer antes del 30 de octubre",[448,449,450],"key-takeaways",{},[164,451,452,455,462,468,476,482],{},[167,453,454],{},"Deja en paz las tablas que ya tienes si lo único que quieres es que tu app siga funcionando. Conservan sus grants.",[167,456,457,458,461],{},"Pide a tu builder que escriba el grant, ",[14,459,460],{},"enable row level security"," y una policy en la misma migración que cada tabla nueva, como un solo cambio.",[167,463,464,465,467],{},"Cuando aparezca el error, lee qué rol nombra la pista. ",[14,466,43],{}," significa cualquier visitante de tu app.",[167,469,470,471,473,474,174],{},"No des nada a ",[14,472,43],{}," en una tabla hasta que Row Level Security esté activado y haya una regla escrita. Las tablas con personas o pedidos normalmente no necesitan ningún grant a ",[14,475,43],{},[167,477,478,479,481],{},"Rechaza cualquier arreglo que apague Row Level Security o añada ",[14,480,295],{}," para quitar un error de permisos. Ninguno de los dos lo toca.",[167,483,484],{},"Comprueba qué puede leer un desconocido de las tablas que ya tienes. El 30 de octubre las deja como están.",[10,486,487,488,490],{},"Empieza por la tabla que un desconocido más querría leer, normalmente la que\ntiene personas dentro, y ",[100,489,273],{"href":272}," para ver qué\nentrega hoy.",{"title":69,"searchDepth":492,"depth":492,"links":493},3,[494,496,497,498,499,500,501,502],{"id":29,"depth":495,"text":30},2,{"id":78,"depth":495,"text":79},{"id":204,"depth":495,"text":205},{"id":227,"depth":495,"text":228},{"id":276,"depth":495,"text":277},{"id":353,"depth":495,"text":354},{"id":395,"depth":495,"text":396},{"id":445,"depth":495,"text":446},"Fundamentos de seguridad","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcover-1200x630.png","Una hilera de puertas a tablas de una base de datos. Las más antiguas se abren a filas iluminadas y la más nueva, al final, está cerrada.","Desde el 30 de octubre, una tabla nueva de Supabase responde \"permission denied for table\" hasta que le das acceso. El grant del email es la mitad del arreglo.",false,"md",[510,513,515,517,520],{"q":511,"a":512},"¿Mi app de Supabase dejará de funcionar el 30 de octubre?","No. Cada tabla que exista el 30 de octubre conserva el acceso que tiene, y Supabase ha confirmado que esos grants no se van a retirar. Lo que cambia es la siguiente tabla que se cree después de esa fecha. Nace inalcanzable desde tu app hasta que alguien le da acceso, así que lo primero que se rompe es la primera función nueva que necesite una tabla nueva.",{"q":30,"a":514},"Significa que el tipo de visitante que hace la petición no tiene ningún acceso a esa tabla, así que tu base de datos la rechazó antes de mirar una sola fila. Viene de Postgres, la base de datos sobre la que corre Supabase, con el código 42501, y suele llegar a tu app como un 401 o un 403. Supabase añade una pista con la sentencia GRANT exacta que dejaría pasar a ese visitante.",{"q":228,"a":516},"Solo cuando la tabla ya tiene Row Level Security activado y una regla escrita. Un grant a anon deja que cualquier visitante de tu app pida filas a la tabla, porque la clave que hace esas peticiones viaja dentro de tu app. Con una regla puesta, recibe las filas que la regla permite. Sin regla y con Row Level Security apagado, las recibe todas.",{"q":518,"a":519},"¿Este cambio afecta a Storage, al inicio de sesión o a mis edge functions?","Storage y el inicio de sesión viven en sus propios esquemas, storage y auth, y Supabase dice que sus grants y sus valores por defecto se quedan como están. Las edge functions son otra historia. Una que use tu clave secreta sigue necesitando un grant en cualquier tabla nueva, porque los grants automáticos que desaparecen cubrían a service_role además de los dos roles que usan tus visitantes.",{"q":521,"a":522},"¿Puedo volver a activar el comportamiento anterior?","Supabase documenta cómo hacerlo, con un ajuste en la página Data API del panel o con SQL, y lo desaconseja. Con eso activado, cada tabla nueva es alcanzable por cualquier visitante desde el momento en que existe, y Row Level Security es lo único que se interpone entre un desconocido y sus filas. Así funcionaban todos los proyectos antes del cambio.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",[525,526,527,528,529,530],"supabase permission denied for table","supabase grant tablas nuevas","cambio supabase 30 de octubre data api","supabase 42501","supabase exponer tablas nuevas automáticamente","supabase default privileges esquema public",{},true,"Supabase \"permission denied for table\" desde el 30 de octubre","\u002Fblog\u002Fsupabase-permission-denied-for-table","2026-09-26",{"title":5,"description":506},"blog\u002Fsupabase-permission-denied-for-table",[539,540,541],"Desde el 30 de octubre de 2026, una tabla nueva de tu proyecto de Supabase responde \"permission denied for table\" hasta que alguien le da acceso. Las tablas que ya tienes siguen funcionando exactamente igual que hoy.","Un grant decide si una petición llega a una tabla. Row Level Security sigue decidiendo qué filas se lleva. Dar a anon acceso a una tabla sin reglas deja cada fila legible para cualquiera.","El cambio no cierra nada que ya esté abierto. Comprueba qué puede leer hoy un desconocido, y otra vez después de cada tabla que añadas.","9tBjoa8ogUm3GiSOY748P_ZjkEbL3WYEmXiwZvw8Ah0",[544,550,556,562,568,574,580,586,592,598,604,610,616,623,629,634,635,641,647,653,659,665,671,677,683,689,695,701,707,713,719,725,731,737,743,749,755,761,767,773,779,785,791,797,803,809,814,820,826,832,838,844,850,856,861,867,873,878,883,889],{"path":545,"title":546,"description":547,"published":548,"category":503,"image":549,"draft":507},"\u002Fblog\u002Fbase44-security-scan","Escaneo de seguridad de Base44: lo que solo él ve","El escaneo de seguridad de Base44 revisa siete tipos de problema desde dentro. Esta es la mitad que lee y nadie más puede leer, y la mitad que nunca mira.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":551,"title":552,"description":553,"published":554,"category":503,"image":555,"draft":507},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Tu clave API se filtró. El orden en el que hay que actuar","Una clave API se filtró y no sabes por dónde empezar. No todas las claves de tu frontend lo son, y el orden importa más que la velocidad.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":557,"title":558,"description":559,"published":560,"category":503,"image":561,"draft":507},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" sin desactivar RLS","\"Infinite recursion detected in policy for relation\" significa que tu policy preguntó a la tabla que protege. Así se rompe el círculo.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":563,"title":564,"description":565,"published":566,"category":503,"image":567,"draft":507},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" en Supabase, y el arreglo equivocado","\"No API key found in request\" significa que tu petición llegó a Supabase sin clave. Casi todas las respuestas apuntan a las reglas de tu base de datos.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":569,"title":570,"description":571,"published":572,"category":503,"image":573,"draft":507},"\u002Fblog\u002Fis-base44-safe","¿Es seguro Base44? Lo que vimos en 5.442 apps Base44","¿Es seguro Base44? Pasamos nueve comprobaciones a 5.442 apps Base44 en producción. Casi todas sacaron B por motivos que su dueño nunca eligió.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":575,"title":576,"description":577,"published":578,"category":503,"image":579,"draft":507},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Ocultar una clave API: muévela a una Edge Function de Supabase","Ocultar una clave API significa sacarla del navegador, y una Edge Function de Supabase es el sitio más pequeño donde ponerla. Dos pasos importan más.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":581,"title":582,"description":583,"published":584,"category":503,"image":585,"draft":507},"\u002Fblog\u002Fenv-file-exposed-on-your-server","¿Tu archivo .env está expuesto? Las doce rutas a revisar","¿Tu archivo .env está expuesto en tu propio servidor web? Doce direcciones te lo dicen, y un acierto significa que todo lo que contiene ya es público.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":587,"title":588,"description":589,"published":590,"category":503,"image":591,"draft":507},"\u002Fblog\u002Fis-v0-safe","Seguridad de v0: las 1.790 aplicaciones escaneadas sacaron una A","Seguridad de v0, medida en 1.790 aplicaciones v0 en vivo: todas sacaron A. Solo 17 nombraban una base de datos, y eso es casi todo lo que mide la A.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":593,"title":594,"description":595,"published":596,"category":503,"image":597,"draft":507},"\u002Fblog\u002Fis-bolt-safe","¿Es seguro Bolt? Lo que vimos en 1.123 aplicaciones Bolt","¿Es seguro Bolt? Pasamos 1.123 aplicaciones Bolt en vivo por nueve comprobaciones. El hosting salió limpio. Los hallazgos eran claves y tablas abiertas dentro.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":599,"title":600,"description":601,"published":602,"category":503,"image":603,"draft":507},"\u002Fblog\u002Fis-supabase-down-or-your-app","¿Supabase está caído o es tu app? Cómo distinguirlo","¿Supabase está caído o es tu app? Un proyecto pausado, una base de datos llena y un fallo tuyo parecen lo mismo. Cuatro comprobaciones los separan.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":605,"title":606,"description":607,"published":608,"category":503,"image":609,"draft":507},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","¿Supabase cifra mis datos? Sí. Esto es lo que detiene","¿Supabase cifra los datos? Sí: AES-256 en reposo, TLS en tránsito, SOC 2 e ISO 27001. Qué cubre cada uno, y la fuga que ninguno de ellos detiene.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":611,"title":612,"description":613,"published":614,"category":503,"image":615,"draft":507},"\u002Fblog\u002Fsupabase-free-plan-limits","¿Cuánto cuesta Supabase? Los límites del plan gratuito","Los límites del plan gratuito de Supabase: 500 MB de base de datos, 5 GB de egress y ningún backup. Qué pasa en cada uno y qué cambia Pro por $25.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":617,"title":618,"description":619,"published":620,"category":621,"image":622,"draft":507},"\u002Fblog\u002Ftest-your-supabase-backup","Prueba tu backup de Supabase antes del día que lo necesites","Cómo probar tu backup de Supabase: restaurarlo en un proyecto de prueba, contar filas, iniciar sesión y buscar la línea que le falta a un archivo cortado.","2026-09-28","Backups","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":624,"title":625,"description":626,"published":627,"category":621,"image":628,"draft":507},"\u002Fblog\u002Fsupabase-backup-github-action","Backup gratis de Supabase con una GitHub Action, y la trampa","Un backup de Supabase con GitHub Action es gratis y sirve a muchas apps. El workflow, el connection string correcto y el egress de cada ejecución.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":630,"title":631,"description":632,"published":535,"category":621,"image":633,"draft":507},"\u002Fblog\u002Fdownload-your-supabase-backup","Por qué no puedes descargar tu backup de Supabase","No puedes descargar tu backup de Supabase en un proyecto actual: la copia diaria es una instantánea física. Cómo comprobarlo y tener tu propia copia.","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":534,"title":5,"description":506,"published":535,"category":503,"image":523,"draft":507},{"path":636,"title":637,"description":638,"published":639,"category":503,"image":640,"draft":507},"\u002Fblog\u002Fopen-api-endpoint-exposed","¿Un endpoint de API abierto es un problema? Mira el JSON","Tu escaneo señaló un endpoint de API abierto. Que importe depende de lo que devolvió, y la mayoría de los que encontramos eran de la plataforma.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":642,"title":643,"description":644,"published":645,"category":503,"image":646,"draft":507},"\u002Fblog\u002Flovable-security-scan","Escaneo de seguridad de Lovable: lo que no puede probar","Escaneo de seguridad de Lovable: qué revisan el Quick scan y el Deep scan, cuándo corre cada uno, y lo único que ningún escaneo desde dentro puede probar.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":648,"title":649,"description":650,"published":651,"category":621,"image":652,"draft":507},"\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","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":654,"title":655,"description":656,"published":657,"category":503,"image":658,"draft":507},"\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":660,"title":661,"description":662,"published":663,"category":503,"image":664,"draft":507},"\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":666,"title":667,"description":668,"published":669,"category":503,"image":670,"draft":507},"\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":672,"title":673,"description":674,"published":675,"category":503,"image":676,"draft":507},"\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":678,"title":679,"description":680,"published":681,"category":503,"image":682,"draft":507},"\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":684,"title":685,"description":686,"published":687,"category":503,"image":688,"draft":507},"\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":690,"title":691,"description":692,"published":693,"category":503,"image":694,"draft":507},"\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":696,"title":697,"description":698,"published":699,"category":503,"image":700,"draft":507},"\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":702,"title":703,"description":704,"published":705,"category":621,"image":706,"draft":507},"\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":708,"title":709,"description":710,"published":711,"category":621,"image":712,"draft":507},"\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":714,"title":715,"description":716,"published":717,"category":621,"image":718,"draft":507},"\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":720,"title":721,"description":722,"published":723,"category":503,"image":724,"draft":507},"\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":726,"title":727,"description":728,"published":729,"category":503,"image":730,"draft":507},"\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":732,"title":733,"description":734,"published":735,"category":503,"image":736,"draft":507},"\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":738,"title":739,"description":740,"published":741,"category":503,"image":742,"draft":507},"\u002Fblog\u002Frotate-supabase-service-role-key","Cómo rotar una clave service_role de Supabase filtrada","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.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":744,"title":745,"description":746,"published":747,"category":503,"image":748,"draft":507},"\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":750,"title":751,"description":752,"published":753,"category":503,"image":754,"draft":507},"\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":756,"title":757,"description":758,"published":759,"category":503,"image":760,"draft":507},"\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":762,"title":763,"description":764,"published":765,"category":503,"image":766,"draft":507},"\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":768,"title":769,"description":770,"published":771,"category":503,"image":772,"draft":507},"\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":774,"title":775,"description":776,"published":777,"category":503,"image":778,"draft":507},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","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":780,"title":781,"description":782,"published":783,"category":621,"image":784,"draft":507},"\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":786,"title":787,"description":788,"published":789,"category":503,"image":790,"draft":507},"\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":792,"title":793,"description":794,"published":795,"category":621,"image":796,"draft":507},"\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":798,"title":799,"description":800,"published":801,"category":503,"image":802,"draft":507},"\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":804,"title":805,"description":806,"published":807,"category":503,"image":808,"draft":507},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","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":290,"title":810,"description":811,"published":812,"category":503,"image":813,"draft":507},"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":815,"title":816,"description":817,"published":818,"category":503,"image":819,"draft":507},"\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":821,"title":822,"description":823,"published":824,"category":621,"image":825,"draft":507},"\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":827,"title":828,"description":829,"published":830,"category":621,"image":831,"draft":507},"\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":833,"title":834,"description":835,"published":836,"category":503,"image":837,"draft":507},"\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":839,"title":840,"description":841,"published":842,"category":503,"image":843,"draft":507},"\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":845,"title":846,"description":847,"published":848,"category":621,"image":849,"draft":507},"\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":851,"title":852,"description":853,"published":854,"category":503,"image":855,"draft":507},"\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":857,"title":858,"description":859,"published":854,"category":503,"image":860,"draft":507},"\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":862,"title":863,"description":864,"published":865,"category":503,"image":866,"draft":507},"\u002Fblog\u002Fsupabase-new-api-keys","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":868,"title":869,"description":870,"published":871,"category":621,"image":872,"draft":507},"\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":363,"title":874,"description":875,"published":876,"category":503,"image":877,"draft":507},"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":879,"title":880,"description":881,"published":876,"category":621,"image":882,"draft":507},"\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":884,"title":885,"description":886,"published":887,"category":621,"image":888,"draft":507},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","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":890,"title":891,"description":892,"published":887,"category":503,"image":893,"draft":507},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","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",1791618971504]