Pular para o conteúdo

Noções de segurança

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á?

Vlad Tkachenko8 min de leitura
Um painel do dashboard: anon e service_role esmaecidos acima, sb_publishable_ e sb_secret_ nítidos abaixo.

Em resumo

  • O Supabase agora emite chaves sb_publishable_ e sb_secret_. Elas substituem anon e service_role e fazem exatamente os mesmos dois trabalhos.
  • A chave publicável pertence ao seu app. A secreta nunca, e agora dá para diferenciar lendo os primeiros caracteres.
  • Suas chaves antigas ainda funcionam hoje. O Supabase disse que todos os projetos vão ter que sair delas no fim de 2026.

Se você abriu o painel do Supabase há pouco e encontrou chaves começando com sb_publishable_ e sb_secret_ onde antes ficavam anon e service_role, não quebrou nada. O Supabase renomeou suas chaves de API, e o par que você conhecia está de saída.

A mudança é pequena no que faz e grande no que evita. As duas chaves continuam cumprindo exatamente os dois papéis de sempre. O que é novo é que agora você vê qual é qual sem abrir nada.

O que o Supabase mudou de fato

O Supabase anunciou as chaves novas em julho de 2025, junto com uma mudança em como ele assina os tokens de login. Duas coisas substituíram duas coisas:

  • A chave publicável, sb_publishable_…, substitui a chave anon.
  • Chaves secretas, sb_secret_…, substituem a chave service_role.

As permissões continuam iguais. Uma chave publicável ainda só identifica o seu projeto e não carrega permissão própria; uma secreta ainda ignora todas as regras que você escreveu. Se você já sabe quais chaves são seguras num frontend, nada dessa intuição ficou errado.

Duas diferenças práticas valem a pena. Você pode ter várias chaves secretas ao mesmo tempo e revogar uma de cada vez, então girar uma chave não significa mais um momento em que tudo o que a usava fica quebrado. E as chaves antigas tinham uma característica que quase ninguém notou: eram JWTs que expiram dez anos depois de você criar o projeto. As novas não carregam validade por dentro.

Os mesmos dois trabalhos, dois formatos diferentes. No par antigo o papel fica enterrado no meio; no novo é a primeira coisa que você lê.

A chave anon é a mesma coisa que a chave publicável?

Sim no que ela faz, não no que ela é.

sb_publishable_… faz exatamente o trabalho da chave anon: nomeia o seu projeto para que um pedido saiba para onde ir, não carrega permissões próprias, e é feita para ficar no seu app onde qualquer um pode ler. Tudo o que você já entendia da chave anon continua verdadeiro. Se você trocar uma pela outra, nenhuma tabela fica mais ou menos legível, porque nenhuma das duas nunca protegeu as suas linhas. Quem faz isso é a Row Level Security.

O que muda é o valor em si. São strings diferentes em formatos diferentes, emitidas separadamente, e um projeto pode ter os dois pares ao mesmo tempo durante a migração. Então «a mesma chave com um nome novo» é a imagem errada. É uma chave nova fazendo um trabalho antigo, e o seu app precisa ser avisado.

Uma consequência pega muita gente: ativar as chaves novas não troca o seu app. O Supabase emite as chaves e deixa o seu app rodando com o que você deu a ele. A troca é uma mudança de uma linha que você mesmo faz, no ponto em que o seu app cria o cliente Supabase.

Qual das duas pertence ao seu app

A publicável, e só ela.

Seu app roda no navegador do seu visitante, e o pedido ao seu banco sai dali. Ele precisa dizer a qual projeto pertence, e esse identificador chega a todo visitante por projeto. sb_publishable_… é a chave feita para isso: encontrá-la no seu app não é um achado, e nunca foi.

sb_secret_… é o oposto. Ela lê e escreve em toda linha de toda tabela, de qualquer lugar, ignorando por completo as suas políticas, e é exatamente para isso que ela existe. O lugar dela é um servidor, uma edge function, um worker: nenhum lugar que um navegador alcance. Se alguma já foi colada em código de frontend, troque a chave no painel antes de mexer em qualquer outra coisa, porque apagar a linha não fecha a porta.

Como é uma chave sb_publishable_?

Uma única string contínua que começa com o literal sb_publishable_, seguido de um meio aleatório. Nenhum ponto dentro dela, e nada ali que dê para decodificar. A contraparte secreta se lê igual, com sb_secret_ na frente.

O par antigo não se parece nada com isso. anon e service_role são JWTs: três blocos separados por pontos, com algumas centenas de caracteres, começando com eyJ. O bloco do meio não é criptografado, só codificado, então qualquer um cola num decodificador e lê o campo role lá dentro. Era assim que se distinguia os dois antes, e é por isso que tanta gente nunca distinguiu.

Ler os primeiros quinze caracteres é a verificação inteira agora. A chave perigosa se anuncia na parte da string onde o seu olho cai primeiro, em vez de no meio de uma coisa que você precisa abrir.

Como saber qual delas você tem

Leia os primeiros caracteres. Hoje essa é toda a conferência.

O que você vêO que éSegura no navegador?
sb_publishable_…chave publicável atualÉ o lugar dela
sb_secret_…chave secreta atualNunca
eyJ… com anonchave publicável antigaÉ o lugar dela
eyJ… com service_rolechave secreta antigaNunca

Uma chave atual é uma sequência longa em duas metades: um miolo aleatório e uma soma de verificação curta no fim. Uma chave antiga são três blocos separados por pontos, e o do meio é texto legível em vez de criptografia, e por isso diferenciar o par antigo passava por decodificá-lo e ler o campo role.

Se você achou uma chave no seu app e não sabe qual é, nosso scan gratuito lê o seu site no ar por fora e diz o que consegue ver. Leva uns 20 segundos e não precisa de conta: escaneie seu app.

Minhas chaves anon e service_role antigas ainda funcionam?

Hoje, sim. O Supabase publicou um cronograma, não um botão de desligar:

QuandoO que acontece
1 de novembro de 2025Projetos restaurados depois dessa data não ganham mais anon nem service_role.
Fim de 2026, sem data exataTodos os projetos vão precisar usar as chaves novas.

Ou seja: não há emergência esta semana, e há um prazo este ano. Se o seu app foi feito antes da renomeação e não foi tocado desde então, ele está rodando com chaves antigas agora e vai continuar por um tempo.

O argumento para mudar cedo não é o prazo. É o dia em que alguém cola a chave errada num prompt: sb_secret_ se entrega, eyJ… não.

O que são as chaves de API legadas do Supabase?

Legadas é como o Supabase chama hoje o par original, anon e service_role, junto com o segredo JWT que assina as duas. Todo projeto criado antes de meados de 2025 começou com elas, o que é a maioria dos apps feitos com vibe coding.

Elas diferem do par novo em pontos que vale conhecer. Sendo JWTs, carregam uma expiração dez anos depois da criação do projeto, dentro da própria chave, onde ninguém olha. Não dá para trocá-las de jeito nenhum: o Supabase disse que trocar os segredos legados anon, service_role e JWT não é mais possível, então invalidar uma que vazou significa migrar para as chaves novas e desativar o par antigo. E um projeto restaurado depois de 1 de novembro de 2025 nem recebe elas.

Se uma das suas já vazou, essa migração é a única forma de invalidar a chave, e a ordem para fazer isso depende de a chave já estar num bundle que os seus visitantes baixam.

Como trocar sem quebrar o seu app

O guia de migração do próprio Supabase é a referência. A versão curta, para um app que você não escreveu na mão, partindo do princípio de que você já sabe achar a página onde ficam as suas chaves:

  1. No painel, abra Settings → API Keys e crie as chaves novas. Isso adiciona as novas; não tira as antigas, e os dois pares funcionam ao mesmo tempo.
  2. Ache onde o seu app cria o cliente do Supabase e troque a chave publicável. Num builder como Lovable ou Bolt isso costuma ser um valor nas configurações do projeto, não uma linha de código.
  3. Troque a chave secreta em todo lugar onde ela é usada num servidor: edge functions, webhooks, tarefas agendadas, qualquer coisa que não seja o navegador.
  4. Abra o seu app e passe pelas partes que leem e escrevem dados. Uma chave publicável errada falha na hora e alto, que é o caso bom.
  5. Só quando tudo estiver funcionando, desative as chaves antigas.

O passo 5 é o que fica por último, e vale fazer de propósito em vez de nunca: projetos meio migrados, em que o app ainda carrega uma chave anon velha ao lado de uma sb_publishable_ viva, são comuns e confusos de depurar.

O que fazer esta semana

O que fazer

  • Abra Settings → API Keys e veja quais pares o seu projeto tem. Leva um minuto e já diz onde você está.
  • Se achar sb_secret_… ou service_role em qualquer lugar do código do frontend, troque a chave hoje. É o único item urgente desta lista.
  • Crie as chaves novas e passe o seu app para elas quando tiver meia hora, não por causa do prazo, e sim porque o prefixo deixa o próximo erro óbvio.
  • Aproveite e olhe o Row Level Security. A chave nova não muda nada do que as suas políticas permitem, e ligar o RLS não é a mesma coisa que estar protegido.

Se quiser a versão específica da plataforma sobre o que conferir, temos um guia em linguagem simples para apps com Supabase, e o checklist de segurança de 10 minutos cobre isso junto com as outras coisas que vale desligar num app recém-lançado.

Perguntas frequentes

sb_publishable_ é a mesma coisa que a chave anon?

Ela faz o mesmo trabalho. Diz qual é o seu projeto para o pedido saber para onde ir, não carrega permissão nenhuma própria e foi feita para ficar no seu app, onde qualquer pessoa pode ler. O que protege seus dados nos dois casos é o Row Level Security, não a chave.

Minhas chaves anon e service_role ainda funcionam?

Sim, hoje. O Supabase manteve as duas no ar durante a migração e você pode ter os dois pares ao mesmo tempo. O que foi anunciado é que no fim de 2026 todos os projetos vão precisar usar as chaves novas, sem uma data exata ainda.

Tenho os dois pares no painel. Qual o meu app deve usar?

A publicável, sb_publishable_. A troca é de uma linha: substitua a chave que o seu app passa quando cria o cliente do Supabase. Nada muda nas suas tabelas nem nas suas políticas, porque a chave nova tem exatamente as permissões que a anon tinha.

O formato novo deixa meu app mais seguro sozinho?

Não. Ele torna a chave perigosa fácil de reconhecer, e isso vale dinheiro em erros que deixam de acontecer, mas uma chave publicável continua lendo tudo o que as suas políticas deixarem. Se o Row Level Security estiver desligado, a chave nova abre o seu banco exatamente tanto quanto a antiga abria.

O que é uma chave publicável do Supabase?

É a chave que o seu app deve entregar: sb_publishable_ seguido de uma string aleatória, emitida pelo Supabase para identificar o seu projeto em cada pedido. Ela não carrega privilégios próprios, então o que consegue ler é exatamente o que as suas políticas de Row Level Security permitem e nada além. Ela substituiu a chave anon, faz o mesmo trabalho, e pode ficar em código que qualquer um lê.

O que são as chaves de API legadas do Supabase?

Legadas é como o Supabase chama hoje o par original, anon e service_role, junto com o segredo JWT que assina as duas. São JWTs em vez de strings opacas, carregam uma expiração dez anos depois da criação do projeto, e projetos restaurados depois de 1 de novembro de 2025 não recebem mais elas. Projetos existentes seguem com elas funcionando até a virada do fim de 2026.

Escrito por

Vlad Tkachenko

Fundador da Reeve

Passo meus dias olhando apps criados com Lovable, Bolt, v0, Cursor e Replit, e a curta lista de erros que aparecem neles sem parar.

Mais sobre o autor

Leia depois

Todos os artigos

Não sabe como está o seu próprio app?

Faça um scan gratuito e receba uma nota clara de A a F em cerca de 20 segundos. Sem conta e sem cartão.

Verificar meu app grátis

Verificação externa automatizada, não uma auditoria completa. A ausência de achados não é garantia de segurança.