maba/gentle-force-bundle
maba/gentle-force-bundle adds brute force protection to your login forms by tracking failed authentication attempts and throttling repeated failures, helping block attackers while keeping legitimate users signed in smoothly.
Architecture fit. maba/gentle-force-bundle is a Symfony bundle, not a Laravel package. It ships a Bundle class, a DependencyInjection extension for the maba_gentle_force config tree, and event subscribers wired into Symfony's security.authentication.failure flow. None of that bootstraps under Laravel's service container. The only realistic leverage for a Laravel-centric org is as a reference design for three limiter primitives: brute-force (credential-stuffing), error-rate (4xx/5xx anomaly), and request-rate (generic throttle), backed by a swappable storage interface with cache-based and Doctrine/ORM-based implementations.
Integration feasibility — low. Three paths, ranked by effort:
Illuminate\Cache\RateLimiter + the throttle middleware + a listener on Illuminate\Auth\Events\Failed. Covers brute-force and request-rate at parity; the error-rate limiter is a small custom middleware.Technical risk — high for anything touching authentication.
symfony/rate-limiter, Symfony's built-in login throttling, Laravel's RateLimiter) already cover the bulk of the functionality.Key questions for the maintainer/owner.
Recommendation: do not adopt as a dependency. Treat it as a design reference and build the three limiters on Laravel primitives. Revisit only if we introduce a Symfony service.
Stack fit. If the target is Laravel: native RateLimiter + Redis store, throttle: middleware, and a Failed-event listener with an exponential backoff keyed on email|ip. The bundle's differentiator — a unified abstraction across three limiter types plus captcha escalation — is reproducible in ~200 lines and inherits framework support guarantees.
Migration path. (1) Inventory current auth endpoints and abuse signals. (2) Implement request-rate first (lowest blast radius, throttle middleware). (3) Add brute-force on Illuminate\Auth\Events\Failed with per-identifier and per-IP buckets. (4) Add error-rate last, since it needs response observation and careful exclusions.
Compatibility. The bundle's PHP 7.x/8.0-era constraints and Symfony 4.4/5.x wiring do not align with a modern Laravel runtime; expect to vendor and patch rather than composer require. If a Symfony port is genuinely on the table, prefer symfony/rate-limiter (actively maintained, same conceptual model) and Symfony's native login throttling.
Sequencing. Shadow mode first — emit limiter decisions as metrics without enforcing, for 2–3 weeks, to tune thresholds and confirm key cardinality. Then enforce on login only. Then extend to API and error-rate. Gate each stage behind a feature flag so rollback is a config change, not a deploy.
Maintenance. Zero upstream velocity. Any bug we hit is ours to fix; the fork becomes a permanent liability on an authentication-critical path. Budget ongoing ownership rather than assuming community support.
Support. Community-only, single maintainer, no SLA, no security channel. Escalation path is a GitHub issue on a repo with 50 stars.
Scaling. Storage choice dominates. A cache/Redis backend scales horizontally and is the only viable option for multi-node deployments. The Doctrine/ORM backend writes a row per attempt — under credential-stuffing load that means hot-row contention and lock waits on the exact table you need responsive during an incident. Counter cardinality also matters: unbounded keys (raw email, raw IP) inflate Redis memory and need TTL discipline.
Failure modes.
Ramp-up. The API surface is small and legible — a mid-level engineer can extract the design in a day and reach a production PoC in 2–4 days. The real ramp-up cost is organizational: agreeing thresholds, defining what "abuse" means per endpoint, and wiring alerting on limiter trips. That work is identical whether we adopt the bundle or reimplement, which further weakens the case for the dependency.
How can I help you explore Laravel packages today?