Ver a chave sb_publishable no seu app React Native publicado não é um vazamento: essa chave foi feita para ser pública, exatamente como a antiga chave anon. Ela tem privilégios baixos e é segura no cliente desde que o Row Level Security esteja ativo. O perigo real não é a sb_publishable aparecer no app, mas sim faltar RLS, o que deixa qualquer pessoa consultar suas tabelas com essa chave pública. A chave que nunca pode vazar é a sb_secret, que ignora o RLS e dá acesso total ao banco.
Resposta rápida
A sb_publishable é pública por design; a sb_secret nunca é. Segundo a documentação das novas chaves da Supabase, a chave sb_publishable tem os mesmos privilégios baixos da antiga anon e é segura no cliente quando o Row Level Security está ativo. Já a sb_secret usa a função service_role com BYPASSRLS, ignora todas as políticas e só deve ficar no servidor. Portanto, a sb_publishable no seu app React Native é esperada, não um vazamento. Verifique se o RLS está ativo em todas as tabelas, e trate qualquer exposição da sb_secret como uma emergência, rotacionando a chave.
sb_publishable vs sb_secret: qual importa
A primeira coisa é saber qual chave você está vendo, porque a resposta muda por completo. A Supabase agora oferece duas chaves: a sb_publishable, de privilégios baixos e feita para ir no cliente, e a sb_secret, uma chave de acesso total que só deve ficar no servidor. Há também o segredo JWT no modelo legado. A tabela abaixo separa as três.
| Chave | Segura no cliente? | Se for exposta |
|---|---|---|
| sb_publishable (antiga anon) | Sim, por design | Segura só se o RLS estiver ativo |
| sb_secret (antiga service_role) | Não, nunca | Acesso total, ignora o RLS, rotacione já |
| Segredo JWT (legado) | Não, nunca | Permite forjar tokens |
Se é a sb_publishable, não se preocupe com a chave em si; a pergunta passa a ser se o RLS protege seus dados. Se é a sb_secret ou o segredo JWT, é uma emergência, porque dão um controle que nenhuma política de RLS consegue conter.
Por que a sb_publishable no app não é um vazamento
A sb_publishable é publicável, e o nome já diz tudo: ela foi feita para ser publicada, ou seja, para viajar no bundle do seu app React Native e ser vista. Assim como a antiga chave anon, ela tem privilégios baixos e serve só para o cliente conversar com a Supabase. Encontrá-la no seu app publicado é o comportamento esperado, não uma falha.
O que a torna segura é o Row Level Security. Com o RLS ativo e políticas corretas, essa chave pública só acessa os dados que você permite, então o fato de ela ser visível não é um problema. Confundir "a chave está no app" com "a chave vazou" leva a um pânico desnecessário: a sb_publishable no cliente é por design.
O perigo real: a falta de RLS
O risco real não é a chave, e sim o que está por trás dela. A Supabase cria as tabelas com o RLS desativado por padrão, então, se o seu projeto nunca ativou o RLS, a chave sb_publishable pública permite que qualquer pessoa consulte e baixe suas tabelas inteiras, sem fazer login. A chave não vazou; ela é pública, mas nada protege os dados.
Foi exatamente isso o que aconteceu no CVE-2025-48757, em que um pesquisador encontrou 170 projetos Lovable cujas tabelas eram legíveis por requisições não autenticadas usando só a chave pública, por falta de RLS. A lição não é esconder a chave publicável, o que é impossível, e sim ativar o RLS em todas as tabelas com políticas que limitem cada usuário aos seus próprios dados.
A chave que nunca pode vazar: sb_secret
A chave que você precisa proteger é a sb_secret, ou a antiga service_role. Ela usa a função service_role do Postgres com o atributo BYPASSRLS, ou seja, ignora todas as suas políticas de RLS e tem acesso total de leitura e escrita ao banco. Por isso, nunca deve aparecer no cliente, no repositório ou no bundle do app.
Se essa chave for exposta, é uma brecha completa, porque quem a tiver acessa tudo, ignorando o RLS. Ela deve viver apenas em componentes controlados por você no servidor, como uma Edge Function ou seu próprio backend, onde você mesmo faz a autorização antes de usá-la. Uma sb_secret no app React Native é um erro de arquitetura, não só uma chave a rotacionar.
As novas chaves substituem anon e service_role
A Supabase está migrando o modelo de chaves. As chaves legadas anon e service_role serão descontinuadas até o fim de 2026, e você deve passar a usar a sb_publishable no lugar da anon e a sb_secret no lugar da service_role. Os dois modelos funcionam ao mesmo tempo durante a migração, então você pode trocar os clientes um a um e desativar as chaves legadas só quando nada mais depender delas.
Uma vantagem prática das novas chaves é a rotação mais simples: você pode revogar uma chave secreta específica e emitir outra, sem invalidar tudo de uma vez como acontecia ao girar o segredo JWT legado. A Supabase também revoga automaticamente as chaves secretas que detecta em repositórios públicos do GitHub, o que ajuda, mas não substitui manter a sb_secret longe do cliente.
O que fazer se a sb_secret vazou
Se a sb_secret, e não a publicável, foi exposta, aja em ordem. A prioridade é revogar e gerar uma nova chave, porque é a única ação que invalida a cópia que um atacante já pode ter. A tabela abaixo dá uma resposta clara.
| Passo | Ação | Prioridade |
|---|---|---|
| 1 | Revogue e gere uma nova sb_secret | Imediata |
| 2 | Ative o RLS em todas as tabelas | Alta |
| 3 | Mova a sb_secret para o backend | Alta |
| 4 | Remova a chave do código e do histórico Git | Alta |
| 5 | Consulte suas tabelas com a sb_publishable | Verifica o RLS |
| 6 | Revise os logs do banco de dados | Detecta abuso |
Rotacione primeiro, corrija depois. Remova a chave do código e, principalmente, do histórico do Git, já que apagá-la em um commit posterior não a remove dos anteriores. Trate qualquer sb_secret exposta como comprometida, mesmo que você rotacione rápido, e revise os logs do banco em busca de acessos anormais.
Como verificar seu app React Native
A verificação mais importante é simples: consulte suas tabelas com a chave sb_publishable pública, sem sessão iniciada, e confirme que ela não retorna dados que não deveria. É exatamente o teste que um atacante ou um bot faz, então passar por ele é a prova direta de que o RLS está protegendo seus dados.
Além disso, confirme que a sb_secret não está em lugar nenhum do cliente. Procure por chaves no bundle JavaScript, nos arquivos de configuração e no repositório. Em um app React Native, lembre que as variáveis de ambiente são embutidas em texto claro no bundle na hora do build, então um arquivo .env não esconde uma chave secreta no app publicado.
Onde os bots entram
Isso não é um ataque manual. Bots automáticos rastreiam repositórios públicos, bundles e binários em busca de URLs e chaves da Supabase. Ao encontrar uma sb_secret, testam contra a API e ganham acesso total em segundos. Ao encontrar uma sb_publishable, consultam suas tabelas para ver se o RLS está ativo.
A velocidade é o problema. Como a varredura é contínua, uma chave secreta enviada a um repositório público pode ser detectada e testada em minutos. Por isso, a sb_secret precisa ficar no servidor, e o RLS precisa estar ativo para que a sb_publishable pública, encontrada por um bot, não sirva de nada.
Antes de publicar, escaneie o build
Como as ferramentas de IA e os fluxos rápidos facilitam esses descuidos, revisar o build antes de publicar detecta uma sb_secret embutida enquanto ainda é barato corrigir. Uma chave secreta no frontend é justamente o padrão que os atacantes automáticos procuram.
Um scanner como o PTKD.com analisa seu .apk ou .ipa e devolve resultados ordenados por gravidade e mapeados ao OWASP MASVS, incluindo segredos embutidos e configurações de rede inseguras, para que uma chave exposta não chegue aos usuários. Sendo claro sobre o limite: um scanner de build verifica o app que você publica, não o painel da Supabase, então não substitui ativar o RLS nem rotacionar uma chave. Ele detecta a exposição no cliente; o backend você protege com o RLS.
O que lembrar
- A sb_publishable é pública por design; encontrá-la no app React Native não é um vazamento.
- O perigo real é a falta de RLS, que deixa a chave pública baixar suas tabelas, como no CVE-2025-48757.
- A sb_secret nunca pode vazar: ela ignora o RLS e dá acesso total, e só deve ficar no servidor.
- As novas chaves sb_publishable e sb_secret substituem anon e service_role até o fim de 2026.
- Antes de publicar, escaneie o build com o PTKD.com para que uma sb_secret não chegue aos usuários.




