[{"data":1,"prerenderedAt":929},["ShallowReactive",2],{"blog-es-supabase-backup-auth-users":3,"blog-index-es":580},{"id":4,"title":5,"body":6,"category":535,"cover":536,"coverAlt":537,"description":538,"draft":539,"extension":540,"faq":541,"image":558,"keywords":559,"meta":568,"navigation":569,"ogTitle":570,"path":571,"published":572,"seo":573,"stem":574,"tldr":575,"updated":572,"__hash__":579},"blog_es\u002Fblog\u002Fsupabase-backup-auth-users.md","Por qué tu dump de Supabase no tiene usuarios dentro",{"type":7,"value":8,"toc":523},"minimark",[9,13,21,35,38,43,46,63,84,87,93,97,102,122,125,135,142,145,150,154,160,214,217,223,226,236,240,243,252,258,261,267,270,276,289,300,306,312,316,319,325,331,334,355,359,362,374,389,395,402,406,443,450,454,457,462,497,505,512],[10,11,12],"p",{},"Hiciste lo sensato. Buscaste cómo hacer copia de una base de datos de Supabase,\nejecutaste el comando que encontraste y guardaste el archivo en un sitio seguro.",[10,14,15,16,20],{},"Entonces un día lo necesitas. Vuelcas el archivo en un proyecto nuevo y la\nrestauración termina sin un solo error. Cada tabla que llegaste a crear está\nahí, y cada una de ellas está vacía. Tus usuarios están peor todavía: la parte\nde la base de datos donde viven, un esquema llamado ",[17,18,19],"code",{},"auth",", nunca llegó al\narchivo.",[10,22,23,24,31,32,34],{},"Aquí está la parte que casi todas las guías se saltan: ",[25,26,27,30],"strong",{},[17,28,29],{},"supabase db dump"," por\nsí solo no es una copia de tus datos."," Sin más flags escribe la forma de tu\nbase de datos y nada de su contenido, y a ",[17,33,19],{}," lo deja fuera hasta de eso.\nSupabase publica el backup como tres comandos, y tus cuentas viajan en el\ntercero.",[10,36,37],{},"Ayuda pensar en un hotel. Tus tablas son las habitaciones y todo lo que hay en\nellas. El registro de la recepción, el que tiene el nombre de cada huésped, es\ndel hotel. Y un plano te enseña cada habitación del edificio sin poner un solo\nhuésped dentro.",[39,40,42],"h2",{"id":41},"un-backup-de-supabase-incluye-mis-usuarios","¿Un backup de Supabase incluye mis usuarios?",[10,44,45],{},"Depende de qué comando escribió el archivo, y el comando que ejecuta la mayoría\nno los incluye.",[10,47,48,49,51,52,55,56,59,60,62],{},"Tus usuarios no son filas de ninguna de tus tablas. Supabase los guarda en un\ncajón aparte de la misma base de datos, el esquema ",[17,50,19],{},", junto con sus\ncontraseñas hasheadas, los proveedores con los que entraron y las sesiones que\ntienen abiertas. Tus propias tablas están en un cajón llamado ",[17,53,54],{},"public",", y cada\ncolumna ",[17,57,58],{},"user_id"," que hay en ellas es una referencia hacia ",[17,61,19],{},".",[10,64,65,66,68,69,71,72,75,76,83],{},"Un esquema es exactamente eso: un cajón con nombre dentro de una base de datos.\n",[17,67,54],{}," es tuyo. ",[17,70,19],{}," es de Supabase, y ",[17,73,74],{},"storage"," también, que guarda la fila\nque describe cada archivo subido. La documentación de Supabase llama a estos sus\nesquemas gestionados y dice que\n",[77,78,82],"a",{"href":79,"rel":80},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Flocal-development\u002Fcli-workflows",[81],"nofollow","normalmente no hace falta traerlos salvo que los hayas modificado",",\nque es la razón por la que las herramientas los tratan distinto de tus tablas.",[10,85,86],{},"Esa división es lo que permite que un comando produzca dos archivos que se\nparecen y contienen cosas completamente distintas.",[88,89],"diagram",{"alt":90,"caption":91,"src":92},"Un archivo de dump con una flecha que alcanza un panel sólido de cuatro tablas encendidas, marcado con un visto. Una segunda flecha se detiene en un muro discontinuo frente a un panel discontinuo con la marca de Supabase, y ese panel contiene una ficha rayada con tres personas junto a cuatro imágenes tenues. Sobre el muro hay una cruz.","Ejecutado por sí solo, el comando de dump copia la forma de tu propio cajón y se detiene en la frontera de los dos que lleva Supabase.","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fwhere-the-dump-stops-1600x620.png",[39,94,96],{"id":95},"qué-escribe-el-comando-de-dump-por-sí-solo","Qué escribe el comando de dump por sí solo",[10,98,99,100,62],{},"El plano. Ninguna fila, y nada de ",[17,101,19],{},[10,103,104,105,108,109,114,115,118,119,62],{},"La página de referencia de Supabase para el comando lo dice en dos frases.\nEjecuta ",[17,106,107],{},"pg_dump"," con flags adicionales para excluir los esquemas gestionados\npor Supabase, y entre los ignorados\n",[77,110,113],{"href":111,"rel":112},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Freference\u002Fcli\u002Fsupabase-db-dump",[81],"están auth, storage y los creados por extensiones",".\nLa misma página dice después que el dump por defecto no contiene datos ni roles\npropios, y que los consigues pidiéndolos con ",[17,116,117],{},"--data-only"," y ",[17,120,121],{},"--role-only",[10,123,124],{},"Así que esto, que es lo que probablemente ejecutaste:",[126,127,132],"pre",{"className":128,"code":130,"language":131},[129],"language-text","supabase db dump --db-url \"postgresql:\u002F\u002F…your connection string…\" -f backup.sql\n","text",[17,133,130],{"__ignoreMap":134},"",[10,136,137,138,141],{},"produce un archivo lleno de sentencias ",[17,139,140],{},"CREATE TABLE",". Cada columna, cada\níndice, cada política que escribiste sobre tus propias tablas, y ni una sola\nfila de nada.",[10,143,144],{},"La razón por la que esto es peor que un archivo obviamente vacío es que\nfunciona. Tampoco se ve pequeño: cada definición de tabla, cada índice y cada\npolítica que llegaste a escribir están ahí, y para una app de verdad eso es\nmucho texto. Un backup vacío se anuncia solo. Este se restaura limpio, y lo\nprimero que te dice otra cosa es una pantalla de acceso que ninguna cuenta\nconsigue pasar.",[88,146],{"alt":147,"caption":148,"src":149},"Dos archivos uno al lado del otro. El de la izquierda es discontinuo y contiene dos rejillas de tabla vacías junto a un contorno vacío donde debería haber una ficha, y está tachado. El de la derecha contiene esas mismas dos tablas con las filas rellenas y, en el lugar del contorno vacío, una ficha rayada con tres personas. Está marcado con un visto.","El mismo comando escribe los dos. Cuál tienes en la mano depende de un flag, y los dos se restauran sin un error.","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fthe-plan-and-the-contents-1600x620.png",[39,151,153],{"id":152},"cómo-compruebo-el-dump-que-ya-tengo","¿Cómo compruebo el dump que ya tengo?",[10,155,156,157,159],{},"Ábrelo en un editor de texto y busca ",[17,158,19],{},". Lo que salga coloca tu archivo en\nuno de tres grupos.",[161,162,163,176,193],"ol",{},[164,165,166,169,170,172,173,175],"li",{},[25,167,168],{},"Ninguna coincidencia."," El esquema ",[17,171,19],{}," no está en este archivo de\nninguna forma. Esto es lo que escribe un ",[17,174,29],{}," a secas.",[164,177,178,192],{},[25,179,180,181,184,185,188,189,62],{},"Coincidencias, pero solo en líneas que empiezan por ",[17,182,183],{},"CREATE",", ",[17,186,187],{},"ALTER"," o\n",[17,190,191],{},"GRANT"," Tienes el diseño del registro y a nadie dentro.",[164,194,195,209,210,213],{},[25,196,197,198,201,202,205,206],{},"Una línea que dice ",[17,199,200],{},"COPY \"auth\".\"users\""," o ",[17,203,204],{},"COPY auth.users",", con filas de\ndatos debajo hasta una línea con ",[17,207,208],{},"\\."," O una serie de líneas que empiezan\npor ",[17,211,212],{},"INSERT INTO \"auth\".\"users\"",". Tus cuentas están ahí.",[10,215,216],{},"Si prefieres hacerlo en la línea de comandos, dos greps responden lo mismo:",[126,218,221],{"className":219,"code":220,"language":131},[129],"grep -c 'auth.*users' backup.sql\ngrep -n 'COPY .*auth.*users\\|INSERT INTO .*auth.*users' backup.sql\n",[17,222,220],{"__ignoreMap":134},[10,224,225],{},"El primero dice si el esquema llegó al archivo. El segundo dice si llegaron las\npersonas. Un cero de los dos, en un archivo con el que contabas, es mejor\ndescubrirlo hoy que la mañana en que lo necesitas.",[10,227,228,229,231,232,62],{},"Busca ",[17,230,74],{}," ya que estás, y lee con cuidado lo que encuentres. Esas filas\nson la lista de tus archivos subidos, que es una cosa distinta de los archivos,\ny\n",[77,233,235],{"href":234},"\u002Fblog\u002Fsupabase-storage-backup","ningún backup de base de datos en ningún plan contiene esos",[39,237,239],{"id":238},"cómo-exporto-los-usuarios-auth-de-supabase","¿Cómo exporto los usuarios auth de Supabase?",[10,241,242],{},"Con el comando de datos, que es un comando distinto del que escribe el esquema.",[10,244,245,246,251],{},"La\n",[77,247,250],{"href":248,"rel":249},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fplatform\u002Fmigrating-within-supabase\u002Fbackup-restore",[81],"guía de backup y restauración","\nde Supabase publica el backup como tres archivos, y vale la pena verlos juntos\nporque la forma es la respuesta:",[126,253,256],{"className":254,"code":255,"language":131},[129],"supabase db dump --db-url \"postgresql:\u002F\u002F…\" -f roles.sql --role-only\nsupabase db dump --db-url \"postgresql:\u002F\u002F…\" -f schema.sql\nsupabase db dump --db-url \"postgresql:\u002F\u002F…\" -f data.sql --use-copy --data-only \\\n  -x \"storage.buckets_vectors\" -x \"storage.vector_indexes\"\n",[17,257,255],{"__ignoreMap":134},[10,259,260],{},"La segunda línea es la que se ejecuta suelta. La tercera es la que lleva tus\nusuarios.",[10,262,263,264,266],{},"Esos dos hechos parecen una contradicción y no lo son. La frase de la página de\nreferencia de Supabase sobre excluir ",[17,265,19],{}," describe el dump de esquema, y el\ndump de datos sí recorre ese esquema.",[10,268,269],{},"Si solo quieres las cuentas, nombra el esquema y obtienes ese cajón solo:",[126,271,274],{"className":272,"code":273,"language":131},[129],"supabase db dump --db-url \"postgresql:\u002F\u002F…\" -f users.sql --data-only --use-copy --schema auth\n",[17,275,273],{"__ignoreMap":134},[10,277,278,285,286,288],{},[25,279,280,281,284],{},"Antes de confiar en cualquiera de estos, añade ",[17,282,283],{},"--dry-run"," y lee lo que sale.","\nImprime el comando ",[17,287,107],{}," que la herramienta va a ejecutar sin ejecutarlo,\nasí ves por ti mismo qué esquemas se incluyen y cuáles se excluyen en la versión\nque tienes instalada. Lee esa salida una vez y no tendrás que creerle nunca a\neste artículo, ni a ningún otro, lo cual importa porque los flags sí se mueven\nentre versiones y el archivo se ve igual de todos modos.",[10,290,291,292,299],{},"También está la vía directa, y\n",[77,293,295,296,298],{"href":294},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","para eso está un ",[17,297,107],{}," a secas",":\nnombra los cajones que quieres y se los lleva.",[126,301,304],{"className":302,"code":303,"language":131},[129],"pg_dump \"postgresql:\u002F\u002F…\" --schema public --schema auth --schema storage \\\n  --no-owner --file backup.sql\n",[17,305,303],{"__ignoreMap":134},[10,307,308,309,311],{},"Una cosa más sobre el archivo de esquema, porque explica por qué esto está\nseparado. Un proyecto nuevo de Supabase llega con un esquema ",[17,310,19],{}," ya\nconstruido, en la versión que el servicio de inicio de sesión corre hoy. Volcar\nencima la versión de tu proyecto viejo pondría un diseño más antiguo sobre uno\nque funciona. Lo que quieres llevarte es el contenido del registro, y eso es lo\nque guarda el archivo de datos.",[39,313,315],{"id":314},"qué-se-rompe-al-devolver-los-usuarios","Qué se rompe al devolver los usuarios",[10,317,318],{},"Dos cosas, y Supabase documenta las dos.",[10,320,321,324],{},[25,322,323],{},"Los triggers, que pueden cifrar una columna dos veces."," El comando de\nrestauración de la guía de Supabase tiene en medio una instrucción fácil de\nleer como relleno:",[126,326,329],{"className":327,"code":328,"language":131},[129],"psql \\\n  --single-transaction \\\n  --variable ON_ERROR_STOP=1 \\\n  --file roles.sql \\\n  --file schema.sql \\\n  --command 'SET session_replication_role = replica' \\\n  --file data.sql \\\n  --dbname \"postgresql:\u002F\u002F…\"\n",[17,330,328],{"__ignoreMap":134},[10,332,333],{},"Esa línea del medio apaga los triggers mientras dura, y la guía dice que está\npara evitar que las columnas se cifren una segunda vez al entrar. Vuelca un\narchivo de datos sin ella y las contraseñas llegan ya revueltas por un proceso\nque ya se les había aplicado, y nada posterior lo deshace.",[10,335,336,339,340,343,344,347,348,343,351,354],{},[25,337,338],{},"La propiedad y los permisos, que detienen el volcado."," Un dump sacado de un\nproyecto de Supabase lleva líneas que se refieren a roles que el proyecto nuevo\nno te deja tocar. Las notas de resolución de problemas de esa misma guía dicen\nque comentes cualquier línea con ",[17,341,342],{},"ALTER ... OWNER TO \"supabase_admin\""," en\n",[17,345,346],{},"schema.sql",", y una línea concreta ",[17,349,350],{},"GRANT \"postgres\" TO \"cli_login_postgres\"",[17,352,353],{},"roles.sql",". Las dos son una edición de texto antes de empezar, y las dos\ndetienen el volcado con la línea en la que se atragantó impresa en tu pantalla.",[39,356,358],{"id":357},"mis-usuarios-tienen-que-entrar-otra-vez","¿Mis usuarios tienen que entrar otra vez?",[10,360,361],{},"Sus contraseñas pasan. Sus sesiones no, salvo que te lleves una cosa más con\nellas.",[10,363,364,365,367,368,373],{},"Supabase dice que puedes migrar cada tabla del esquema ",[17,366,19],{},",\n",[77,369,372],{"href":370,"rel":371},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Ftroubleshooting\u002Fmigrating-auth-users-between-projects",[81],"usuarios y sus contraseñas hasheadas incluidos",",\nasí que nadie tiene que restablecer una contraseña que ya tenía. En ningún punto\nde esto se lee una contraseña; lo que se mueve es su hash.",[10,375,376,377,380,381,384,385,62],{},"Una sesión es otra cosa. Se prueba con un token que se firmó con el secreto JWT\npropio de tu proyecto, y cada proyecto tiene el suyo. Supabase dice que si el\nproyecto nuevo firma con otro secreto, cada token que ya está en el navegador\nde alguien queda inválido y a esa persona se le pide entrar de nuevo. Puedes\nevitarlo poniendo el secreto del proyecto viejo en el nuevo, y en esa misma\npágina está el precio: cambiar el secreto JWT regenera las claves ",[17,378,379],{},"anon"," y\n",[17,382,383],{},"service_role"," de ese proyecto, así que hay que darle a tu app las nuevas antes\nde que pueda hablar con nada. Cuál clave es cuál, y cuál de ellas puede estar en\ntu app siquiera, es\n",[77,386,388],{"href":387},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","lo que conviene tener claro antes de pegar ninguna",[10,390,391,392,394],{},"Así que la versión honesta es que una restauración suele pedirle a todo el mundo\nque entre una vez. Eso es un correo de soporte. No es una cuenta perdida, y la\ndiferencia entre las dos cosas es si el esquema ",[17,393,19],{}," estaba en tu archivo.",[10,396,397,398,401],{},"Tres cosas siguen sin estar ahí, hagas lo que hagas con los flags. Tus archivos\nsubidos, porque Storage guarda los bytes fuera de la base de datos y\n",[77,399,400],{"href":234},"ningún dump en ningún plan los alcanza",". Tus\nedge functions, que son una descarga aparte y cuyos import maps, señala\nSupabase, no se traen automáticamente. Y los ajustes de tu proyecto, que son\nconfiguración y no datos y se vuelven a escribir a mano.",[39,403,405],{"id":404},"qué-hacer-esta-semana","Qué hacer esta semana",[407,408,409],"key-takeaways",{},[410,411,412,418,427,433,440],"ul",{},[164,413,414,415,417],{},"Coge el archivo de backup más reciente que tengas y búscale ",[17,416,19],{},". Grupo uno, dos o tres de la sección de arriba, y lo sabrás en un minuto.",[164,419,420,421,118,423,426],{},"Si es grupo uno o dos, saca hoy un dump de datos con ",[17,422,117],{},[17,424,425],{},"--use-copy",", y guárdalo junto al archivo de esquema en vez de en su lugar. Necesitas los dos.",[164,428,429,430,432],{},"Añade ",[17,431,283],{}," al comando que acabes usando y lee la salida una vez, para saber qué cajones se lleva tu versión de la herramienta.",[164,434,435,436,439],{},"Apunta el orden de la restauración donde lo vayas a encontrar: roles, luego schema, luego ",[17,437,438],{},"SET session_replication_role = replica",", luego data.",[164,441,442],{},"Restaura una vez en un proyecto desechable y luego intenta entrar como un usuario real. Es la única comprobación que prueba aquello de lo que trata este artículo.",[10,444,445,446,449],{},"Hacer esto una vez a mano vale la pena acabes como acabes haciendo tus copias,\nporque hasta que no abres un dump solo has tenido la palabra backup. Si sigues\nhaciéndolo a mano es otra pregunta, y\n",[77,447,448],{"href":294},"las tres vías y lo que cuesta cada una","\nes donde se responde.",[39,451,453],{"id":452},"dónde-encaja-reeve-care","Dónde encaja Reeve Care",[10,455,456],{},"Care saca la copia según un calendario, y el registro va dentro.",[88,458],{"alt":459,"caption":460,"src":461},"Un panel de Reeve Care con dos filas. En la primera, un contorno discontinuo de cuenta contiene una base de datos y un registro de personas, y las dos salen por una flecha hacia un archivo cerrado que se relee con una lupa y se marca con un visto. En la segunda, una tarjeta con un botón devuelve las filas de la base de datos a la cuenta mientras el registro de dentro sigue encendido e intacto.","La copia guarda tus tablas y tus cuentas. El botón de restaurar devuelve tus tablas y deja las cuentas donde están.","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcare-the-register-comes-too-1600x560.png",[410,463,464,475,485,491],{},[164,465,466,169,469,471,472,474],{},[25,467,468],{},"Tus cuentas están en la copia.",[17,470,19],{}," viaja con tus propias tablas, porque una copia de una app de Supabase sin sus usuarios es una copia de la mitad. Las filas de ",[17,473,74],{}," que describen tus archivos vienen también, y los archivos mismos en cuanto conectas una credencial de Storage.",[164,476,477,480,481,484],{},[25,478,479],{},"El botón de restaurar devuelve tus tablas y deja las cuentas en paz."," Volcar ",[17,482,483],{},"auth.users"," sobre un proyecto vivo cierra la sesión de todos y devuelve cuentas que alguien borró a propósito, así que eso sigue siendo una petición con una persona detrás. Y así pulsar el botón en pleno susto no puede echar fuera a los clientes a los que querías ayudar.",[164,486,487,490],{},[25,488,489],{},"La copia se relee antes de contar como sacada."," La fecha de tu panel es la última vez que se abrió y se verificó una copia, nunca el momento en que arrancó un trabajo o aterrizó un archivo.",[164,492,493,496],{},[25,494,495],{},"Restaurar toma antes una instantánea del estado actual",", así que la propia restauración tiene un deshacer.",[10,498,499,500,504],{},"Care empieza en $49 al mes por una app. Es un precio de lista, y la\n",[77,501,503],{"href":502},"\u002Fpricing","página de precios"," a veces está por debajo de la cifra de aquí y\nnunca por encima.",[10,506,507,508,62],{},"Cómo se saca, se comprueba y se devuelve una copia está dibujado paso a paso en\nla ",[77,509,511],{"href":510},"\u002Fsupabase-backups","página de backups de Supabase",[10,513,514,515,517,518,522],{},"Antes de cerrar esta pestaña, abre tu dump más reciente y búscale ",[17,516,19],{},". Es la\nforma más rápida de averiguar si eso que venías llamando backup te devolvería a\ntus clientes, y si la respuesta resulta ser que no,\n",[77,519,521],{"href":520},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","restaurar uno como toca"," es lo\nsiguiente que leer.",{"title":134,"searchDepth":524,"depth":524,"links":525},3,[526,528,529,530,531,532,533,534],{"id":41,"depth":527,"text":42},2,{"id":95,"depth":527,"text":96},{"id":152,"depth":527,"text":153},{"id":238,"depth":527,"text":239},{"id":314,"depth":527,"text":315},{"id":357,"depth":527,"text":358},{"id":404,"depth":527,"text":405},{"id":452,"depth":527,"text":453},"Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcover-1200x630.png","Un archivo sellado con tres filas de datos, y a su lado un registro rayado de personas que queda fuera y lo corta el borde del marco.","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.",false,"md",[542,544,547,549,552,555],{"q":42,"a":543},"Depende de qué comando escribió el archivo. Tus usuarios viven en un esquema llamado auth, que pertenece al servicio de inicio de sesión. Un supabase db dump a secas deja auth fuera y no contiene ninguna fila de nada, porque el dump por defecto es solo el esquema. La mitad de datos del dump, que es un segundo comando con el flag --data-only, es la que lleva tus usuarios. Supabase publica el backup como tres comandos exactamente por eso.",{"q":545,"a":546},"¿Por qué falta auth.users en mi dump?","Porque casi seguro ejecutaste el dump de esquema. Supabase documenta que el comando excluye sus esquemas gestionados, que entre los ignorados están auth y storage, y que el dump por defecto no contiene datos en absoluto. Es deliberado: un proyecto nuevo llega con su propio esquema auth ya construido por el servicio de inicio de sesión, así que volcar encima una copia más vieja reemplazaría algo que funciona. Lo que quieres mover es el contenido, y eso lo lleva el dump de datos.",{"q":239,"a":548},"Con el comando de datos, que está separado del comando de esquema. Ejecuta supabase db dump con --data-only y --use-copy para escribir un archivo de datos, y las tablas de auth vienen con él. Si solo quieres las cuentas, añade --schema auth y obtienes un archivo con ese esquema y nada más. Antes de confiar en cualquiera de los dos, añade --dry-run: imprime el comando pg_dump que la CLI va a ejecutar sin ejecutarlo, así lees qué esquemas se incluyen en la versión que tienes.",{"q":550,"a":551},"¿Las contraseñas sobreviven a una restauración de Supabase?","Sí, si el esquema auth estaba en el archivo. Supabase dice que puedes migrar cada tabla del esquema auth, contraseñas hasheadas incluidas, así que nadie tiene que restablecerlas ni crearlas de nuevo. Lo único que puede arruinarlas es volcar los datos sin desactivar antes los triggers, que es la razón por la que Supabase pone SET session_replication_role = replica en medio de su propio comando de restauración. Sáltate esa línea y una columna ya cifrada se cifra una segunda vez al entrar.",{"q":553,"a":554},"¿Mis usuarios seguirán con la sesión abierta tras una restauración?","No, si el proyecto nuevo firma con otro secreto. Una sesión se prueba con un token firmado con el secreto JWT del proyecto, y Supabase dice que un secreto nuevo invalida los tokens existentes, así que a todos se les pide entrar otra vez. Puedes llevarte el secreto viejo y mantenerlos dentro, pero Supabase también dice que cambiar el secreto JWT regenera las claves anon y service_role de ese proyecto, así que tu app necesita las nuevas.",{"q":556,"a":557},"¿Qué más deja fuera un dump de Supabase?","Tus archivos subidos, lo primero. Storage guarda una fila en tu base de datos por cada archivo y el archivo en otro sitio, así que ningún dump de base de datos en ningún plan contiene los bytes. Las edge functions son una descarga aparte, y Supabase señala que los import maps y los archivos deno.json no se traen automáticamente. Los ajustes del proyecto, los proveedores de auth y los secretos son configuración y no datos, y viven en el dashboard, así que se vuelven a escribir a mano en un proyecto nuevo.","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",[560,561,562,563,564,565,566,567],"supabase backup auth users","exportar usuarios de supabase","supabase db dump esquema auth","migrar usuarios auth supabase","backup de supabase sin usuarios","supabase auth.users export","restaurar usuarios de supabase","supabase dump excluye auth",{},true,"Por qué tu dump de Supabase no tiene usuarios","\u002Fblog\u002Fsupabase-backup-auth-users","2026-09-23",{"title":5,"description":538},"blog\u002Fsupabase-backup-auth-users",[576,577,578],"Supabase publica su backup como tres comandos. El que probablemente ejecutaste es el segundo, y tus usuarios están en el tercero.","Ejecuta supabase db dump sin más flags y obtienes la forma de tus tablas y nada de su contenido, y el esquema auth donde viven tus usuarios queda fuera hasta de eso.","Una sola búsqueda en el archivo que ya tienes te dice cuál de tres cosas estás sosteniendo.","ck-e4jrDHwCXGhwM8KCY3n5dRM_0lH0oWQzEKwOZC1o",[581,588,594,600,606,612,618,624,630,636,642,648,654,660,666,672,677,683,689,690,696,702,708,714,720,726,732,738,743,749,755,761,767,773,779,785,791,797,803,809,815,821,827,833,839,845,851,857,863,868,874,880,886,892,897,903,909,915,920,925],{"path":582,"title":583,"description":584,"published":585,"category":586,"image":587,"draft":539},"\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","Fundamentos de seguridad","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":589,"title":590,"description":591,"published":592,"category":586,"image":593,"draft":539},"\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":595,"title":596,"description":597,"published":598,"category":586,"image":599,"draft":539},"\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":601,"title":602,"description":603,"published":604,"category":586,"image":605,"draft":539},"\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":607,"title":608,"description":609,"published":610,"category":586,"image":611,"draft":539},"\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":613,"title":614,"description":615,"published":616,"category":586,"image":617,"draft":539},"\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":619,"title":620,"description":621,"published":622,"category":586,"image":623,"draft":539},"\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":625,"title":626,"description":627,"published":628,"category":586,"image":629,"draft":539},"\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":631,"title":632,"description":633,"published":634,"category":586,"image":635,"draft":539},"\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":637,"title":638,"description":639,"published":640,"category":586,"image":641,"draft":539},"\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":643,"title":644,"description":645,"published":646,"category":586,"image":647,"draft":539},"\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":649,"title":650,"description":651,"published":652,"category":586,"image":653,"draft":539},"\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":655,"title":656,"description":657,"published":658,"category":535,"image":659,"draft":539},"\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","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":661,"title":662,"description":663,"published":664,"category":535,"image":665,"draft":539},"\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":667,"title":668,"description":669,"published":670,"category":535,"image":671,"draft":539},"\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.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":673,"title":674,"description":675,"published":670,"category":586,"image":676,"draft":539},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": el grant que falta","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.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":678,"title":679,"description":680,"published":681,"category":586,"image":682,"draft":539},"\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":684,"title":685,"description":686,"published":687,"category":586,"image":688,"draft":539},"\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":571,"title":5,"description":538,"published":572,"category":535,"image":558,"draft":539},{"path":691,"title":692,"description":693,"published":694,"category":586,"image":695,"draft":539},"\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":697,"title":698,"description":699,"published":700,"category":586,"image":701,"draft":539},"\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":703,"title":704,"description":705,"published":706,"category":586,"image":707,"draft":539},"\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":709,"title":710,"description":711,"published":712,"category":586,"image":713,"draft":539},"\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":715,"title":716,"description":717,"published":718,"category":586,"image":719,"draft":539},"\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":721,"title":722,"description":723,"published":724,"category":586,"image":725,"draft":539},"\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":727,"title":728,"description":729,"published":730,"category":586,"image":731,"draft":539},"\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":733,"title":734,"description":735,"published":736,"category":586,"image":737,"draft":539},"\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":234,"title":739,"description":740,"published":741,"category":535,"image":742,"draft":539},"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":744,"title":745,"description":746,"published":747,"category":535,"image":748,"draft":539},"\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":750,"title":751,"description":752,"published":753,"category":535,"image":754,"draft":539},"\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":756,"title":757,"description":758,"published":759,"category":586,"image":760,"draft":539},"\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":762,"title":763,"description":764,"published":765,"category":586,"image":766,"draft":539},"\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":768,"title":769,"description":770,"published":771,"category":586,"image":772,"draft":539},"\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":774,"title":775,"description":776,"published":777,"category":586,"image":778,"draft":539},"\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":780,"title":781,"description":782,"published":783,"category":586,"image":784,"draft":539},"\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":786,"title":787,"description":788,"published":789,"category":586,"image":790,"draft":539},"\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":792,"title":793,"description":794,"published":795,"category":586,"image":796,"draft":539},"\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":798,"title":799,"description":800,"published":801,"category":586,"image":802,"draft":539},"\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":804,"title":805,"description":806,"published":807,"category":586,"image":808,"draft":539},"\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":810,"title":811,"description":812,"published":813,"category":586,"image":814,"draft":539},"\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":816,"title":817,"description":818,"published":819,"category":535,"image":820,"draft":539},"\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":822,"title":823,"description":824,"published":825,"category":586,"image":826,"draft":539},"\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":828,"title":829,"description":830,"published":831,"category":535,"image":832,"draft":539},"\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":834,"title":835,"description":836,"published":837,"category":586,"image":838,"draft":539},"\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":840,"title":841,"description":842,"published":843,"category":586,"image":844,"draft":539},"\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":846,"title":847,"description":848,"published":849,"category":586,"image":850,"draft":539},"\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":852,"title":853,"description":854,"published":855,"category":586,"image":856,"draft":539},"\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":858,"title":859,"description":860,"published":861,"category":535,"image":862,"draft":539},"\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":520,"title":864,"description":865,"published":866,"category":535,"image":867,"draft":539},"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":869,"title":870,"description":871,"published":872,"category":586,"image":873,"draft":539},"\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":875,"title":876,"description":877,"published":878,"category":586,"image":879,"draft":539},"\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":881,"title":882,"description":883,"published":884,"category":535,"image":885,"draft":539},"\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":887,"title":888,"description":889,"published":890,"category":586,"image":891,"draft":539},"\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":893,"title":894,"description":895,"published":890,"category":586,"image":896,"draft":539},"\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":898,"title":899,"description":900,"published":901,"category":586,"image":902,"draft":539},"\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":904,"title":905,"description":906,"published":907,"category":535,"image":908,"draft":539},"\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":910,"title":911,"description":912,"published":913,"category":586,"image":914,"draft":539},"\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":916,"title":917,"description":918,"published":913,"category":535,"image":919,"draft":539},"\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":294,"title":921,"description":922,"published":923,"category":535,"image":924,"draft":539},"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":387,"title":926,"description":927,"published":923,"category":586,"image":928,"draft":539},"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",1791618971513]