ACL (Access Control Lists)
An Access Control List (ACL) is a security mechanism that defines which users or system processes can access specific resources and what operations they can perform. ACLs are fundamental to implementing fine-grained authorization.
Core Concepts
- Subject: The entity requesting access (user, role, service)
- Object/Resource: The thing being accessed (file, record, endpoint)
- Permission: The allowed action (read, write, delete, execute)
ACL Structure Example
{
"resource": "document:12345",
"entries": [
{ "subject": "user:alice", "permissions": ["read", "write", "delete"] },
{ "subject": "user:bob", "permissions": ["read"] },
{ "subject": "role:editor", "permissions": ["read", "write"] },
{ "subject": "group:marketing", "permissions": ["read"] }
]
}
ACL vs RBAC vs ABAC
| Model | Based On | Complexity | Best For |
|---|---|---|---|
| ACL | Explicit permissions per resource | Simple | File systems, small apps |
| RBAC | Roles assigned to users | Medium | Enterprise applications |
| ABAC | Attributes and policies | Complex | Dynamic, context-aware access |
Implementation Patterns
Database-level ACL
Store permissions in the database, filter queries accordingly:
SELECT * FROM documents
WHERE id = 123
AND EXISTS (
SELECT 1 FROM document_acl
WHERE document_id = 123
AND user_id = current_user_id
AND 'read' = ANY(permissions)
);
Application-level ACL
Check permissions in code before operations:
if (acl.can(currentUser, 'write', document)) {
await document.update(changes);
}
What We Like
- Fine-grained: Exact control over who can do what
- Explicit: Clear audit trail of permissions
- Flexible: Different permissions per resource instance
What We Don't Like
- Scalability: Managing individual permissions gets unwieldy
- Complexity: Hard to answer "what can user X access?"
- Maintenance: Permission sprawl over time
Best Practices
- Combine with RBAC: Use roles for common patterns, ACL for exceptions
- Audit regularly: Review and clean up permissions
- Default deny: Require explicit grants, not explicit denies
- Document your model: Make authorization logic discoverable