advanced-rbac
To implement a scalable permission system where users have roles, and roles have granular permissions. Use when: B2B SaaS applications (Admin, Editor, Viewer); Systems with complex access requirements
SKILL.mdskills/advanced-rbac/SKILL.md
GitHubPurpose
To implement a scalable permission system where users have roles, and roles have granular permissions.
When to Use
- B2B SaaS applications (Admin, Editor, Viewer).
- Systems with complex access requirements.
Procedure
1. Data Model
- Users:
id,name,role_id(or m:nuser_roles). - Roles:
id,name(e.g., 'admin', 'editor'). - Permissions:
id,action,resource(e.g.,create:post,read:user). - RolePermissions: Join table.
2. Middleware (Enforcement)
Don't check roles (if user.role === 'admin'). Check permissions.
// middleware/authorize.js
const authorize = (requiredPermission) => {
return async (req, res, next) => {
const userPermissions = await getUserPermissions(req.user.id); // Cached in JWT or Redis
if (!userPermissions.includes(requiredPermission)) {
return res.status(403).json({ error: 'Forbidden' });
}
next();
};
};
// usage
app.post('/posts', authorize('create:post'), createPost);
3. Hierarchy (Optional)
Roles can inherit from others.
Adminhas all permissions ofEditor+delete:user.- This logic is handled in the permission resolution function.
4. Frontend Integration
Send permissions list to frontend on login.
{
token: "...",
user: {
id: 1,
permissions: ["read:posts", "create:posts"]
}
}
Use a <Can permission="create:posts"> component to hide/show UI elements.
Constraints
- Granularity: Balance between too broad (
manage:all) and too specific (update:post:title). - Caching: Fetching permissions on every request is slow. Cache them in the JWT or Redis (invalidate on role change).
Expected Output
A flexible security model allowing admins to configure what users can do without changing code.