ABAC, ou Attribute-Based Access Control, decide acesso usando atributos do usuário, recurso, ação e contexto. Diferentemente do RBAC, que agrupa permissões por papel, o ABAC permite regras como “editores podem alterar documentos do próprio tenant enquanto estão em rascunho”.
O modelo é útil quando papéis se tornam numerosos ou insuficientes, mas exige políticas centralizadas, dados confiáveis e testes extensivos.
Elementos da decisão
- subject: usuário, serviço ou API key;
- resource: documento, pedido ou conta;
- action: read, update, approve ou delete;
- environment: horário, rede, nível de autenticação e risco.
Primeira política
function canEditPost({ subject, post }) {
if (subject.tenantId !== post.tenantId) return false;
if (!subject.permissions.includes('posts:write')) return false;
if (post.status !== 'draft') return false;
return subject.role === 'admin' || post.authorId === subject.userId;
}A política combina papel, permissão, tenant, estado e propriedade.
Negar por padrão
Se uma regra não autoriza explicitamente, negue. Não use fallbacks como “usuário autenticado pode acessar” em recursos sensíveis.
Contexto confiável
Atributos não devem vir diretamente de headers ou body sem validação. O tenant e a propriedade precisam ser obtidos do recurso ou de identidade autenticada.
Política separada do controller
const decision = authorization.evaluate({
subject: req.auth,
action: 'invoice:approve',
resource: invoice,
environment: {
mfa: req.auth.mfa,
ipRisk: req.risk.ipScore,
},
});
if (!decision.allowed) {
throw new ForbiddenError();
}Controllers devem aplicar a decisão, não reconstruir a regra em cada rota.
Resultado explicável
return {
allowed: false,
reason: 'mfa_required',
policy: 'invoice-approval-v3',
};O reason ajuda auditoria e testes. Para o cliente, devolva mensagem genérica quando detalhes revelariam regras internas.
RBAC e ABAC juntos
RBAC pode conceder a permissão ampla e ABAC limitar pelo recurso:
papel editor => posts:write
ABAC => mesmo tenant, autor ou admin, status draftEssa combinação mantém papéis compreensíveis e regras contextuais precisas.
Multi-tenant
O isolamento por tenant deve ser condição obrigatória em todas as políticas aplicáveis. Também filtre consultas no banco para não carregar recursos de outro tenant antes da decisão.
Row-level security
Banco e aplicação podem aplicar controles complementares. Row-level security reduz impacto de falhas na aplicação, mas precisa de contexto de conexão confiável e testes.
Condições temporais
Acesso temporário deve usar timestamps do servidor:
if (grant.expiresAt <= new Date()) return deny('grant_expired');Não confie no relógio do cliente.
Nível de autenticação
Operações críticas podem exigir MFA recente:
const ageMs = Date.now() - subject.mfaVerifiedAt;
if (ageMs > 10 * 60 * 1000) return deny('step_up_required');Políticas como código
Regras em código passam por revisão, testes e versionamento. Para sistemas maiores, motores como Open Policy Agent ou Cedar podem centralizar decisões. Adotar um motor adiciona rede, disponibilidade e linguagem própria.
Policy Decision Point
O componente que decide é o PDP; o middleware ou serviço que aplica é o PEP. Separe responsabilidades para tornar auditoria e substituição mais fáceis.
Cache de decisões
Decisões dependem de atributos mutáveis. Cacheie somente por janela curta e inclua versão da política, identidade, ação e recurso. Revogação urgente precisa invalidar.
Performance
Evite várias consultas por decisão. Carregue atributos necessários em uma consulta, use índices e meça p95. Não copie dados sensíveis para tokens apenas para eliminar chamadas.
Auditoria
Registre decisões críticas com policy version, subject ID, resource ID, action, resultado e reason. Não registre conteúdo completo do recurso.
Testes de tabela
const cases = [
{ role: 'editor', owner: true, status: 'draft', allowed: true },
{ role: 'editor', owner: false, status: 'draft', allowed: false },
{ role: 'admin', owner: false, status: 'draft', allowed: true },
{ role: 'admin', owner: false, status: 'published', allowed: false },
];Teste limites de tenant, horário, MFA, estado e atributos ausentes.
Erros comuns
- atributos controlados pelo cliente;
- regras duplicadas em controllers;
- permitir por padrão;
- não versionar políticas;
- cache sem invalidação;
- não filtrar tenant no banco;
- políticas impossíveis de explicar;
- registrar dados sensíveis;
- usar ABAC para toda regra simples.
Fluxo recomendado
- comece com ações e recursos;
- liste atributos confiáveis;
- negue por padrão;
- centralize políticas;
- combine com RBAC;
- versione decisões;
- teste matrizes;
- audite ações críticas;
- meça latência.
Combine ABAC com RBAC no Node.js, JWT, API Keys e Pino.
Consulte o guia de autorização da OWASP e a referência de ABAC do NIST.



