gremo/hmac-authentication-bundle
A Symfony bundle for HMAC request authentication. It signs and verifies API requests using shared secrets, timestamps, and nonces, integrating with Symfony Security to protect stateless REST endpoints from tampering and replay attacks.
Architecture fit. Poor, and the mismatch is structural rather than cosmetic. This package is a Symfony bundle, not a Laravel package. It hooks into Symfony's security layer (firewall listener / authentication provider) and relies on Symfony's DependencyInjection, EventDispatcher, and HttpFoundation contracts. Laravel's auth surface is entirely different (middleware pipeline + guards + service container with different binding semantics). There is no Illuminate\Support\ServiceProvider, no configuration publishing, no facade — nothing a Laravel app can composer require and boot. The only genuinely reusable asset is the HMAC canonicalization scheme (which request components are signed, in what order, with what encoding), which is a specification, not an integration.
Integration feasibility. Two options, neither of which is "install the package":
hash_hmac, hash_equals, a timestamp-window check, and a nonce replay cache. Low effort, full control, no dead dependency.Installing it directly into a Laravel app is not viable without pulling Symfony components and hand-wiring a listener into Laravel's kernel — an anti-pattern that trades a 200-line middleware for a permanent dependency liability.
Technical risk. High, driven by three independent factors:
composer.json require block before anything else).The mitigating factor is that HMAC request signing is a well-understood, small primitive. The risk is in the dependency, not in the problem. Reimplementing removes nearly all of it.
Key questions to answer before any decision:
hash_equals), or a naive ==?Stack fit. Treat this repository as a reference implementation and interop spec, not a dependency. The deliverable is a first-party Laravel middleware: verify signature → check timestamp within window (e.g. ±300s) → check nonce against Redis with TTL ≥ window → resolve client secret from a api_clients table → attach an authenticated principal to the request. Pair it with a Laravel guard or a lightweight Request::setUserResolver so existing authorization (policies, gates) works unchanged.
Migration path. Four phases:
If no clients exist yet, skip the compatibility constraint entirely and design the canonicalization to current best practice (sign method + path + sorted query + SHA-256 body hash + timestamp + nonce).
Compatibility. Target Laravel 10/11/12 on PHP 8.2+. The original bundle likely declares PHP 7.x and Symfony 3/4 — assume a hard conflict and plan not to resolve it. Prefer a maintained alternative (e.g. a current HMAC auth package with recent releases) if one passes review; otherwise the in-house middleware is the lower-risk path.
Sequencing. Do the dependency/licence review and spec extraction first — one day of work that either kills the option or scopes it. Then middleware, then shadow mode, then client onboarding and secret provisioning, then enforcement. Client key distribution is the long pole; start it early and in parallel with the code.
Maintenance. If adopted as a dependency: effectively zero upstream maintenance, which converts to 100% internal ownership the moment a PHP or Symfony upgrade lands — you inherit a fork whether or not you plan to. If reimplemented: ~200 lines of first-party code with your own tests, which is cheaper to own over a 3-year horizon than an unmaintained transitive dependency.
Support. None available. No maintainer responsiveness, no issue triage, no security disclosure channel that would reach you in time. Any CVE-class issue in this code path is yours to find and patch. For authentication code, that is the decisive operational fact.
Scaling. The verification path is stateless and cheap — CPU-negligible per request, horizontally scalable with no coordination. The only stateful component is the nonce replay cache; Redis with TTL equal to the timestamp window scales fine and is already in most Laravel stacks. Do not put the nonce store in MySQL on the hot path.
Failure modes to design for explicitly:
Ramp-up. Low for the concept (HMAC signing is standard), moderate for the porting work (half a sprint including tests), and non-trivial for client onboarding — every integrating team needs the canonicalization spec, a test-vector fixture, and a sandbox. Budget documentation and a reference client SDK snippet; that, not the middleware, is where integration friction concentrates.
TPM recommendation. Do not take a production dependency on this package. Use it as a specification source, ship a first-party Laravel middleware with conformance tests, and record the decision as "reference-only, no runtime dependency." The package's low score, six-year staleness, and zero dependents align with that call; the underlying primitive is simple enough that building it is the cheaper and safer option.
How can I help you explore Laravel packages today?