As a backend developer, I’ve spent most of my career working with Python — FastAPI, Django, Flask.
I’ve always cared about one thing deeply:
👉 building systems that scale without becoming messy
But there was one problem I kept running into… no matter the stack.
🧠 The Problem: The “Global Role” Trap
At first, everything looks simple:
• Users
• Roles
• Permissions
But as systems grow, things start breaking.
Most RBAC (Role-Based Access Control) packages assume:
👉 a user is either an Admin… or they aren’t.
But real-world systems are never that simple.
A real scenario:
• A user is a Manager in Branch A
• The same user is a Viewer in Branch B
Now ask yourself:
👉 How do you model this cleanly?
Most of the time, we don’t.
We write conditions like:
if ($user->role === 'manager' && $branch_id === 1) { ... }
And slowly…
• logic spreads everywhere
• dependencies grow
• and one small change breaks multiple parts of the system
😵 When It Became a Problem
Across multiple projects, I saw the same pattern:
• Roles started multiplying
• Permissions became unclear
• Debugging access issues became painful
It didn’t matter if I was using Python or Laravel.
👉 The problem wasn’t the framework.
👉 The problem was the model.
🔄 The Turning Point
While working on Laravel-based systems, I explored existing solutions like Spatie.
They are great — clean, simple, and widely used 👏
But for complex systems, I kept hitting limitations:
• No real support for contextual authority
• Difficult to manage multi-tenant permissions
• Hard to model relationships between roles and scopes
At some point, I stopped trying to “work around” the problem.
👉 I decided to rethink it.
🚀 Building Laravel IAM
Instead of focusing only on roles, I started thinking in terms of:
👉 relationships + context + resolution
This led me to build:
Laravel IAM (v0.2.0)
⚙️ The Core Idea: The Four Levels of Truth
Instead of hardcoding logic, the system resolves permissions through layered specificity:
- *Global *→ . (Super Admin)
- Resource Wildcard → invoice.*
- Action Wildcard → *.approve
- Atomic Permission → invoice.approve This makes permission checks: • predictable • scalable • easy to reason about
🧩 Context Matters
The same role doesn’t mean the same thing everywhere.
So the system supports:
• Tenant-based roles
• Team-based roles
• Branch-level permissions
👉 Without turning your code into a mess
💡 What I Learned
This journey taught me something important:
👉 Authorization is not about roles — it’s about context
And even more importantly:
👉 Architecture matters more than framework
⚙️ Under the Hood
Some design decisions behind the system:
• Registry Pattern → decoupled resources & actions
• Flexible Role Assignment → supports IDs, slugs, or models
• Scoped Middleware → supports contextual authorization
• Blade Directives → clean UI permission checks
And yes — everything is backed by a test suite simulating real workflows ✅
🛠️ Open Source
I’ve open-sourced the project and would genuinely love feedback:
📦 https://packagist.org/packages/apurba-labs/laravel-iam
💻 https://github.com/apurba-labs/laravel-iam
💬 Let’s Talk
How do you handle complex permissions in your systems?
Have you faced similar challenges with RBAC?
This is a submission for the 2026 WeCoded Challenge: Echoes of Experience
Built with ☕ and logic by Apurba Labs.
Top comments (0)