[{"data":1,"prerenderedAt":731},["ShallowReactive",2],{"blog-pt-supabase-rls-disabled-in-public":3,"blog-index-pt":490},{"id":4,"title":5,"body":6,"category":446,"cover":447,"coverAlt":448,"description":449,"draft":450,"extension":451,"faq":452,"image":468,"keywords":469,"meta":478,"navigation":479,"ogTitle":480,"path":481,"published":482,"seo":483,"stem":484,"tldr":485,"updated":482,"__hash__":489},"blog_pt\u002Fblog\u002Fsupabase-rls-disabled-in-public.md","Supabase \"RLS disabled in public\": o que o aviso não vê",{"type":7,"value":8,"toc":434},"minimark",[9,18,29,36,41,44,55,58,61,65,68,71,77,80,83,87,98,101,107,110,117,211,214,220,234,238,241,248,251,254,260,270,274,277,280,285,298,305,309,312,315,328,334,347,351,354,361,364,369,372,384,388,421],[10,11,12,13,17],"p",{},"Você abriu o Security Advisor no seu dashboard do Supabase, ou alguém colou a\nsaída dele na sua frente, e lá está em vermelho: ",[14,15,16],"strong",{},"RLS disabled in public",".\nEmbaixo, uma linha por tabela, nas palavras do próprio Supabase:",[19,20,25],"pre",{"className":21,"code":23,"language":24},[22],"language-text","Table public.profiles is public, but RLS has not been enabled.\n","text",[26,27,23],"code",{"__ignoreMap":28},"",[10,30,31,32,35],{},"Aqui está a parte que guia após guia conta errado: ",[14,33,34],{},"zerar essa lista não quer\ndizer que ninguém consegue ler os seus dados."," O advisor tem uma regra separada\npara uma política que deixa todo mundo entrar, e essa regra pula exatamente a\nforma que um construtor de IA escreve quando destrava o seu app. Então a lista\nque você acabou de resolver e a lista de tabelas que um desconhecido consegue\nler são duas listas diferentes, e uma delas não aparece em lugar nenhum do seu\ndashboard.",[37,38,40],"h2",{"id":39},"o-que-significa-rls-disabled-in-public","O que significa \"RLS disabled in public\"?",[10,42,43],{},"Uma tabela do seu schema public está com o Row Level Security desligado, e a\nconsequência é que qualquer pessoa com o endereço do seu projeto consegue ler\ntodas as linhas dela.",[10,45,46,47,50,51,54],{},"As duas metades disso precisam ser abertas. O ",[14,48,49],{},"schema public"," é o lugar para\nonde uma tabela vai quando ninguém diz o contrário, e é a parte do seu banco que\no Supabase publica na web: cada projeto responde requisições em um endereço\npróprio, e a chave necessária para falar com ele está no código que o seu site\nmanda para cada visitante. ",[14,52,53],{},"Row Level Security"," é a chave que decide se as\nsuas regras são consultadas antes de as linhas saírem. Com ela desligada não há\nnada para consultar, então a resposta é sempre sim.",[10,56,57],{},"É essa combinação que faz isso ser reportado como erro e não como aviso. O\nadvisor classifica o que encontra, e este é o degrau mais alto.",[10,59,60],{},"Pense no advisor como um fiscal com uma prancheta. Ele lê a sua papelada com\ncuidado e faz isso bem. Ele nunca testa a maçaneta. Nada naquele painel é\nresultado de uma requisição que alguém tenha feito ao seu banco.",[37,62,64],{"id":63},"ativar-o-rls-vai-quebrar-o-meu-app","Ativar o RLS vai quebrar o meu app?",[10,66,67],{},"Vai, na hora, e é a configuração funcionando.",[10,69,70],{},"A correção que o Supabase te dá é uma linha, e você roda ela no SQL Editor:",[19,72,75],{"className":73,"code":74,"language":24},[22],"alter table public.profiles enable row level security;\n",[26,76,74],{"__ignoreMap":28},[10,78,79],{},"A documentação do próprio Supabase é direta sobre o que vem depois: com uma\nchave publicável os dados ficam inacessíveis pela API enquanto não houver\npolíticas definidas. Então suas listas voltam vazias, suas telas ficam em\nbranco, e o erro no advisor é substituído por uma entrada mais discreta dizendo\nque a tabela está com RLS ativo mas sem políticas.",[10,81,82],{},"Essa é a porta fechada com ninguém ainda na lista. A próxima coisa que quase\ntodo mundo faz é adicionar uma política que deixa todo mundo ler, porque é o que\nfaz as telas voltarem.",[37,84,86],{"id":85},"a-falha-que-o-aviso-não-está-procurando","A falha que o aviso não está procurando",[10,88,89,90,93,94,97],{},"Uma tabela com o Row Level Security ",[14,91,92],{},"ligado"," e uma política de leitura cuja\ncondição é ",[26,95,96],{},"USING (true)"," entrega exatamente as mesmas linhas exatamente para o\nmesmo desconhecido. O advisor não aponta isso.",[10,99,100],{},"Não é um descuido. O Supabase tem sim uma regra para políticas sempre\nverdadeiras, e ela deixa as de leitura de fora de propósito. A descrição da\nprópria regra diz isso:",[19,102,105],{"className":103,"code":104,"language":24},[22],"SELECT policies with `USING (true)` are intentionally excluded as this\npattern is often used deliberately for public read access.\n",[26,106,104],{"__ignoreMap":28},[10,108,109],{},"No caso geral a regra está certa. Um catálogo de produtos, uma lista de artigos\npublicados, um mapa de locais: essas coisas foram feitas para qualquer um ler, e\napontá-las treinaria todo desenvolvedor da plataforma a ignorar o painel. O que\nnenhum linter consegue saber é se a tabela na frente dele guarda locais ou\nclientes.",[10,111,112,113,116],{},"E uma política que deixa todo mundo ler é o jeito mais rápido de fazer um app\nquebrado voltar a funcionar, que é por isso que um construtor de IA recorre a\nela. Peça para o Cursor ou para o Lovable consertar as telas vazias e\n",[26,114,115],{},"FOR SELECT USING (true)"," é uma resposta comum. O seu app carrega, o erro some,\no painel se cala, e a tabela continua tão legível quanto antes.",[118,119,120,136],"table",{},[121,122,123],"thead",{},[124,125,126,130,133],"tr",{},[127,128,129],"th",{},"O que o advisor consegue ver",[127,131,132],{},"Como ele reporta",[127,134,135],{},"O que um desconhecido com a sua chave publicável recebe",[137,138,139,155,169,182,197],"tbody",{},[124,140,141,145,148],{},[142,143,144],"td",{},"RLS desligado",[142,146,147],{},"Erro",[142,149,150],{},[151,152,154],"key-verdict",{"type":153},"danger","Todas as linhas",[124,156,157,160,163],{},[142,158,159],{},"RLS ligado, nenhuma política",[142,161,162],{},"Info",[142,164,165],{},[151,166,168],{"type":167},"safe","Nada",[124,170,171,176,178],{},[142,172,173,174],{},"RLS ligado, ",[26,175,115],{},[142,177,168],{},[142,179,180],{},[151,181,154],{"type":153},[124,183,184,189,192],{},[142,185,173,186],{},[26,187,188],{},"FOR ALL USING (true)",[142,190,191],{},"Aviso",[142,193,194],{},[151,195,196],{"type":153},"Todas as linhas, e pode mudá-las",[124,198,199,204,206],{},[142,200,173,201],{},[26,202,203],{},"USING (auth.uid() = user_id)",[142,205,168],{},[142,207,208],{},[151,209,210],{"type":167},"Só as dele",[10,212,213],{},"As duas linhas onde nada é reportado são o par que merece um minuto. Uma é uma\ntabela que ninguém fora do seu app consegue tocar. A outra é uma tabela que\nqualquer um consegue ler. O seu dashboard fica igualmente calado sobre as duas.",[215,216],"diagram",{"alt":217,"caption":218,"src":219},"Duas faixas terminando nas mesmas quatro linhas, todas acesas. A faixa de cima está com a chave do Row Level Security desligada e carrega um sinal de aviso. A de baixo está com ela ligada, com uma política mostrando USING (true), e um círculo tracejado vazio onde estaria um sinal.","As mesmas quatro linhas entregues ao mesmo desconhecido. A diferença entre as faixas é sobre qual delas o seu dashboard diz alguma coisa.","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Ftwo-tables-one-outcome-1600x640.png",[10,221,222,223,228,229,233],{},"Como essa política foi parar ali, e por o que trocá-la tabela por tabela, é o\nassunto de\n",[224,225,227],"a",{"href":226},"\u002Fblog\u002Fsupabase-rls-on-but-table-still-public","o Row Level Security está ligado e a tabela continua pública",".\nSe a mesma política também precisa deixar o seu app gravar, o erro que você\nencontra em seguida é\n",[224,230,232],{"href":231},"\u002Fblog\u002Fnew-row-violates-row-level-security-policy","new row violates row-level security policy",".",[37,235,237],{"id":236},"por-que-a-tabela-que-você-criou-com-uma-migração-nunca-te-avisou","Por que a tabela que você criou com uma migração nunca te avisou",[10,239,240],{},"Porque o Table Editor liga o Row Level Security para você e o SQL não liga.",[10,242,243,244,247],{},"O Supabase documenta a diferença sem rodeios: tabelas criadas com o Table Editor\ndo dashboard vêm com RLS ativo por padrão, e tabelas criadas com SQL puro\nprecisam ter isso ativado explicitamente. Uma tabela que você criou clicando\ncomeça protegida. Uma tabela que chegou por um arquivo de migração, um\n",[26,245,246],{},"supabase db push",", um trecho no SQL Editor ou um comando que o seu construtor\nde IA rodou por você começa aberta.",[10,249,250],{},"Esse segundo caminho é como um construtor de IA cria tabelas. Ele escreve o SQL\ne roda por você, então você nunca viu a caixinha e nunca viu que ela estava\ndesmarcada.",[10,252,253],{},"O hábito que fecha isso é colocar a linha na migração, do lado da coisa que ela\nprotege:",[19,255,258],{"className":256,"code":257,"language":24},[22],"create table public.profiles (\n  id uuid primary key references auth.users,\n  full_name text\n);\n\nalter table public.profiles enable row level security;\n",[26,259,257],{"__ignoreMap":28},[261,262,264],"callout",{"type":263},"warn",[10,265,266,269],{},[14,267,268],{},"O advisor é uma foto, não um monitoramento."," Ele reporta como o seu banco\nestava na última vez que rodou, e vai continuar te mostrando tranquilamente um\npainel limpo de antes da migração desta manhã. Rode ele de novo depois de\nqualquer mudança que crie uma tabela ou mexa em uma política, que em um projeto\nfeito com IA são quase todas as mudanças.",[37,271,273],{"id":272},"como-conferir-as-tabelas-que-o-advisor-liberou","Como conferir as tabelas que o advisor liberou",[10,275,276],{},"Faça ao seu banco a pergunta que um desconhecido faz: mande uma requisição de\nfora, com a chave publicável que viaja dentro do seu app, e veja o que volta.",[10,278,279],{},"Essa é a diferença em torno da qual o artigo inteiro gira. O advisor lê a sua\nconfiguração. Uma requisição lê as suas linhas. São duas perguntas diferentes, e\numa tabela pode passar na primeira e não passar na segunda, que é exatamente o\nque uma política de leitura permissiva faz.",[215,281],{"alt":282,"caption":283,"src":284},"Dois leitores fora de um limite tracejado do projeto. Uma lupa alcança só o painel de configurações lá dentro e volta com um círculo tracejado vazio. A requisição de uma pessoa passa direto até as linhas da tabela e volta com elas.","O advisor para nas suas configurações. Uma requisição de fora segue até as linhas, e é por isso que os dois podem discordar sobre a mesma tabela.","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fsettings-versus-answer-1600x600.png",[10,286,287,288,292,293,297],{},"Nós fizemos essa requisição em escala. Entre 12 e 14 de agosto de 2026 rodamos\nnove verificações externas em 30.998 apps no ar publicados pelo Lovable,\nBase44, Replit, v0 e Bolt. Dos 3.680 apps com Supabase onde a verificação\nconseguiu terminar, 2.096 tinham pelo menos uma tabela que respondeu a uma\nrequisição anônima com linhas. Isso dá 57%, e é uma fatia dos apps de que\nconseguimos uma resposta clara, não de tudo que escaneamos. Entre os apps feitos\ncom Bolt foram 27 de 35, uma amostra pequena o bastante para ler como direção e\nnão como taxa. O\n",[224,289,291],{"href":290},"\u002Fresearch\u002Fvibe-coded-app-security-2026","conjunto de dados completo está publicado",",\ne ",[224,294,296],{"href":295},"\u002Fblog\u002Fcan-anyone-read-your-supabase-database","de que esses 57% são uma fatia","\npercorre a contagem.",[10,299,300,301,233],{},"Você mesmo pode fazer essa requisição em uma tabela com um navegador e a sua\nchave publicável. Se preferir não ir tabela por tabela, o nosso escaneamento\ngratuito pergunta ao seu app no ar por fora e diz quais tabelas responderam.\nLeva uns 20 segundos e não precisa de conta: ",[224,302,304],{"href":303},"\u002F#scan","escanear seu app",[37,306,308],{"id":307},"preciso-de-um-backup-antes-de-mudar-políticas-de-rls","Preciso de um backup antes de mudar políticas de RLS?",[10,310,311],{},"Para qualquer tabela em que o seu app grava, sim. Para uma tabela só de leitura\nque você está apenas apertando, o risco é o seu app ficar em branco, não os seus\ndados sumirem.",[10,313,314],{},"Vale separar duas coisas diferentes aqui, porque só uma delas tem a ver com o\nconserto.",[10,316,317,320,321,323,324,327],{},[14,318,319],{},"O que uma política permissiva já permitiu."," Se a regra na tabela era\n",[26,322,188],{}," e não ",[26,325,326],{},"FOR SELECT",", então quem a encontrasse podia mudar\ne apagar linhas além de ler, e apertá-la hoje não faz nada em relação a ontem.\nEssa versão costuma aparecer como uma mensagem no suporte sobre dados que\nmudaram sozinhos, ou como uma tabela que de repente está vazia.",[10,329,330,333],{},[14,331,332],{},"O conserto em si."," Reescrever políticas em uma dúzia de tabelas é uma mudança\nem um banco no ar, escrita pelas mesmas ferramentas que produziram o problema.\nUma migração que apaga uma política e recria torto é uma terça-feira comum, e o\ncaminho de volta é uma cópia de como as coisas estavam uma hora atrás.",[10,335,336,337,341,342,346],{},"Em um plano pago do Supabase a cópia de ontem à noite está ali no console. No\nplano gratuito não há nada para onde voltar, porque\n",[224,338,340],{"href":339},"\u002Fblog\u002Fdoes-supabase-back-up-my-database","o plano gratuito não faz backup automático nenhum",".\nSe for o seu caso, tire uma antes de encostar em uma política:\n",[224,343,345],{"href":344},"\u002Fblog\u002Fback-up-supabase-free-tier","como fazer backup de um banco Supabase no plano gratuito","\né a versão de dez minutos.",[37,348,350],{"id":349},"do-que-o-reeve-care-guarda-uma-cópia","Do que o Reeve Care guarda uma cópia",[10,352,353],{},"Do seu banco Supabase, copiado em uma programação, guardado fora da sua conta do\nSupabase, criptografado e lido de volta antes de a data no seu dashboard mudar.\nOs arquivos que os seus usuários subiram viajam junto assim que você conecta uma\nchave de Storage.",[10,355,356,357,360],{},"Dois limites, ditos de antemão. Os backups são ",[14,358,359],{},"só do Supabase",": se os seus\ndados moram em outro lugar, a gente fala, em vez de te vender uma assinatura que\nvigia uma caixa vazia. E a chave de Storage é pedida à parte, porque o Supabase\nnão emite chave só de leitura para arquivos, então a que copia os seus uploads\ntambém consegue gravar. A que copia o seu banco não consegue. Conectar é\nopcional, e o banco é salvo de qualquer jeito.",[10,362,363],{},"A restauração é a parte que importa para este artigo. Colocar uma cópia antiga\npor cima de um banco no ar é o botão mais assustador do produto, então o Care\ntira primeiro uma cópia do estado atual e só depois reproduz a que você\nescolheu. A restauração tem um desfazer próprio.",[215,365],{"alt":366,"caption":367,"src":368},"Um limite tracejado em volta de um banco de dados, com a marca do Reeve Care ao lado. O passo um é uma seta saindo do limite para uma cópia nova. O passo dois é uma seta trazendo a cópia guardada de volta para dentro.","O que acontece quando você aperta restaurar. O estado atual é copiado para fora antes de qualquer coisa ser reproduzida, então apertar o botão também dá para desfazer.","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Frestore-takes-a-copy-first-1600x520.png",[10,370,371],{},"A outra metade do Care é aquela para a qual este artigo fica apontando. Uma\npolítica que afrouxou durante uma migração não é coisa que você acha olhando,\nentão a mesma verificação externa roda de novo em uma programação e te avisa\nquando a resposta muda. Uptime, um relatório mensal e o escaneamento estão na\nmesma assinatura.",[10,373,374,375,379,380,233],{},"O que uma cópia não faz é escrever as suas políticas, e nenhum backup deixa\nfechada uma tabela aberta. Essas tabelas continuam sendo trabalho seu. O que a\ncópia muda é o que acontece quando o conserto sai torto.\n",[224,376,378],{"href":377},"\u002Fsupabase-backups","O que o Reeve salva no Supabase, com que frequência, e o que uma restauração faz","\ndesenha o ciclo inteiro, e os planos e os preços deles estão na\n",[224,381,383],{"href":382},"\u002Fpricing","página de preços",[37,385,387],{"id":386},"o-que-fazer-esta-semana","O que fazer esta semana",[389,390,391],"key-takeaways",{},[392,393,394,402,408,411,418],"ul",{},[395,396,397,398,401],"li",{},"Zere primeiro as entradas \"RLS disabled in public\". São as tabelas onde nada é consultado, e a correção é uma linha ",[26,399,400],{},"alter table"," em cada uma.",[395,403,404,405,407],{},"Depois abra Authentication → Policies e leia a condição de cada política que sobrou. Um ",[26,406,96],{}," em uma política de leitura é invisível para o advisor e escancarado para um desconhecido.",[395,409,410],{},"Decida tabela por tabela se você ficaria à vontade publicando o conteúdo dela em uma página. Essa é a pergunta que o linter não consegue responder por você, e com uma política de leitura permissiva é a única que importa.",[395,412,413,414,417],{},"Coloque ",[26,415,416],{},"alter table ... enable row level security;"," em toda migração que cria uma tabela, e rode o advisor de novo depois de cada uma. O padrão do dashboard só vale para as tabelas que você cria clicando.",[395,419,420],{},"Tire uma cópia do seu banco antes de reescrever políticas em uma tabela no ar, e veja em qual plano do Supabase você está para saber se já tem uma.",[10,422,423,424,428,429,433],{},"Comece pela tabela que mais te deixaria sem graça como página pública. O\n",[224,425,427],{"href":426},"\u002Fchecklist","checklist de segurança em 10 minutos"," cobre isso junto com o resto\ndo que vale conferir em um app recém-lançado, e o\n",[224,430,432],{"href":431},"\u002Fis-your-supabase-app-safe","guia de segurança do Supabase"," passa pelo que mais\ncostuma ficar aberto.",{"title":28,"searchDepth":435,"depth":435,"links":436},3,[437,439,440,441,442,443,444,445],{"id":39,"depth":438,"text":40},2,{"id":63,"depth":438,"text":64},{"id":85,"depth":438,"text":86},{"id":236,"depth":438,"text":237},{"id":272,"depth":438,"text":273},{"id":307,"depth":438,"text":308},{"id":349,"depth":438,"text":350},{"id":386,"depth":438,"text":387},"Noções de segurança","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcover-1200x630.png","Um painel de dashboard listando várias tabelas, com um sinal de aviso ao lado de uma delas e nada ao lado das outras.","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.",false,"md",[453,456,459,462,465],{"q":454,"a":455},"\"RLS disabled in public\" é um erro ou um aviso?","Um erro, e é o nível mais alto que o advisor usa. A entrada diz \"Table public.\u003Cname> is public, but RLS has not been enabled.\" As duas entradas vizinhas são mais discretas: uma tabela com a chave ligada e nenhuma política é reportada como INFO, e uma política cuja condição é sempre verdadeira é reportada como WARN. Esses níveis dizem o quanto o linter confia no que consegue enxergar na sua configuração, não o tamanho do seu problema.",{"q":457,"a":458},"Ativar o Row Level Security vai quebrar o meu app?","Na hora, sim, e é a configuração fazendo o trabalho dela. O Supabase documenta que os dados ficam inacessíveis pela API com uma chave publicável enquanto não houver políticas definidas, então no momento em que você roda a linha suas listas voltam vazias e suas telas ficam em branco. O app volta quando você adiciona uma política dizendo quem pode ver quais linhas. O erro a evitar é adicionar uma que libera todo mundo, porque essa versão também faz o app funcionar.",{"q":460,"a":461},"Ativei o RLS e agora nada carrega. O que aconteceu?","Nada quebrou. Com o Row Level Security ligado e nenhuma política escrita, o Postgres (o motor de banco de dados por baixo do Supabase) recusa todas as requisições, inclusive as do seu próprio app, e o advisor troca o erro dele por uma entrada INFO dizendo que a tabela está com RLS ativo mas sem políticas. Escreva uma política para as linhas que o seu app deve mostrar, começando pela que compara o visitante logado com a coluna de dono da linha.",{"q":463,"a":464},"Minha tabela não foi apontada e mesmo assim qualquer um consegue ler. Por quê?","O mais provável é que o Row Level Security esteja ligado e exista uma política de leitura cuja condição é USING (true). O advisor tem sim uma regra para políticas sempre verdadeiras, e ela pula as de leitura de propósito, porque acesso público de leitura é uma coisa razoável para um catálogo de produtos ou uma lista de artigos publicados. Nada no seu dashboard sabe se a sua tabela guarda locais ou clientes, então essa conferência é sua.",{"q":466,"a":467},"Preciso de Row Level Security se o meu app só conversa com o meu servidor?","Se o navegador realmente nunca conversa com o Supabase e nenhuma chave publicável está no código que o seu site manda para os visitantes, então a Data API não é uma porta de entrada e não são as políticas que protegem essas tabelas. Isso é raro em um app feito com Lovable, Bolt ou v0, porque esses construtores ligam o navegador direto no Supabase por padrão. Abra o seu próprio site, veja se a URL do projeto e a chave publicável estão na página, e deixe essa resposta decidir.","\u002Fblog\u002Fsupabase-rls-disabled-in-public\u002Fcard-800x500.png",[470,471,472,473,474,475,476,477],"rls disabled in public","aviso supabase rls desativado","supabase security advisor","supabase database linter","supabase lint 0013","table is public but rls has not been enabled","ativar rls supabase","rls policy always true",{},true,"Supabase: o que \"RLS disabled in public\" não vê","\u002Fblog\u002Fsupabase-rls-disabled-in-public","2026-09-09",{"title":5,"description":449},"blog\u002Fsupabase-rls-disabled-in-public",[486,487,488],"\"RLS disabled in public\" quer dizer uma coisa só: uma tabela do seu schema public está com o Row Level Security desligado, então qualquer pessoa com o endereço do seu projeto e a sua chave publicável consegue ler.","Ele não diz nada sobre uma tabela onde você ligou a chave e depois escreveu uma política que deixa todo mundo ler. Existe uma regra para políticas sempre verdadeiras, e ela pula as políticas de leitura de propósito.","Resolva as tabelas apontadas e depois confira o resto por fora, porque o advisor lê as suas configurações e nunca pergunta ao seu banco o que um desconhecido recebe de verdade.","f_Rmu_tbxxG-2onvBXP6R2SydaUMb3jnHfKACrWoV6E",[491,498,504,510,516,522,528,534,540,546,552,558,564,570,576,577,583,589,595,601,607,613,619,625,631,636,642,648,653,659,665,671,677,683,689,694,699,705,710,715,720,726],{"path":492,"title":493,"description":494,"published":495,"category":496,"image":497,"draft":450},"\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","Backups","\u002Fblog\u002Fsupabase-backup-auth-users\u002Fcard-800x500.png",{"path":499,"title":500,"description":501,"published":502,"category":446,"image":503,"draft":450},"\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":505,"title":506,"description":507,"published":508,"category":446,"image":509,"draft":450},"\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":511,"title":512,"description":513,"published":514,"category":446,"image":515,"draft":450},"\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":517,"title":518,"description":519,"published":520,"category":446,"image":521,"draft":450},"\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":523,"title":524,"description":525,"published":526,"category":446,"image":527,"draft":450},"\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":529,"title":530,"description":531,"published":532,"category":446,"image":533,"draft":450},"\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":535,"title":536,"description":537,"published":538,"category":446,"image":539,"draft":450},"\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":541,"title":542,"description":543,"published":544,"category":446,"image":545,"draft":450},"\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":547,"title":548,"description":549,"published":550,"category":496,"image":551,"draft":450},"\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":553,"title":554,"description":555,"published":556,"category":496,"image":557,"draft":450},"\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":559,"title":560,"description":561,"published":562,"category":496,"image":563,"draft":450},"\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":565,"title":566,"description":567,"published":568,"category":446,"image":569,"draft":450},"\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":571,"title":572,"description":573,"published":574,"category":446,"image":575,"draft":450},"\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":481,"title":5,"description":449,"published":482,"category":446,"image":468,"draft":450},{"path":578,"title":579,"description":580,"published":581,"category":446,"image":582,"draft":450},"\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":584,"title":585,"description":586,"published":587,"category":446,"image":588,"draft":450},"\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":590,"title":591,"description":592,"published":593,"category":446,"image":594,"draft":450},"\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":596,"title":597,"description":598,"published":599,"category":446,"image":600,"draft":450},"\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":602,"title":603,"description":604,"published":605,"category":446,"image":606,"draft":450},"\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":608,"title":609,"description":610,"published":611,"category":446,"image":612,"draft":450},"\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":614,"title":615,"description":616,"published":617,"category":446,"image":618,"draft":450},"\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":620,"title":621,"description":622,"published":623,"category":496,"image":624,"draft":450},"\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":626,"title":627,"description":628,"published":629,"category":446,"image":630,"draft":450},"\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":344,"title":632,"description":633,"published":634,"category":496,"image":635,"draft":450},"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":637,"title":638,"description":639,"published":640,"category":446,"image":641,"draft":450},"\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":643,"title":644,"description":645,"published":646,"category":446,"image":647,"draft":450},"\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":231,"title":649,"description":650,"published":651,"category":446,"image":652,"draft":450},"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":654,"title":655,"description":656,"published":657,"category":446,"image":658,"draft":450},"\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":660,"title":661,"description":662,"published":663,"category":496,"image":664,"draft":450},"\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":666,"title":667,"description":668,"published":669,"category":496,"image":670,"draft":450},"\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":672,"title":673,"description":674,"published":675,"category":446,"image":676,"draft":450},"\u002Fblog\u002Fsupabase-storage-bucket-public","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":678,"title":679,"description":680,"published":681,"category":446,"image":682,"draft":450},"\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":684,"title":685,"description":686,"published":687,"category":496,"image":688,"draft":450},"\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":295,"title":690,"description":691,"published":692,"category":446,"image":693,"draft":450},"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":695,"title":696,"description":697,"published":692,"category":446,"image":698,"draft":450},"\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":700,"title":701,"description":702,"published":703,"category":446,"image":704,"draft":450},"\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":339,"title":706,"description":707,"published":708,"category":496,"image":709,"draft":450},"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":226,"title":711,"description":712,"published":713,"category":446,"image":714,"draft":450},"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":716,"title":717,"description":718,"published":713,"category":496,"image":719,"draft":450},"\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":721,"title":722,"description":723,"published":724,"category":496,"image":725,"draft":450},"\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":727,"title":728,"description":729,"published":724,"category":446,"image":730,"draft":450},"\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",1790150954672]