-
Notifications
You must be signed in to change notification settings - Fork 11.8k
Description
Laravel Version
12.43
PHP Version
8.3
Database Driver & Version
No response
Description
When using Redis-native rate limiting (via ThrottleRequestsWithRedis), the throttle middleware generates Redis keys without a stable namespace.
The key generation logic lives in ThrottleRequests::handle() and produces keys based on the request signature (hashed identifier), which results in raw, unhaspaced Redis keys (e.g. SHA-1 hashes).
While this works in unrestricted Redis environments, it breaks in Redis installations where ACLs are enforced using key patterns (common in managed Redis / Valkey services).
In such environments, Redis-native throttling fails with:
NOPERM No permissions to access a key
even when all required Redis commands (including EVAL) are explicitly allowed.
This behavior is inconsistent with other Redis-backed features in Laravel (cache, queue, session), which always use namespaced keys (laravel:, queues:*).
Additional context
The throttle middleware already supports a $prefix argument, which is concatenated to the generated key in ThrottleRequests::handle().
However, this prefix is designed for logical separation of rate limiters at the route level (e.g. distinguishing different limits on the same endpoint), not as a stable infrastructure-level namespace.
Because the prefix is optional, route-specific, and user-provided, it cannot be reliably used to ensure compatibility with Redis ACLs based on key patterns.
For comparison, using the cache-based throttle middleware (ThrottleRequests) with Redis configured as the cache driver works correctly in the same ACL-restricted Redis environments, as cache keys are properly namespaced via the cache prefix.
Possible improvement
Providing a stable, overrideable namespace for Redis-based rate limiter keys would make the middleware compatible with Redis ACLs while preserving backward compatibility.
For example, this could be achieved by introducing a protected method that returns an optional infrastructure-level key prefix (defaulting to an empty string), which would be prepended to the generated throttle key.
This approach would preserve existing behavior by default, while allowing applications running in ACL-restricted Redis environments to safely namespace rate limiter keys.
Steps To Reproduce
-
Create a new Laravel application.
-
Configure Redis as the backend for rate limiting and enable Redis-native throttling
(i.e. useThrottleRequestsWithRedis). -
Configure Redis/Valkey with ACLs that restrict access by key pattern, for example:
- Allow all commands required by Redis-based throttling (including
EVAL). - Allow access only to keys matching a specific prefix (e.g.
throttle:*orlaravel:*).
- Allow all commands required by Redis-based throttling (including
-
Apply the throttle middleware to a route:
Route::middleware('throttle:5,1')->get('/test', fn () => 'ok');
-
Send a request to the route.
-
Observe that Redis immediately returns the following error:
NOPERM No permissions to access a key -
Inspect the Redis key used by the throttle middleware: it is a raw hash without a namespace
and therefore does not match the allowed ACL key patterns.