Back to build log
Designing role based access systems
·7 min read
Designing role based access systems
Every multi-user application eventually needs access control. Here's how I built one that scales.
The Permission Model
I settled on a hierarchical model:
• **Admin** - Full access
• **Organizer** - Can manage events they own
• **Staff** - Can check in attendees
• **Attendee** - Can view and register
Database Schema
The key insight was separating roles from permissions:
CREATE TABLE roles (
id UUID PRIMARY KEY,
name TEXT NOT NULL,
level INT NOT NULL
);
CREATE TABLE permissions (
id UUID PRIMARY KEY,
role_id UUID REFERENCES roles(id),
resource TEXT NOT NULL,
action TEXT NOT NULL
);Middleware Pattern
Every protected route runs through a single middleware:
export function requirePermission(resource: string, action: string) {
return async (req, res, next) => {
const hasAccess = await checkPermission(req.user, resource, action);
if (!hasAccess) return res.status(403).json({ error: 'Forbidden' });
next();
};
}Lessons Learned
• Start simple, add complexity only when needed
• Always log permission checks for debugging
• Test edge cases: What happens when a user has multiple roles?