Como Adicionar Controle de Acesso Baseado em Funções (RBAC) ao Seu App
Para adicionar controle de acesso baseado em funções, dê a cada usuário uma ou mais funções (por exemplo, administrador, editor, leitor), defina quais ações cada função pode executar e verifique essas permissões no servidor em cada requisição — não apenas escondendo botões. Confira também se o registro acessado pertence à conta ou à equipe do usuário. Comece com algumas funções fixas no seu banco de dados e teste tentando acessar diretamente os dados de outro usuário.
Autenticação vs. autorização
Duas palavras que se confundem:
- Autenticação é quem é você? — fazer login. Veja como adicionar login ao seu app.
- Autorização é o que você tem permissão para fazer? — quais páginas, registros e ações um usuário logado pode acessar.
O RBAC é a forma mais comum de fazer autorização. Isso importa: em setembro de 2026, Broken Access Control está em primeiro lugar no OWASP Top 10:2025, a lista amplamente usada dos riscos de segurança mais graves em aplicações web. As falhas típicas são usuários lendo registros de outros alterando um ID na URL, ou usuários comuns chamando rotas de API exclusivas de administradores.
Escolha um modelo
| Modelo | Como funciona | Ideal para | Trade-off |
|---|---|---|---|
| Uma coluna de função | users.role = admin / member | Apps pequenos com duas ou três funções | Fica confuso quando as pessoas precisam de funções diferentes em lugares diferentes |
| Funções + permissões | As funções mapeiam para permissões nomeadas (invoices.approve); o código verifica permissões | Apps cujas regras vão crescer | Mais tabelas; uma lista de permissões para manter |
| Funções por equipe (multi-tenant) | Uma tabela de associações: usuário + organização + função | SaaS em que as pessoas pertencem a equipes ou espaços de trabalho | Cada consulta precisa ser limitada à organização |
| Baseado em atributos ou relacionamentos | Regras sobre atributos do registro ("o autor pode editar o próprio post") ou sobre relacionamentos (compartilhado com) | Documentos, compartilhamento, fluxos complexos | Mais difícil de raciocinar; considere uma biblioteca ou serviço dedicado |
| Funções do provedor de autenticação | Seu provedor de login guarda funções ou associações a organizações | Apps que já usam um provedor de autenticação hospedado | Preso a esse provedor; ainda assim, aplique no seu servidor |
Na prática, a maioria dos apps combina duas coisas: funções para o tipo de ação que alguém pode executar e propriedade para os registros sobre os quais ela pode agir. "Editores podem editar posts" é uma regra de função; "…posts no próprio espaço de trabalho" é uma regra de propriedade. Você precisa das duas.
Comece mais simples do que imagina. Administrador, membro e leitor cobrem um número surpreendente de apps. É mais fácil dividir uma função depois do que desembaraçar dez funções que ninguém entende.
Defina as funções antes de escrever código
Escreva primeiro uma tabela de permissões em linguagem simples. Ela serve como especificação para a IA e como plano de testes:
| Ação | Dono | Administrador | Membro | Leitor |
|---|---|---|---|---|
| Ver projetos da equipe | ✓ | ✓ | ✓ | ✓ |
| Criar e editar projetos | ✓ | ✓ | ✓ | |
| Excluir projetos | ✓ | ✓ | ||
| Convidar e remover pessoas | ✓ | ✓ | ||
| Alterar funções | ✓ | |||
| Cobrança | ✓ |
Decida também os casos extremos: o último dono pode sair? Um administrador pode remover o dono? O que um usuário removido vê?
Passo a passo
1. Tenha um login funcionando primeiro
O RBAC fica sobre a autenticação. O servidor precisa saber com confiabilidade quem está fazendo cada requisição, a partir de uma sessão ou de um token verificado — nunca a partir de um ID de usuário que o navegador envia no corpo da requisição.
2. Guarde as funções no banco de dados
Para um app de uma única equipe, uma coluna role na tabela de usuários basta. Para equipes, use uma tabela de associações:
create table memberships (
user_id uuid references users(id),
organization_id uuid references organizations(id),
role text not null check (role in ('owner','admin','member','viewer')),
primary key (user_id, organization_id)
);
Nunca deixe o usuário definir a própria função por uma atualização normal do perfil. Alterações de função passam por um endpoint dedicado, com verificação de permissão.
3. Verifique as permissões no servidor, em um único lugar
Escreva uma função auxiliar — algo como can(user, 'projects.delete', project) — e chame-a em cada rota de API, ação do servidor e tarefa em segundo plano que lê ou altera dados. Uma função central é mais fácil de revisar e testar do que verificações espalhadas pelo código. Negue por padrão: se nenhuma regra permite uma ação, ela é recusada.
4. Limite todas as consultas
Toda consulta a dados da equipe deve incluir a equipe: where organization_id = :currentOrg, e não apenas where id = :id. É isso que impede alguém de trocar /projects/123 por /projects/124 e ver o projeto de outra empresa. Para registros de outras equipes, responda "não encontrado" em vez de "proibido", para não revelar que eles existem.
5. Adicione proteção no próprio banco onde ela importa
A row-level security (RLS) do Postgres permite que o banco imponha quais linhas cada usuário pode ver. Ela é essencial se o navegador conversa diretamente com o banco (como em alguns backends hospedados), e é uma segunda camada útil para tabelas sensíveis nos demais casos.
6. Reflita as funções na interface
Agora esconda ou desabilite o que os usuários não podem fazer, para que o app não fique confuso. Isso serve só para usabilidade; quem protege são as verificações no servidor.
7. Registre ações sensíveis
Registre quem alterou funções, excluiu dados ou exportou registros, e quando. Um log de auditoria ajuda em dúvidas de suporte e incidentes.
8. Teste como um atacante
Entre como cada função e tente todas as ações da tabela de permissões. Depois, tente o que não deveria funcionar: chamar rotas de API de administrador como leitor, trocar IDs em URLs e requisições, remover a si mesmo como último dono. Vale escrever testes automatizados para a tabela de permissões quando as regras estiverem estáveis.
Prompts que funcionam
Adicione controle de acesso baseado em funções. Funções por organização: dono, administrador, membro, leitor, guardadas em uma tabela de associações. As permissões estão nesta tabela: [cole sua tabela]. Crie uma função auxiliar no servidor can(user, action, resource), com negação por padrão, e use-a em todas as rotas de API. Limite todas as consultas por organization_id. Esconda na interface as ações que o usuário não pode executar, mas nunca dependa disso para segurança.
Revise cada rota de API e função do servidor deste app. Para cada uma, liste quais dados ela lê ou altera, se verifica que o usuário está logado, se verifica a função dele e se limita a consulta à organização dele. Corrija as que estiverem sem alguma verificação e me mostre a lista.
Adicione uma página /admin, exclusiva para administradores, na qual o dono possa alterar as funções dos membros. Impeça remover ou rebaixar o último dono, registre cada alteração de função com quem a fez e quando, e garanta que o endpoint de alteração de função rejeite quem não for dono.
Erros comuns
- Verificar funções só no frontend. A API continua aberta para qualquer um que a chame.
- Confiar em IDs vindos do cliente — um
userIdouroleno corpo da requisição em vez da sessão. - Consultas sem limite que buscam pelo ID do registro apenas.
- Funções verificadas nas páginas, mas não nas rotas de API, exportações, downloads de arquivos ou webhooks.
- Administrador definido por endereço de e-mail fixo no código (
if email === 'eu@...'), fácil de esquecer e difícil de mudar. - Funções demais, cedo demais, que ninguém consegue explicar seis meses depois.
- Sessões desatualizadas: um usuário rebaixado mantém direitos de administrador até sair. Verifique as funções no banco de dados, ou atualize-as, em ações sensíveis.
Checklist de RBAC
- Tabela de permissões escrita em linguagem simples, com os casos extremos decididos
- O servidor identifica o usuário pela sessão, nunca pelos dados da requisição
- Funções guardadas no banco de dados; usuários não conseguem alterar as próprias
- Uma verificação central de permissões, com negação por padrão, usada em todas as rotas
- Toda consulta limitada à organização ou à propriedade do usuário
- Row-level security onde o navegador consegue acessar o banco
- A interface esconde o que o usuário não pode fazer (só para usabilidade)
- Ações sensíveis registradas
- Cada função testada, incluindo chamadas diretas à API e IDs alterados
O controle de acesso é um item de uma lista maior; a lista de segurança para apps feitos com IA cobre o resto. Se você está criando uma ferramenta para a sua equipe interna, como criar uma ferramenta interna mostra onde as funções se encaixam.
RBAC no Mythex
O Mythex não oferece um sistema de login ou de funções integrado para os usuários do seu app. Você escolhe uma biblioteca ou provedor de autenticação e descreve as funções, e o agente conecta tudo ao seu código e ao banco Postgres do projeto (adicionar login ao seu app). As funções de workspace do próprio Mythex, como Dono e Membro, controlam quem pode editar seus projetos no Mythex, não quem pode usar o app que você publica. Use o modo de planejamento para combinar a tabela de permissões antes de construir, depois use o prompt de revisão acima e teste cada função no Preview antes de publicar. Os prompts de segurança da documentação são um bom passo seguinte.
Perguntas
O que é controle de acesso baseado em funções?
O controle de acesso baseado em funções (RBAC) define o que cada usuário pode fazer com base nas funções que ele tem, como administrador, editor ou leitor. As permissões ficam ligadas às funções, não às pessoas individualmente, então mudar o que alguém pode fazer é uma questão de mudar a função dessa pessoa.
Qual é a diferença entre autenticação e autorização?
A autenticação verifica quem a pessoa é, geralmente com o login. A autorização decide o que essa pessoa logada pode ver e fazer. O RBAC é uma das formas de fazer autorização.
Esconder botões na interface é suficiente para restringir o acesso?
Não. Qualquer pessoa pode chamar sua API diretamente, então esconder um botão só muda o que as pessoas veem. Toda requisição que lê ou altera dados precisa ser verificada no servidor, de acordo com a função do usuário e com a propriedade do registro.
Devo usar row-level security do Postgres?
A row-level security permite que o próprio banco de dados imponha quais linhas cada usuário pode ler ou gravar, o que é uma ótima rede de segurança, especialmente quando o frontend conversa diretamente com o banco. Ela adiciona complexidade, então muitos apps aplicam as permissões no código do servidor e usam a row-level security como uma camada extra para tabelas sensíveis.