[{"data":1,"prerenderedAt":959},["ShallowReactive",2],{"blog-pt-storage-upload-violates-row-level-security":3,"blog-index-pt":602},{"id":4,"title":5,"body":6,"category":558,"cover":559,"coverAlt":560,"description":561,"draft":562,"extension":563,"faq":564,"image":580,"keywords":581,"meta":589,"navigation":590,"ogTitle":591,"path":592,"published":593,"seo":594,"stem":595,"tldr":596,"updated":593,"__hash__":601},"blog_pt\u002Fblog\u002Fstorage-upload-violates-row-level-security.md","\"Row-level security policy for table objects\" ao enviar",{"type":7,"value":8,"toc":545},"minimark",[9,13,24,31,39,44,51,57,70,74,77,87,99,105,109,112,118,121,129,133,136,142,153,156,172,179,259,262,267,271,274,277,283,289,292,298,312,319,326,330,333,339,348,355,362,365,371,384,389,395,399,402,405,408,418,422,425,434,454,463,480,483,487,532],[10,11,12],"p",{},"O seu app envia um arquivo. Funcionava no preview do seu builder, ou funcionava\nsemana passada, e agora toda tentativa volta com uma frase sobre row-level\nsecurity:",[14,15,20],"pre",{"className":16,"code":18,"language":19},[17],"language-text","new row violates row-level security policy for table \"objects\"\n","text",[21,22,18],"code",{"__ignoreMap":23},"",[10,25,26,27,30],{},"Quase toda essa frase vai parecer conhecida se você já passou por isso numa\ntabela sua. O que muda é a última palavra, porque ",[21,28,29],{},"objects"," não é uma tabela que\nvocê criou.",[10,32,33,34,38],{},"Esta é a parte que guia após guia erra: ",[35,36,37],"strong",{},"a primeira solução que você vai achar\né deixar o bucket público, e ela não faz nada pelos envios."," A própria\ndocumentação do Supabase diz isso em uma linha. Essa chave deixa o envio\nrecusado e abre os arquivos que já estavam lá dentro.",[40,41,43],"h2",{"id":42},"o-que-significa-new-row-violates-row-level-security-policy-for-table-objects","O que significa \"new row violates row-level security policy for table objects\"",[10,45,46,47,50],{},"O seu envio chegou ao Supabase Storage, o Storage perguntou às regras postas\nnuma tabela chamada ",[21,48,49],{},"storage.objects"," se aquele arquivo podia entrar, não achou\nnenhuma que dissesse sim, e recusou.",[10,52,53,54,56],{},"A linha da mensagem existe de verdade. O Storage guarda uma linha em\n",[21,55,49],{}," para cada arquivo que tem, com o nome do arquivo, o bucket em\nque ele está e quem o colocou ali. Escrever um arquivo é escrever essa linha,\nentão as regras dessa tabela decidem se o envio acontece. Nada se perdeu: nenhum\narquivo foi guardado, e o resto do bucket está exatamente como há um minuto.",[10,58,59,60,63,64,69],{},"A redação vem do Postgres, o banco de dados que roda embaixo do Supabase, e por\nisso soa a maquinário. Ela traz o código ",[21,61,62],{},"42501",", o mesmo de\n",[65,66,68],"a",{"href":67},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","um salvamento recusado numa das suas próprias tabelas",".",[40,71,73],{"id":72},"por-que-a-mensagem-cita-objects-e-não-o-seu-bucket","Por que a mensagem cita \"objects\" e não o seu bucket",[10,75,76],{},"Porque o Storage guarda as regras de todos os buckets do seu projeto nessa única\ntabela.",[10,78,79,80,82,83,86],{},"Um bucket organiza arquivos. Ele não tem regras próprias, e não existe nenhum\neditor de policies pendurado nele. ",[21,81,49],{}," é onde as regras moram,\npara todos os seus buckets ao mesmo tempo, e ",[21,84,85],{},"bucket_id"," é uma coluna dela.\nEntão uma regra que diz \"só no bucket avatars\" é escrita como uma condição sobre\nessa coluna.",[10,88,89,90,93,94,96,97,69],{},"É também por isso que a regra de tabela que você escreveu semana passada não\najudou. Uma regra em ",[21,91,92],{},"profiles"," é uma regra sobre linhas de ",[21,95,92],{},", e um\narquivo é uma linha de ",[21,98,49],{},[100,101],"diagram",{"alt":102,"caption":103,"src":104},"Três buckets lado a lado, cada um com uma seta descendo até um painel largo rotulado storage.objects que carrega três fichas de policy e um nome de coluna. À esquerda, do outro lado de uma linha tracejada, um cartão mais apagado rotulado profiles tem as próprias linhas e a própria ficha insert, sem nenhuma linha ligando a nada.","Todos os buckets do seu projeto são governados pela mesma tabela. As regras que você escreveu nas suas próprias tabelas ficam do outro lado dessa linha e nunca encontram um arquivo.","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fone-table-every-bucket-1600x720.png",[40,106,108],{"id":107},"preciso-deixar-o-bucket-público-para-conseguir-enviar","Preciso deixar o bucket público para conseguir enviar?",[10,110,111],{},"Não. Atrás de um bucket existem duas perguntas diferentes, e a chave responde só\numa delas. Quem pode tirar um arquivo é o que público decide. Quem pode colocar\num é o assunto do seu erro, e a documentação do Supabase é explícita que o\najuste não chega até lá. Da página que descreve os dois tipos de bucket, lida em\n11 de outubro de 2026:",[113,114,115],"blockquote",{},[10,116,117],{},"O controle de acesso continua sendo aplicado a outros tipos de operação,\nincluindo enviar, apagar, mover e copiar.",[10,119,120],{},"O que público de fato faz está dito com a mesma clareza nessa página: quem tem o\nendereço de um arquivo consegue abri-lo sem entrar na conta. O ajuste não é mais\ndo que isso.",[10,122,123,124,128],{},"Então virar a chave deixa você no único estado que ninguém quer. O envio\ncontinua recusado, porque enviar nunca foi o que o ajuste controlava, e os\narquivos que já estavam no bucket agora podem ser abertos por qualquer um que\ntenha o endereço deles.\n",[65,125,127],{"href":126},"\u002Fblog\u002Fsupabase-storage-bucket-public","O que um bucket público custa de verdade","\né uma pergunta diferente desse erro, e vale ler antes de mexer na chave.",[40,130,132],{"id":131},"o-que-um-bucket-realmente-confere-quando-você-envia","O que um bucket realmente confere quando você envia",[10,134,135],{},"Uma regra, e o nome dela é insert.",[10,137,138,139,141],{},"A página de controle de acesso do Supabase deixa o padrão claro: sem policies, o\nStorage não permite nenhum envio a um bucket, e você libera operações uma a uma\nescrevendo-as em ",[21,140,49],{},". Depois ela nomeia a que você precisa:",[113,143,144],{},[10,145,146,147,150,151,69],{},"Por exemplo, a única policy de RLS necessária para enviar objetos é conceder a\npermissão ",[21,148,149],{},"INSERT"," na tabela ",[21,152,49],{},[10,154,155],{},"Existe uma segunda metade disso, e é o motivo mais comum de uma regra insert não\ntirar o erro:",[113,157,158],{},[10,159,160,161,164,165,168,169,69],{},"Para permitir sobrescrever arquivos pela funcionalidade ",[21,162,163],{},"upsert",", você\nprecisará conceder também as permissões ",[21,166,167],{},"SELECT"," e ",[21,170,171],{},"UPDATE",[10,173,174,175,178],{},"Se o seu envio manda ",[21,176,177],{},"upsert: true",", que pede ao Storage para substituir um\narquivo de mesmo nome quando já existe um, então uma regra insert sozinha não\nbasta. Substituir um arquivo são três perguntas em vez de uma: você pode\nacrescentar esta linha, pode ver a que está lá, e pode alterá-la.",[180,181,182,197],"table",{},[183,184,185],"thead",{},[186,187,188,192],"tr",{},[189,190,191],"th",{},"O que o seu app pede ao Storage",[189,193,194,195],{},"O que ele precisa em ",[21,196,49],{},[198,199,200,212,231,240,249],"tbody",{},[186,201,202,206],{},[203,204,205],"td",{},"enviar um arquivo novo",[203,207,208,209],{},"uma regra ",[21,210,211],{},"insert",[186,213,214,220],{},[203,215,216,217,219],{},"substituir um arquivo de mesmo nome (",[21,218,163],{},")",[203,221,222,224,225,168,228],{},[21,223,211],{},", mais ",[21,226,227],{},"select",[21,229,230],{},"update",[186,232,233,236],{},[203,234,235],{},"abrir um arquivo num bucket privado",[203,237,208,238],{},[21,239,227],{},[186,241,242,245],{},[203,243,244],{},"listar o que há num bucket",[203,246,208,247],{},[21,248,227],{},[186,250,251,254],{},[203,252,253],{},"apagar um arquivo",[203,255,208,256],{},[21,257,258],{},"delete",[10,260,261],{},"Você não precisa escrever as cinco. Escreva as que o seu app de fato faz, que na\nmaioria dos envios é a primeira linha e às vezes a segunda.",[100,263],{"alt":264,"caption":265,"src":266},"Um depósito de arquivos com tampa e duas aberturas na parede direita. A abertura de cima tem uma barra atravessada, e um documento que chega de fora é recusado por uma cruz. A de baixo está com a barra erguida, e um arquivo sai por ela até uma figura que espera ao lado de um visto. Uma chave logo abaixo é ligada por um único traço à abertura de baixo e a mais nada.","Um depósito, duas aberturas. A chave está ligada à de baixo. Um envio chega na de cima, onde uma regra que ninguém escreveu ainda decide se ele entra.","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Ftwo-counters-1600x720.png",[40,268,270],{"id":269},"a-regra-que-deixa-o-seu-app-enviar-e-só-o-seu-app","A regra que deixa o seu app enviar, e só o seu app",[10,272,273],{},"Nomeie o bucket, e diga para quem a regra vale.",[10,275,276],{},"O ponto de partida da documentação limita um envio a um bucket e a visitantes\nlogados:",[14,278,281],{"className":279,"code":280,"language":19},[17],"create policy \"Allow authenticated uploads\"\non storage.objects\nfor insert\nto authenticated\nwith check (bucket_id = 'my_bucket_id');\n",[21,282,280],{"__ignoreMap":23},[10,284,285,288],{},[21,286,287],{},"to authenticated"," é a parte que não convém pular. Ela quer dizer que a regra\nvale para visitantes logados; tire-a e a regra passa a valer para todo mundo,\nestranhos inclusive.",[10,290,291],{},"Para qualquer coisa que pertença a uma pessoa específica, a versão que o\nSupabase publica põe os arquivos de cada pessoa numa pasta com o nome dela:",[14,293,296],{"className":294,"code":295,"language":19},[17],"create policy \"Allow authenticated uploads\"\non storage.objects\nfor insert\nto authenticated\nwith check (\n  bucket_id = 'my_bucket_id' and\n  (storage.foldername(name))[1] = (select auth.jwt()->>'sub')\n);\n",[21,297,295],{"__ignoreMap":23},[10,299,300,303,304,307,308,311],{},[21,301,302],{},"storage.foldername(name)"," divide o caminho de um arquivo guardado nas pastas\ndele, então ",[21,305,306],{},"[1]"," é a primeira. ",[21,309,310],{},"auth.jwt()->>'sub'"," é o id de quem está logado\ne fazendo o pedido. Lidas juntas, as duas linhas dizem que você pode colocar um\narquivo na pasta com o seu nome, naquele bucket, e em nenhum outro lugar.",[10,313,314,315,318],{},"Os dois são exemplos do Supabase e não nossos, lidos em 11 de outubro de 2026,\ncom ",[21,316,317],{},"my_bucket_id"," onde eles deixaram, para você ver qual parte é o nome do seu\npróprio bucket.",[10,320,321,322,69],{},"Se preferir ver o resultado de fora, o nosso escaneamento gratuito pergunta ao\nseu projeto em produção quais dos seus buckets vão entregar o conteúdo a um\nestranho. Leva uns 20 segundos e não precisa de conta:\n",[65,323,325],{"href":324},"\u002Fsecurity-scanner","escaneie o seu app",[40,327,329],{"id":328},"o-que-uma-regra-de-leitura-entrega-sem-que-ninguém-peça","O que uma regra de leitura entrega sem que ninguém peça",[10,331,332],{},"Listar um bucket e baixar dele são o mesmo privilégio, então uma regra escrita\npara fazer os seus downloads funcionarem também deixa o conteúdo do bucket\nlistável.",[10,334,335,336,338],{},"A página de funções auxiliares do Supabase diz isso direto: um único privilégio\nde SQL como ",[21,337,167],{}," é usado por várias ações do Storage. A página de controle\nde acesso depois avisa do caso específico, embaixo de um exemplo que abre um\nbucket de avatares para todo mundo:",[113,340,341],{},[10,342,343,344,347],{},"O filtro ",[21,345,346],{},"allow_any_operation()"," é crítico aqui, porque sem ele os usuários\nconseguiriam listar o conteúdo do bucket.",[10,349,350,351,354],{},"Essa é a brecha que a gente mede de fora. Escaneamos 8.435 apps no ar que citam\num projeto Supabase. A verificação de buckets obteve resposta em 4.703 delas, e\n",[35,352,353],{},"792 dessas responderam ao nosso pedido de listagem com os nomes do que tinham\ndentro",", sem ninguém logado. Isso é cerca de uma em cada seis das apps que\nconseguimos perguntar.",[10,356,357,358,361],{},"Muitas vezes um nome já basta, porque um bucket que lista poupa um estranho de\nadivinhar nomes de arquivo. ",[21,359,360],{},"invoice-2026-03-hannah.pdf"," diz de quem é o arquivo\nantes de alguém abrir.",[10,363,364],{},"A correção que o Supabase documenta é dizer para qual ação do Storage a regra\nvale:",[14,366,369],{"className":367,"code":368,"language":19},[17],"create policy \"Allow users to list their own objects\"\non storage.objects\nfor select\nto authenticated\nusing (\n  storage.allow_only_operation('object.list')\n  and owner_id = (select auth.uid()::text)\n);\n",[21,370,368],{"__ignoreMap":23},[10,372,373,376,377,380,381,383],{},[21,374,375],{},"storage.allow_only_operation"," e a irmã ",[21,378,379],{},"storage.allow_any_operation"," são o jeito\nde uma regra ",[21,382,227],{}," se estreitar a uma das ações que dividem o privilégio. Sem\numa das duas, uma regra que você escreveu para o seu app poder mostrar uma\nimagem é também uma regra que vai ler em voz alta tudo o que há no bucket.",[100,385],{"alt":386,"caption":387,"src":388},"Uma caixa rotulada select de onde saem dois ramos. O ramo de cima chega a um documento único, repassado a uma figura ao lado de um visto. O ramo de baixo atravessa uma placa estreita desenhada com traço pontilhado e chega a uma pilha de seis linhas acesas, marcada com uma cruz.","Uma regra, duas ações diferentes do Storage. A placa no caminho de baixo é o filtro de ação, e o traço pontilhado é como ela fica quando ninguém escreveu nenhum.","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fone-rule-two-actions-1600x700.png",[10,390,391,394],{},[65,392,393],{"href":126},"Se um bucket listável é um problema para o seu app","\ndepende do que tem dentro, e essa é uma pergunta que o resultado do escaneamento\nnão responde por você.",[40,396,398],{"id":397},"quando-público-é-a-resposta-certa","Quando público é a resposta certa",[10,400,401],{},"Quando os arquivos existem para serem vistos por qualquer um que peça, o que é\numa categoria real e da qual o Supabase dá os próprios exemplos.",[10,403,404],{},"Os casos de uso que o Supabase cita para um bucket público são fotos de perfil,\nmídia pública e conteúdo de posts de blog. São arquivos que o seu app mostra a\num visitante que não entrou na conta, e servi-los de um bucket público ainda é\nmais rápido, porque os dois tipos de bucket são cacheados de formas diferentes.",[10,406,407],{},"Para o outro tipo, a documentação cita dois jeitos de tirar um arquivo de um\nbucket privado: um download carregando o token da pessoa logada, ou um link\nassinado que funciona por um tempo limitado. Os dois deixam a decisão com as\nsuas regras em vez de deixar com quem achou o endereço.",[409,410,412],"callout",{"type":411},"warn",[10,413,414,417],{},[35,415,416],{},"Buckets são privados por padrão."," Um bucket que você criou e nunca mais\npensou a respeito já está no mais rígido dos dois estados, o que quer dizer que\no erro que você está lendo é o comportamento previsto. Escreva a regra e o envio\npassa; a chave não tem nada a dizer sobre essa pergunta, nem num sentido nem no\noutro.",[40,419,421],{"id":420},"como-manter-o-bucket-certo-depois-de-hoje","Como manter o bucket certo depois de hoje",[10,423,424],{},"Com as regras corretas, duas coisas ainda se mexem: alguém vira a chave enquanto\npersegue um bug sem relação, e um arquivo some.",[10,426,427],{},[35,428,429,433],{},[65,430,432],{"href":431},"\u002Fpricing","O Reeve Monitor"," roda as nove verificações de fora de novo por você:",[435,436,437,441,444,451],"ul",{},[438,439,440],"li",{},"as nove verificações a cada hora, em até três apps, incluindo a de listagem de bucket",[438,442,443],{},"se o app responde, a cada 60 segundos",[438,445,446,447,450],{},"uma mensagem quando um resultado ",[35,448,449],{},"muda",", para que um bucket que abriu de madrugada não espere você olhar",[438,452,453],{},"um relatório mensal do que foi visto",[10,455,456],{},[35,457,458,462],{},[65,459,461],{"href":460},"\u002Fsupabase-backups","O Reeve Care"," guarda uma cópia do que está lá dentro:",[435,464,465,468,471,474,477],{},[438,466,467],{},"uma cópia criptografada do seu banco Supabase toda noite, guardada onde o seu projeto não alcança",[438,469,470],{},"cada cópia verificada antes de contar, contando as linhas de cada tabela",[438,472,473],{},"também os seus arquivos enviados, assim que você conectar um acesso de Storage",[438,475,476],{},"uma restauração em um clique quando precisar",[438,478,479],{},"tudo o que o Monitor faz",[10,481,482],{},"Os dois estão na página de preços, que às vezes fica abaixo do valor de tabela\ndaqui e nunca acima.",[40,484,486],{"id":485},"o-que-fazer-hoje","O que fazer hoje",[488,489,490],"key-takeaways",{},[435,491,492,495,511,521,524],{},[438,493,494],{},"Leia a mensagem como uma recusa. O arquivo não foi guardado, o bucket está igual, e não há nada a recuperar.",[438,496,497,498,500,501,503,504,506,507,510],{},"Crie uma regra ",[21,499,211],{}," em ",[21,502,49],{}," que cite o seu bucket em ",[21,505,85],{}," e carregue a cláusula ",[21,508,509],{},"TO"," que você queria.",[438,512,174,513,515,516,168,518,520],{},[21,514,177],{},", acrescente ",[21,517,227],{},[21,519,230],{},", senão a regra insert sozinha não tira o erro.",[438,522,523],{},"Deixe a chave de público onde está enquanto faz isso. Sobre envios ela não tem nada a dizer, e sobre quem pode abrir o que já está guardado ela tem.",[438,525,526,527,500,529,531],{},"Leia cada regra ",[21,528,227],{},[21,530,49],{}," e pergunte o que ela permite além do download para o qual você a escreveu. A listagem divide esse privilégio.",[10,533,534,535,539,540,544],{},"Comece pelo bucket de onde veio o erro, e depois olhe os outros buckets do mesmo\nprojeto, porque uma regra escrita de forma ampla uma vez costuma ter sido colada\nduas. A ",[65,536,538],{"href":537},"\u002Fchecklist","checklist de segurança em 10 minutos"," cobre o que mais\ncostuma ficar aberto num app recém-lançado, e o\n",[65,541,543],{"href":542},"\u002Fis-your-supabase-app-safe","guia de segurança do Supabase"," passa pelo resto do\nque um estranho consegue alcançar.",{"title":23,"searchDepth":546,"depth":546,"links":547},3,[548,550,551,552,553,554,555,556,557],{"id":42,"depth":549,"text":43},2,{"id":72,"depth":549,"text":73},{"id":107,"depth":549,"text":108},{"id":131,"depth":549,"text":132},{"id":269,"depth":549,"text":270},{"id":328,"depth":549,"text":329},{"id":397,"depth":549,"text":398},{"id":420,"depth":549,"text":421},{"id":485,"depth":549,"text":486},"Noções de segurança","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcover-1200x630.png","Uma portinhola de entrega trancada com um documento parado do lado de fora, e atrás dela uma prateleira de arquivos com uma tampa sobre a borda.","\"New row violates row-level security policy for table objects\" quer dizer que o seu envio não tem regra insert. Deixar o bucket público não cria nenhuma.",false,"md",[565,568,571,574,577],{"q":566,"a":567},"Por que o meu upload no Supabase falha com um erro de row-level security?","Porque o Supabase Storage perguntou às regras postas numa tabela chamada storage.objects se o seu arquivo podia entrar, e não achou nenhuma que dissesse sim. O Storage escreve uma linha nessa tabela para cada arquivo que guarda, e o Row Level Security vale para essa linha igual a qualquer outra linha de qualquer outra tabela. Nenhum arquivo foi guardado e nada do que já estava no bucket mudou. A mensagem traz o código do Postgres 42501, o mesmo de quando um salvamento numa tabela sua é recusado.",{"q":569,"a":570},"Preciso deixar o meu bucket público para conseguir enviar?","Não, e deixar público não ajuda. O Supabase documenta que o controle de acesso continua valendo para enviar, apagar, mover e copiar, esteja o bucket como estiver. Público muda uma coisa só: se quem tem o endereço de um arquivo consegue abrir esse arquivo sem entrar na conta. Então a chave deixa o seu envio recusado e faz com que os arquivos que já estavam lá possam ser abertos por qualquer um que tenha o endereço deles.",{"q":572,"a":573},"De quais policies um bucket precisa?","Um envio precisa de uma regra insert em storage.objects. Se o seu código substitui arquivos de mesmo nome, que é o que o upsert faz, o Supabase diz que também precisa de select e update. Abrir um arquivo num bucket privado precisa de uma regra select, e listar o que está no bucket também, porque essas duas ações do Storage rodam sobre o mesmo privilégio de SQL. Apagar precisa de uma regra delete. Não é obrigatório escrever as quatro, só as que o seu app de fato faz.",{"q":575,"a":576},"Um bucket público é perigoso?","Depende inteiramente do que tem dentro. Público é o ajuste certo para fotos de perfil, logos e qualquer outra coisa que o seu app mostre a um visitante que não entrou na conta, que é justamente o que o Supabase lista como casos de uso dele. É o ajuste errado para notas fiscais, exportações ou qualquer coisa que pertença a uma pessoa específica, e para isso você quer um bucket privado com um link assinado. A pergunta nunca foi se público é ruim.",{"q":578,"a":579},"Como eu confiro se o meu bucket pode ser listado?","Pergunte de fora, sem nenhuma conta conectada, exatamente como um estranho faria. A listagem é concedida por uma regra select e não pela chave de público, então nem a chave no painel nem uma olhada na sua lista de policies respondem isso. O nosso escaneamento gratuito faz isso no seu projeto em produção e diz quais dos seus buckets responderam com os nomes do que tinham dentro.","\u002Fblog\u002Fstorage-upload-violates-row-level-security\u002Fcard-800x500.png",[582,583,584,585,586,587,588],"new row violates row-level security policy for table objects","erro rls upload supabase storage","supabase storage policy upload","supabase bucket upload 403","storage objects rls supabase","supabase upload permissão negada","exemplo policy supabase storage",{},true,"\"Row-level security policy for table objects\"","\u002Fblog\u002Fstorage-upload-violates-row-level-security","2026-10-11",{"title":5,"description":561},"blog\u002Fstorage-upload-violates-row-level-security",[597,598,599,600],"\"New row violates row-level security policy for table objects\" quer dizer que o seu envio chegou ao Supabase Storage e nenhuma regra em storage.objects deixou o arquivo entrar. O arquivo não foi guardado, e o resto do bucket continua intacto.","O Storage guarda as regras numa única tabela para todos os buckets do seu projeto, e é por isso que a mensagem cita uma tabela que você nunca criou.","Deixar o bucket público não resolve. O Supabase confere os envios de qualquer jeito, e público só decide quem pode abrir um arquivo cujo endereço já tem.","Um envio precisa de uma regra insert em storage.objects. Se o seu código salva com upsert, também precisa de select e update.","4utcsQEXUrdNqEF8vctFybkfqVNjOw_F-VU0FlYmesA",[603,604,610,616,622,628,634,640,646,652,658,664,670,676,683,689,695,700,706,712,718,724,730,736,742,748,754,760,766,772,778,784,790,796,802,808,814,820,826,832,838,844,850,856,862,868,874,879,885,891,897,902,908,914,920,925,931,937,943,948,954],{"path":592,"title":5,"description":561,"published":593,"category":558,"image":580,"draft":562},{"path":605,"title":606,"description":607,"published":608,"category":558,"image":609,"draft":562},"\u002Fblog\u002Fbase44-security-scan","Scan de segurança do Base44: o que só ele enxerga","O scan de segurança do Base44 verifica sete tipos de problema por dentro. Esta é a metade que ele lê e mais ninguém, e a metade que ele nunca olha.","2026-10-10","\u002Fblog\u002Fbase44-security-scan\u002Fcard-800x500.png",{"path":611,"title":612,"description":613,"published":614,"category":558,"image":615,"draft":562},"\u002Fblog\u002Fapi-key-leaked-what-to-do","Sua chave de API vazou. A ordem em que agir","Uma chave de API vazou e você não sabe o que fazer primeiro. Nem toda chave no seu frontend é um vazamento, e a ordem importa mais que a pressa.","2026-10-09","\u002Fblog\u002Fapi-key-leaked-what-to-do\u002Fcard-800x500.png",{"path":617,"title":618,"description":619,"published":620,"category":558,"image":621,"draft":562},"\u002Fblog\u002Finfinite-recursion-in-policy-for-relation","\"Infinite recursion detected in policy\" sem desligar o RLS","\"Infinite recursion detected in policy for relation\" significa que a sua policy perguntou à tabela que ela protege. Veja como quebrar o círculo.","2026-10-08","\u002Fblog\u002Finfinite-recursion-in-policy-for-relation\u002Fcard-800x500.png",{"path":623,"title":624,"description":625,"published":626,"category":558,"image":627,"draft":562},"\u002Fblog\u002Fno-api-key-found-in-request","\"No API key found in request\" no Supabase, e a correção errada","\"No API key found in request\" significa que sua requisição chegou ao Supabase sem chave. Quase toda resposta aponta para as regras do seu banco.","2026-10-07","\u002Fblog\u002Fno-api-key-found-in-request\u002Fcard-800x500.png",{"path":629,"title":630,"description":631,"published":632,"category":558,"image":633,"draft":562},"\u002Fblog\u002Fis-base44-safe","O Base44 é seguro? O que vimos em 5.442 apps Base44","O Base44 é seguro? Rodamos nove verificações em 5.442 apps Base44 no ar. Quase todas tiraram B por motivos que o dono nunca escolheu.","2026-10-06","\u002Fblog\u002Fis-base44-safe\u002Fcard-800x500.png",{"path":635,"title":636,"description":637,"published":638,"category":558,"image":639,"draft":562},"\u002Fblog\u002Fmove-a-secret-to-an-edge-function","Esconder uma chave de API: mova para uma Edge Function do Supabase","Esconder uma chave de API é tirá-la do navegador, e uma Edge Function do Supabase é o menor lugar para guardá-la. Dois passos em volta pesam mais.","2026-10-05","\u002Fblog\u002Fmove-a-secret-to-an-edge-function\u002Fcard-800x500.png",{"path":641,"title":642,"description":643,"published":644,"category":558,"image":645,"draft":562},"\u002Fblog\u002Fenv-file-exposed-on-your-server","Seu arquivo .env está exposto? Os doze caminhos para testar","Seu arquivo .env está exposto no seu próprio servidor web? Doze endereços dizem isso em um minuto, e um acerto significa que tudo nele já é público.","2026-10-04","\u002Fblog\u002Fenv-file-exposed-on-your-server\u002Fcard-800x500.png",{"path":647,"title":648,"description":649,"published":650,"category":558,"image":651,"draft":562},"\u002Fblog\u002Fis-v0-safe","Segurança do v0: os 1.790 aplicativos v0 escaneados tiraram A","A segurança do v0 medida em 1.790 aplicativos v0 no ar: todos tiraram A. Só 17 citavam um banco de dados, e é sobretudo isso que esse A mede.","2026-10-03","\u002Fblog\u002Fis-v0-safe\u002Fcard-800x500.png",{"path":653,"title":654,"description":655,"published":656,"category":558,"image":657,"draft":562},"\u002Fblog\u002Fis-bolt-safe","O Bolt é seguro? O que vimos em 1.123 aplicativos Bolt","O Bolt é seguro? Passamos 1.123 aplicativos Bolt no ar por nove verificações. A hospedagem saiu limpa. Os achados: chaves e tabelas abertas nos aplicativos.","2026-10-02","\u002Fblog\u002Fis-bolt-safe\u002Fcard-800x500.png",{"path":659,"title":660,"description":661,"published":662,"category":558,"image":663,"draft":562},"\u002Fblog\u002Fis-supabase-down-or-your-app","O Supabase caiu ou o problema é o seu app? Como saber","O Supabase caiu ou o problema é o seu app? Um projeto pausado, um banco cheio e um erro seu parecem iguais. Quatro verificações separam os casos.","2026-10-01","\u002Fblog\u002Fis-supabase-down-or-your-app\u002Fcard-800x500.png",{"path":665,"title":666,"description":667,"published":668,"category":558,"image":669,"draft":562},"\u002Fblog\u002Fdoes-supabase-encrypt-my-data","O Supabase criptografa meus dados? Sim. Veja o que isso impede","O Supabase criptografa os dados? Sim: AES-256 em repouso, TLS em trânsito, SOC 2 e ISO 27001. O que cada um cobre, e o vazamento que nenhum deles impede.","2026-09-30","\u002Fblog\u002Fdoes-supabase-encrypt-my-data\u002Fcard-800x500.png",{"path":671,"title":672,"description":673,"published":674,"category":558,"image":675,"draft":562},"\u002Fblog\u002Fsupabase-free-plan-limits","Quanto custa o Supabase? Os limites do plano gratuito","Quanto custa o Supabase: o plano gratuito tem 500 MB de banco, 5 GB de egress e nenhum backup. O que acontece em cada limite e o que o Pro de $25 muda.","2026-09-29","\u002Fblog\u002Fsupabase-free-plan-limits\u002Fcard-800x500.png",{"path":677,"title":678,"description":679,"published":680,"category":681,"image":682,"draft":562},"\u002Fblog\u002Ftest-your-supabase-backup","Teste o backup do seu Supabase antes do dia em que precisar","Como testar o backup do seu Supabase: restaurar num projeto de teste, contar as linhas, entrar e procurar a linha que falta num arquivo cortado.","2026-09-28","Backups","\u002Fblog\u002Ftest-your-supabase-backup\u002Fcard-800x500.png",{"path":684,"title":685,"description":686,"published":687,"category":681,"image":688,"draft":562},"\u002Fblog\u002Fsupabase-backup-github-action","Backup grátis do Supabase com uma GitHub Action, e a pegadinha","Um backup do Supabase com GitHub Action é grátis e serve para muitos apps. O workflow, a connection string certa e o egress de cada execução.","2026-09-27","\u002Fblog\u002Fsupabase-backup-github-action\u002Fcard-800x500.png",{"path":690,"title":691,"description":692,"published":693,"category":681,"image":694,"draft":562},"\u002Fblog\u002Fdownload-your-supabase-backup","Por que você não consegue baixar seu backup do Supabase","Você não consegue baixar seu backup do Supabase num projeto atual, porque a cópia diária é um snapshot físico. Como conferir e como ter uma cópia só sua.","2026-09-26","\u002Fblog\u002Fdownload-your-supabase-backup\u002Fcard-800x500.png",{"path":696,"title":697,"description":698,"published":693,"category":558,"image":699,"draft":562},"\u002Fblog\u002Fsupabase-permission-denied-for-table","Supabase \"permission denied for table\": o grant que falta","A partir de 30 de outubro, uma tabela nova no Supabase responde \"permission denied for table\" até receber um grant. O e-mail mostra só metade.","\u002Fblog\u002Fsupabase-permission-denied-for-table\u002Fcard-800x500.png",{"path":701,"title":702,"description":703,"published":704,"category":558,"image":705,"draft":562},"\u002Fblog\u002Fopen-api-endpoint-exposed","Um endpoint de API aberto é um problema? Leia o JSON","Seu scan apontou um endpoint de API aberto. Se isso importa depende do que voltou, e a maioria dos que encontramos era da própria plataforma.","2026-09-25","\u002Fblog\u002Fopen-api-endpoint-exposed\u002Fcard-800x500.png",{"path":707,"title":708,"description":709,"published":710,"category":558,"image":711,"draft":562},"\u002Fblog\u002Flovable-security-scan","Escaneamento de segurança do Lovable: o que ele não prova","Escaneamento de segurança do Lovable: o que o Quick scan e o Deep scan checam, quando cada um roda, e a única coisa que nenhum escaneamento por dentro prova.","2026-09-24","\u002Fblog\u002Flovable-security-scan\u002Fcard-800x500.png",{"path":713,"title":714,"description":715,"published":716,"category":681,"image":717,"draft":562},"\u002Fblog\u002Fsupabase-backup-auth-users","Por que seu dump do Supabase não tem usuários dentro","Rode supabase db dump sozinho e você recebe a forma do seu banco e nenhuma das linhas dele, sem o schema auth onde seus usuários moram.","2026-09-23","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":719,"title":720,"description":721,"published":722,"category":558,"image":723,"draft":562},"\u002Fblog\u002Fdomain-and-certificate-expiry","Domínio expirado, site fora do ar: o que acontece agora","Seu domínio expirou e seu site está fora do ar. O relógio que começa a correr, por que o certificado é o problema menor, e como conferir os dois.","2026-09-22","\u002Fblog\u002Fdomain-and-certificate-expiry\u002Fcard-800x500.png",{"path":725,"title":726,"description":727,"published":728,"category":558,"image":729,"draft":562},"\u002Fblog\u002Fis-lovable-safe","O Lovable é seguro? O que vimos em 18.554 aplicativos Lovable","O Lovable é seguro? Passamos 18.554 aplicativos Lovable no ar por nove verificações. A plataforma foi a mais limpa de cinco. Os achados estavam nos aplicativos.","2026-09-21","\u002Fblog\u002Fis-lovable-safe\u002Fcard-800x500.png",{"path":731,"title":732,"description":733,"published":734,"category":558,"image":735,"draft":562},"\u002Fblog\u002Fvibe-coded-app-security-checklist","O checklist de segurança do vibe coding, em nove verificações","Um checklist de segurança do vibe coding com nove itens, cada um verificável no seu app de fora por qualquer pessoa, e cada um com um teste de uma linha.","2026-09-20","\u002Fblog\u002Fvibe-coded-app-security-checklist\u002Fcard-800x500.png",{"path":737,"title":738,"description":739,"published":740,"category":558,"image":741,"draft":562},"\u002Fblog\u002Fstripe-secret-key-in-frontend","Uma chave secreta da Stripe no frontend pode mover dinheiro","Uma chave secreta da Stripe exposta no seu frontend pode reembolsar, cobrar e ler cada ficha de cliente que você tem. Sua chave pk_live_ é que deve estar aí.","2026-09-19","\u002Fblog\u002Fstripe-secret-key-in-frontend\u002Fcard-800x500.png",{"path":743,"title":744,"description":745,"published":746,"category":558,"image":747,"draft":562},"\u002Fblog\u002Fvite-and-next-public-env-vars","Variáveis de ambiente do Vite expostas: o prefixo diz publique isto","Variáveis de ambiente do Vite expostas no seu app: fizeram o que o prefixo pediu. VITE_ e NEXT_PUBLIC_ significam publique isto, e a IA nunca soube o custo.","2026-09-18","\u002Fblog\u002Fvite-and-next-public-env-vars\u002Fcard-800x500.png",{"path":749,"title":750,"description":751,"published":752,"category":558,"image":753,"draft":562},"\u002Fblog\u002Fbase44-source-maps","Segurança no Base44: o que um scan aponta e o que é seu para corrigir","Segurança no Base44 em 5.438 apps escaneados: três achados em quase todos são da plataforma, o source map é o selo do Base44, e a sua parte é uma lista curta.","2026-09-17","\u002Fblog\u002Fbase44-source-maps\u002Fcard-800x500.png",{"path":755,"title":756,"description":757,"published":758,"category":558,"image":759,"draft":562},"\u002Fblog\u002Fis-cursor-ai-safe","O Cursor AI é seguro? O editor, o código e o app que você publicou","O Cursor AI é seguro? Três perguntas em uma busca: o que o Cursor guarda, o que o código que ele escreve erra, e se o app que você publicou está aberto.","2026-09-16","\u002Fblog\u002Fis-cursor-ai-safe\u002Fcard-800x500.png",{"path":761,"title":762,"description":763,"published":764,"category":558,"image":765,"draft":562},"\u002Fblog\u002Fis-replit-safe","O Replit é seguro? O que vimos em 3.042 aplicativos Replit no ar","O Replit é seguro? Passamos 3.042 aplicativos Replit no ar por nove verificações externas. Os achados estavam no aplicativo publicado, não no host.","2026-09-15","\u002Fblog\u002Fis-replit-safe\u002Fcard-800x500.png",{"path":767,"title":768,"description":769,"published":770,"category":681,"image":771,"draft":562},"\u002Fblog\u002Fsupabase-storage-backup","Supabase storage backup: sua cópia do banco não tem nenhum arquivo","Um Supabase storage backup é uma tarefa à parte. Os backups do banco guardam a lista dos seus arquivos e nenhum deles, então cada upload fica quebrado.","2026-09-14","\u002Fblog\u002Fsupabase-storage-backup\u002Fcard-800x500.png",{"path":773,"title":774,"description":775,"published":776,"category":681,"image":777,"draft":562},"\u002Fblog\u002Fsupabase-point-in-time-recovery","Point-in-time recovery do Supabase: preço e limites","O point-in-time recovery do Supabase rebobina seu banco para qualquer segundo da última semana. Custa $100 por mês além do Pro e cobre só o banco.","2026-09-13","\u002Fblog\u002Fsupabase-point-in-time-recovery\u002Fcard-800x500.png",{"path":779,"title":780,"description":781,"published":782,"category":681,"image":783,"draft":562},"\u002Fblog\u002Fsupabase-project-paused-recover","Projeto Supabase pausado? Seus dados continuam lá","O Supabase pausou seu projeto depois de uma semana sem atividade. Nada foi apagado, Restaurar fica ao lado do nome e você tem um ano antes disso mudar.","2026-09-12","\u002Fblog\u002Fsupabase-project-paused-recover\u002Fcard-800x500.png",{"path":785,"title":786,"description":787,"published":788,"category":558,"image":789,"draft":562},"\u002Fblog\u002Fsafest-ai-app-builder","Qual builder de apps com IA é mais seguro? 30.998 apps testados","Qual builder de apps com IA é mais seguro? Escaneamos 30.998 apps no ar do Lovable, Base44, Replit, v0 e Bolt. O builder não é o que decide sua nota.","2026-09-11","\u002Fblog\u002Fsafest-ai-app-builder\u002Fcard-800x500.png",{"path":791,"title":792,"description":793,"published":794,"category":558,"image":795,"draft":562},"\u002Fblog\u002Fenable-rls-on-every-supabase-table","Ative Row Level Security em toda tabela do Supabase e comprove","Ativar Row Level Security no Supabase sem política fecha a tabela por completo. Uma política sem a chave ligada não faz nada. Aqui está o SQL, e o teste.","2026-09-10","\u002Fblog\u002Fenable-rls-on-every-supabase-table\u002Fcard-800x500.png",{"path":797,"title":798,"description":799,"published":800,"category":558,"image":801,"draft":562},"\u002Fblog\u002Fsupabase-rls-disabled-in-public","Supabase \"RLS disabled in public\": o que o aviso não vê","O Supabase marca \"RLS disabled in public\" como erro. Ele não diz nada sobre a política de leitura que deixa a sua tabela igualmente aberta.","2026-09-09","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",{"path":803,"title":804,"description":805,"published":806,"category":558,"image":807,"draft":562},"\u002Fblog\u002Frotate-supabase-service-role-key","Como rotacionar uma chave service_role do Supabase vazada","O Supabase manda fechar o vazamento primeiro. Outros guias mandam rotacionar agora. O que vale depende de para onde a sua chave service_role vazou.","2026-09-08","\u002Fblog\u002Frotate-supabase-service-role-key\u002Fcard-800x500.png",{"path":809,"title":810,"description":811,"published":812,"category":558,"image":813,"draft":562},"\u002Fblog\u002Fvibe-coding-security-scanners-compared","Scanners de segurança para vibe coding comparados, o nosso incluído","O melhor scanner de segurança para vibe coding depende de três perguntas que nenhuma lista de recursos responde. Dez ferramentas comparadas, com preços.","2026-09-07","\u002Fblog\u002Fvibe-coding-security-scanners-compared\u002Fcard-800x500.png",{"path":815,"title":816,"description":817,"published":818,"category":558,"image":819,"draft":562},"\u002Fblog\u002Fsupabase-security-checker","Supabase security checker: faça você mesmo as cinco verificações","Um Supabase security checker lê o seu app publicado em vez das configurações do projeto. Aqui estão as cinco verificações e como fazer cada uma sozinho.","2026-09-06","\u002Fblog\u002Fsupabase-security-checker\u002Fcard-800x500.png",{"path":821,"title":822,"description":823,"published":824,"category":558,"image":825,"draft":562},"\u002Fblog\u002Fvibe-coding-security-scanner","Scanner de segurança para vibe coding: o que ele não vê","Um scanner de segurança para vibe coding lê seu app no ar, de fora. O que isso cobre, as quatro coisas que ele não consegue ver e como ler o resultado.","2026-09-05","\u002Fblog\u002Fvibe-coding-security-scanner\u002Fcard-800x500.png",{"path":827,"title":828,"description":829,"published":830,"category":558,"image":831,"draft":562},"\u002Fblog\u002Fmissing-security-headers","Cabeçalhos de segurança faltando: quando isso importa","Cabeçalhos de segurança faltando é o achado que nosso scanner mais imprime. Contra o que eles protegem e quando são a linha menos urgente do relatório.","2026-09-04","\u002Fblog\u002Fmissing-security-headers\u002Fcard-800x500.png",{"path":833,"title":834,"description":835,"published":836,"category":558,"image":837,"draft":562},"\u002Fblog\u002Fopenai-api-key-exposed-in-frontend","Sua chave de API da OpenAI está exposta no frontend. Troque-a.","Uma chave de API da OpenAI exposta no frontend não pode ser presa a um domínio. Troque-a hoje, mova a chamada para o seu servidor e limite o gasto.","2026-09-03","\u002Fblog\u002Fopenai-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":839,"title":840,"description":841,"published":842,"category":558,"image":843,"draft":562},"\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps","Chave de API exposta no frontend: o que 30.998 apps entregam","Uma chave de API exposta no seu frontend costuma ser uma chave do Google Maps. Escaneamos 30.998 apps vibe-coded e contamos quais segredos vazam de verdade.","2026-09-02","\u002Fblog\u002Fwhat-secrets-leak-from-vibe-coded-apps\u002Fcard-800x500.png",{"path":845,"title":846,"description":847,"published":848,"category":681,"image":849,"draft":562},"\u002Fblog\u002Fsupabase-backup-tools-compared","Ferramentas de backup do Supabase comparadas, a nossa incluída","Quatro tipos de ferramenta de backup do Supabase, o que cada uma copia de verdade e quando uma GitHub Action gratuita ganha de pagar, nós inclusive.","2026-09-01","\u002Fblog\u002Fsupabase-backup-tools-compared\u002Fcard-800x500.png",{"path":851,"title":852,"description":853,"published":854,"category":558,"image":855,"draft":562},"\u002Fblog\u002Freplit-secrets-explained","Como usar secrets no Replit, e o que ainda assim é publicado","Como usar secrets no Replit: adicionar um, ler de volta e resolver as duas causas do undefined. E as chaves que a ferramenta Secrets não consegue proteger.","2026-08-31","\u002Fblog\u002Freplit-secrets-explained\u002Fcard-800x500.png",{"path":857,"title":858,"description":859,"published":860,"category":681,"image":861,"draft":562},"\u002Fblog\u002Fback-up-supabase-free-tier","Backups do plano gratuito do Supabase: como fazer sem terminal","No plano gratuito do Supabase não existe backup nenhum: a cópia é você que faz. Como fazer uma pelo painel e o que a rota do CSV deixa para trás.","2026-08-30","\u002Fblog\u002Fback-up-supabase-free-tier\u002Fcard-800x500.png",{"path":863,"title":864,"description":865,"published":866,"category":558,"image":867,"draft":562},"\u002Fblog\u002Fis-supabase-secure","O Supabase é seguro? É. Seu projeto é outra pergunta","O Supabase é seguro? A plataforma é auditada, criptografada e passa por pentests. A documentação deles diz onde isso termina e começam suas configurações.","2026-08-29","\u002Fblog\u002Fis-supabase-secure\u002Fcard-800x500.png",{"path":869,"title":870,"description":871,"published":872,"category":558,"image":873,"draft":562},"\u002Fblog\u002Fwhere-to-find-supabase-api-keys","Onde ficam as chaves de API do Supabase: anon, service_role e URL","A URL do projeto, a chave anon e a chave service_role ficam todas numa página do painel. Aqui está onde ela fica, e qual dos quatro valores vai no seu app.","2026-08-28","\u002Fblog\u002Fwhere-to-find-supabase-api-keys\u002Fcard-800x500.png",{"path":67,"title":875,"description":876,"published":877,"category":558,"image":878,"draft":562},"New row violates row-level security policy no Supabase. E agora?","\"New row violates row-level security policy\" significa que o Supabase recusou uma escrita. O conserto rápido reabre a tabela para qualquer um.","2026-08-27","\u002Fblog\u002Fnew-row-violates-row-level-security-policy\u002Fcard-800x500.png",{"path":880,"title":881,"description":882,"published":883,"category":558,"image":884,"draft":562},"\u002Fblog\u002Fcors-wildcard-security-risk","Um curinga CORS é um risco de segurança? Quase nunca.","Um curinga CORS é um risco de segurança? Em geral é o padrão do seu builder e não entrega nada que o seu servidor já não desse a qualquer um que pedisse.","2026-08-26","\u002Fblog\u002Fcors-wildcard-security-risk\u002Fcard-800x500.png",{"path":886,"title":887,"description":888,"published":889,"category":681,"image":890,"draft":562},"\u002Fblog\u002Fsupabase-branching-is-not-a-backup","Branching do Supabase não é backup. Ele só anda para a frente.","Por que o branching do Supabase não é backup: um branch começa sem os seus dados e um merge só leva o esquema. Para que ele serve e o que usar no lugar.","2026-08-25","\u002Fblog\u002Fsupabase-branching-is-not-a-backup\u002Fcard-800x500.png",{"path":892,"title":893,"description":894,"published":895,"category":681,"image":896,"draft":562},"\u002Fblog\u002Fhow-to-restore-a-supabase-backup","Como restaurar um backup do Supabase, e o que quebra depois","Como restaurar um backup do Supabase pelo painel ou por um arquivo de dump, o que a restauração substitui e por que o seu app pode continuar quebrado no fim.","2026-08-24","\u002Fblog\u002Fhow-to-restore-a-supabase-backup\u002Fcard-800x500.png",{"path":126,"title":898,"description":899,"published":900,"category":558,"image":901,"draft":562},"Seu bucket do Supabase Storage é público. Isso é um problema?","Um bucket público do Supabase Storage significa que quem tem a URL de um arquivo pode abri-lo. Não significa que alguém possa listar o que está lá dentro.","2026-08-23","\u002Fblog\u002Fsupabase-storage-bucket-public\u002Fcard-800x500.png",{"path":903,"title":904,"description":905,"published":906,"category":558,"image":907,"draft":562},"\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend","Uma chave de API do Google no frontend é um problema?","Uma chave de API do Google exposta no seu frontend é a chave que nosso scanner mais encontra, e quase sempre está tudo bem. Um ajuste gratuito decide isso.","2026-08-22","\u002Fblog\u002Fgoogle-api-key-exposed-in-frontend\u002Fcard-800x500.png",{"path":909,"title":910,"description":911,"published":912,"category":681,"image":913,"draft":562},"\u002Fblog\u002Fai-agent-deleted-my-database","Um agente de IA apagou meus dados do Supabase. O que eu recupero?","Um agente de IA apagou dados do seu banco. O que você recupera já estava decidido antes de ele rodar, e os próximos minutos decidem o resto.","2026-08-21","\u002Fblog\u002Fai-agent-deleted-my-database\u002Fcard-800x500.png",{"path":915,"title":916,"description":917,"published":918,"category":558,"image":919,"draft":562},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","Qualquer um consegue ler seu banco Supabase? Testamos 3.680 apps","Qualquer um consegue ler seu banco de dados Supabase sem fazer login? Escaneamos 30.998 apps no ar criadas com builders de IA e medimos quantas dizem que sim.","2026-08-18","\u002Fblog\u002Fcan-anyone-read-your-supabase-database\u002Fcard-800x500.png",{"path":921,"title":922,"description":923,"published":918,"category":558,"image":924,"draft":562},"\u002Fblog\u002Fsource-maps-exposed-in-production","Source maps expostos: seu app está publicando o código original","Um source map exposto deixa qualquer um ler o código original do seu app, comentários incluídos. A verificação de 30 segundos e o que importa de verdade.","\u002Fblog\u002Fsource-maps-exposed-in-production\u002Fcard-800x500.png",{"path":926,"title":927,"description":928,"published":929,"category":558,"image":930,"draft":562},"\u002Fblog\u002Fsupabase-new-api-keys","As novas chaves de API do Supabase: qual vai no seu app?","O Supabase trocou anon e service_role por chaves publicáveis e secretas. Qual delas pertence ao seu app e qual nunca deve estar lá?","2026-08-12","\u002Fblog\u002Fsupabase-new-api-keys\u002Fcard-800x500.png",{"path":932,"title":933,"description":934,"published":935,"category":681,"image":936,"draft":562},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","O Supabase faz backup do meu banco de dados? Depende do plano.","O Supabase faz backup do seu banco de dados? Todo dia nos planos pagos, e nada no gratuito. Como descobrir o que você tem e o que essa cópia não cobre.","2026-08-11","\u002Fblog\u002Fdoes-supabase-back-up-my-database\u002Fcard-800x500.png",{"path":938,"title":939,"description":940,"published":941,"category":558,"image":942,"draft":562},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","O Supabase Row Level Security está ligado. A tabela continua pública.","Ligar o Supabase Row Level Security não protege uma tabela. Quem protege são as políticas, e a que consertou o seu app pode deixar qualquer um entrar.","2026-08-10","\u002Fblog\u002Fsupabase-rls-on-but-table-still-public\u002Fcard-800x500.png",{"path":944,"title":945,"description":946,"published":941,"category":681,"image":947,"draft":562},"\u002Fblog\u002Fversion-history-is-not-a-backup","O histórico de versões não é backup. Ele não desfaz um delete.","Lovable e Bolt guardam um histórico de versões do seu código. Seu banco de dados é um serviço à parte, e voltar atrás não traz os seus dados de volta.","\u002Fblog\u002Fversion-history-is-not-a-backup\u002Fcard-800x500.png",{"path":949,"title":950,"description":951,"published":952,"category":681,"image":953,"draft":562},"\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database","Três formas de fazer backup de um banco Supabase, e o que falta","O painel, o pg_dump e um serviço gerenciado. O que cada um salva de verdade, o que deixa de fora sem avisar e qual sobrevive a perder a conta.","2026-08-09","\u002Fblog\u002Fthree-ways-to-back-up-a-supabase-database\u002Fcard-800x500.png",{"path":955,"title":956,"description":957,"published":952,"category":558,"image":958,"draft":562},"\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend","Quais chaves de API são seguras no navegador e quais não são","Sua chave anon do Supabase foi feita para ser pública. Sua chave service_role não, e ela ignora todas as regras que você criar. Como diferenciar as duas.","\u002Fblog\u002Fwhich-api-keys-are-safe-in-your-frontend\u002Fcard-800x500.png",1791705963220]