When working with Laravel applications that use multiple guards (web, api, etc.), I ran into a subtle but critical issue:
Permissions were leaking between guards.
At first, everything seemed fine… until it wasn’t.
The Problem
Imagine this scenario:
A user has a permission under the api guard
You check that permission under the web guard
$user->hasPermissionTo('posts.edit');
And it returns true, even though it shouldn’t.
This happens when your permission system doesn’t properly isolate guards — something that can silently introduce security issues in production.
Why This Happens
Most implementations treat permission names as globally unique:
posts.edit
But in reality, permissions should be scoped by guard, meaning:
web: posts.edit
api: posts.edit
Without that separation, collisions are inevitable.
The Solution
In v2.0.0 of my package (laravel-permissions-redis), I redesigned the permission system to be fully guard-aware.
1. Guard-Scoped Permission Checks
All permission and role checks now accept a guard:
$user->hasPermissionTo('posts.edit', 'api');
$user->hasRole('admin', 'web');
Or fluently:
$user->forGuard('api')->hasPermissionTo('posts.edit');
2. Redis Storage Redesign
Permissions are now stored using this format:
guard|permission
Example:
api|posts.edit
web|posts.edit
This completely eliminates collisions between guards.
3. Smarter Caching
I also improved cache control to make the system more scalable:
rewarmAll() → rebuild cache without flushing
warmPermissionAffectedUsers() → only warm impacted users
getUserIdsAffectedByPermission() → precise impact analysis
4. Performance Improvements
No more full table scans when warming users
Redis config is cached internally
Middleware now resolves the correct guard automatically
Breaking Changes
If you're upgrading:
Methods like hasPermission() now accept a $guard
Redis key format changed → you must flush and rewarm cache
Key Takeaway
Authorization bugs are dangerous because they don’t crash your app — they silently give access.
Fixing guard isolation is not just a “nice to have”, it’s essential for any system with:
- APIs + Web apps
- Multi-auth setups
- Scalable architectures
Final Thoughts
This update was focused on one thing:
Making authorization correct, predictable, and scalable.
If you're dealing with complex permission systems in Laravel, this approach might save you from some very tricky bugs.
I’d love to hear your thoughts or how you're handling permissions in your projects.
Top comments (0)