Access Control & RBAC
Implement secure access control systems with fine-grained permissions using RBAC, ABAC, or hybrid approaches.
Access Control Models
Model Description Best For
RBAC Role-based - users assigned to roles with permissions Most applications
ABAC Attribute-based - policies evaluate user/resource attributes Complex rules
MAC Mandatory - system-enforced classification levels Government/military
DAC Discretionary - resource owners control access File systems
ReBAC Relationship-based - access via entity relationships Social apps
Node.js RBAC Implementation
class Permission { constructor(resource, action) { this.resource = resource; this.action = action; }
matches(resource, action) { return (this.resource === '' || this.resource === resource) && (this.action === '' || this.action === action); } }
class Role { constructor(name, permissions = [], parent = null) { this.name = name; this.permissions = permissions; this.parent = parent; }
hasPermission(resource, action) { if (this.permissions.some(p => p.matches(resource, action))) return true; return this.parent?.hasPermission(resource, action) ?? false; } }
class RBACSystem { constructor() { this.roles = new Map(); this.userRoles = new Map(); }
createRole(name, permissions = [], parentRole = null) { const parent = parentRole ? this.roles.get(parentRole) : null; this.roles.set(name, new Role(name, permissions, parent)); }
assignRole(userId, roleName) { const userRoles = this.userRoles.get(userId) || []; userRoles.push(this.roles.get(roleName)); this.userRoles.set(userId, userRoles); }
can(userId, resource, action) { const roles = this.userRoles.get(userId) || []; return roles.some(role => role.hasPermission(resource, action)); } }
// Express middleware const requirePermission = (resource, action) => (req, res, next) => { if (!rbac.can(req.user.id, resource, action)) { return res.status(403).json({ error: 'Forbidden' }); } next(); };
// Setup default roles const rbac = new RBACSystem(); rbac.createRole('viewer', [new Permission('', 'read')]); rbac.createRole('editor', [new Permission('', 'write')], 'viewer'); rbac.createRole('admin', [new Permission('', '')], 'editor');
Python ABAC Pattern
class Policy: def init(self, name, effect, resource, action, conditions): self.name = name self.effect = effect # 'allow' or 'deny' self.resource = resource self.action = action self.conditions = conditions
def matches(self, context):
if self.resource != "*" and self.resource != context.get("resource"):
return False
if self.action != "*" and self.action != context.get("action"):
return False
return True
def evaluate(self, context):
return all(cond(context) for cond in self.conditions)
class ABACEngine: def init(self): self.policies = []
def add_policy(self, policy):
self.policies.append(policy)
def check_access(self, context):
for policy in self.policies:
if policy.matches(context) and policy.evaluate(context):
return policy.effect == 'allow'
return False # Deny by default
Condition functions
def is_resource_owner(ctx): return ctx.get("user_id") == ctx.get("resource_owner_id")
def is_within_business_hours(ctx): from datetime import datetime return 9 <= datetime.now().hour < 18
See references/python-abac.md for complete implementation with Flask integration.
Java Spring Security
See references/java-spring-security.md for enterprise implementation with:
-
Spring Security configuration
-
Method-level security with @PreAuthorize
-
Custom permission service
-
Custom security expressions
Best Practices
Do:
-
Apply least privilege principle
-
Use role hierarchies to reduce duplication
-
Audit all access changes
-
Review permissions quarterly
-
Cache permission checks for performance
-
Separate authentication from authorization
Don't:
-
Hardcode permission checks
-
Allow permission creep without review
-
Skip audit logging
-
Use overly broad wildcards
References
-
NIST RBAC Model
-
OWASP Access Control Cheat Sheet
-
AWS IAM Best Practices