Back to results for “Design Patterns in Java”
Node.js › Authentication & Authorization

How would you implement Attribute-Based Access Control (ABAC) in a Node.js application when RBAC roles aren't expressive enough?

Intermediate

Answer

ABAC evaluates access decisions based on attributes of the user, the resource, and the context (time of day, IP location, resource ownership) rather than a fixed role -- a policy engine evaluates rules like 'a user can edit a document if user.department === document.department AND user.id === document.ownerId' at request time, providing much finer-grained control than RBAC alone can express, at the cost of more complex policy definitions and evaluation logic.
function canEditDocument(user, document) {
  return (
    document.ownerId === user.id ||
    (user.department === document.department && user.role === 'manager')
  );
}

app.put('/documents/:id', requireAuth, async (req, res) => {
  const doc = await Document.findById(req.params.id);
  if (!canEditDocument(req.user, doc)) return res.status(403).json({ error: 'Forbidden' });
  updateDocument(doc, req.body);
});
Real-world example A document-management system lets a manager edit any document belonging to their own department, and lets any user edit documents they personally own, regardless of department -- a rule that a simple role check alone couldn't express, requiring an attribute-based comparison between the user and the specific resource involved.

Common follow-ups: How do dedicated policy engines like Open Policy Agent (OPA) or CASL formalize this pattern beyond hand-written if statements?;At what point does the combinatorial complexity of ABAC rules become a maintenance burden?