DEV Community

Sebastian Cabarcas
Sebastian Cabarcas

Posted on

How I Solved Multi-Guard Permission Issues in Laravel with Redis

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)