Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

RBAC no Node.js

Atualizado em: 7 de outubro de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

RBAC, ou Role-Based Access Control, organiza permissões por papéis como administrador, suporte, editor e usuário. Em aplicações Node.js, ele reduz verificações espalhadas e cria uma política central de autorização. O modelo precisa aplicar menor privilégio, negar por padrão e considerar o recurso acessado, não apenas a rota.

Autenticação e autorização

Autenticação responde quem é o usuário. Autorização decide o que ele pode fazer. Um JWT válido ou sessão ativa não concede automaticamente acesso administrativo.

Modelo simples

const rolePermissions = {
  admin: new Set(['users:read', 'users:write', 'billing:read']),
  support: new Set(['users:read']),
  editor: new Set(['posts:read', 'posts:write']),
  user: new Set(['profile:read', 'profile:write']),
};

function can(role, permission) {
  return rolePermissions[role]?.has(permission) ?? false;
}

Use nomes estáveis de permissão. Evite regras como isAdmin espalhadas pelo código.

Middleware

function requirePermission(permission) {
  return (req, res, next) => {
    if (!req.auth || !can(req.auth.role, permission)) {
      res.status(403).json({ error: 'forbidden' });
      return;
    }
    next();
  };
}

app.get('/users', requireJwt, requirePermission('users:read'), listUsers);

Negar por padrão

Uma rota nova não deve ficar acessível porque ninguém adicionou uma regra. Crie convenções e testes que falhem quando endpoints sensíveis não possuem middleware de autorização.

Papéis no banco

CREATE TABLE roles (
  id UUID PRIMARY KEY,
  name TEXT UNIQUE NOT NULL
);

CREATE TABLE role_permissions (
  role_id UUID NOT NULL,
  permission TEXT NOT NULL,
  PRIMARY KEY (role_id, permission)
);

Em sistemas simples, configuração em código é mais previsível. Em sistemas multi-tenant ou administráveis, banco pode ser necessário.

Usuário com múltiplos papéis

function permissionsForRoles(roles) {
  const permissions = new Set();
  for (const role of roles) {
    for (const permission of rolePermissions[role] || []) {
      permissions.add(permission);
    }
  }
  return permissions;
}

Defina se permissões são apenas aditivas ou se existe negação explícita. Misturar os dois modelos sem precedência clara cria erros.

Escopo do recurso

RBAC puro pode dizer que um editor pode alterar posts, mas ainda é preciso decidir quais posts. Verifique propriedade, tenant, estado e outras condições:

if (post.tenantId !== req.auth.tenantId) {
  throw new ForbiddenError();
}

if (!can(req.auth.role, 'posts:write')) {
  throw new ForbiddenError();
}

Multi-tenant

Um usuário pode ser admin em um tenant e leitor em outro. Não coloque apenas role=admin no token sem contexto. Modele associação:

userId + tenantId + role

Valide tenant pelo recurso e não apenas por header fornecido pelo cliente.

Hierarquia de papéis

Hierarquia como admin > editor > viewer parece simples, mas papéis reais nem sempre são lineares. Permissões explícitas são mais fáceis de auditar que números de nível.

Claims no JWT

Roles no JWT ficam desatualizadas até a expiração. Use access tokens curtos e, para operações críticas, consulte a autorização atual ou uma versão de permissões.

Versão de autorização

if (payload.authzVersion !== user.authzVersion) {
  throw new AuthenticationError('Token desatualizado');
}

Incrementar a versão permite invalidar tokens após alteração importante.

Separação de funções

Algumas operações exigem que quem cria não aprove. Modele permissões distintas e registre o autor da ação. RBAC pode implementar segregação, mas a regra precisa estar no domínio.

Elevação temporária

Acesso administrativo temporário deve expirar automaticamente, exigir MFA e gerar auditoria. Não altere um usuário permanentemente para resolver um incidente curto.

Contas de serviço

Serviços não deveriam receber papel humano genérico. Use identidades e permissões específicas, como invoice-worker com invoices:process.

UI não é controle

Ocultar botão melhora experiência, mas o backend precisa negar a requisição. Clientes podem chamar endpoints diretamente.

Resposta 401 ou 403

  • 401: identidade ausente ou inválida;
  • 403: identidade válida sem permissão.

Para recursos sensíveis, às vezes 404 reduz enumeração, mas a política deve ser consistente.

Cache de permissões

Cache reduz consultas, mas precisa de TTL curto ou invalidação. Uma revogação urgente não pode levar horas para surtir efeito.

Auditoria

Registre mudanças de papel, concessões, revogações e uso de ações críticas. Inclua ator, alvo, tenant, permissão, timestamp e request ID, sem dados sensíveis.

Testes de matriz

const cases = [
  ['admin', 'users:write', true],
  ['support', 'users:write', false],
  ['support', 'users:read', true],
];

for (const [role, permission, expected] of cases) {
  expect(can(role, permission)).toBe(expected);
}

Teste também isolamento entre tenants, tokens desatualizados e propriedade do recurso.

Erros comuns

  • confiar na interface;
  • role admin sem tenant;
  • permissões em strings espalhadas;
  • não negar por padrão;
  • tokens longos com role antiga;
  • cache sem invalidação;
  • papéis excessivamente amplos;
  • não auditar mudanças;
  • confundir papel com propriedade do recurso.

Fluxo recomendado

  1. liste ações do domínio;
  2. crie permissões estáveis;
  3. agrupe em papéis;
  4. negue por padrão;
  5. valide tenant e recurso;
  6. use tokens curtos;
  7. audite alterações;
  8. teste a matriz;
  9. revise menor privilégio.

Combine RBAC com JWT no Node.js, API Keys, Pino e Secret Management.

Consulte o guia de autorização da OWASP e a referência de RBAC do NIST.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita