aporat/laravel-auth-signature
Laravel middleware that authenticates incoming HTTP requests using signed signatures, letting you verify request integrity and identity without exposing credentials on each call.
Architecture fit: This package provides HMAC-style request signing for Laravel/PHP services. v3.2.0 materially improves client-side adoption: Http::withSignature() signs outgoing Laravel HTTP client requests at send time, RequestSigner supports PSR-7 requests, and auth-signature:sign gives developers a CLI for generating headers, curl commands, and canonical-string debug output. Because the macro and command reuse SignatureGenerator, client output should verify against existing ValidateAuthSignature middleware. That symmetry is the main TPM leverage point: standardize service-to-service authentication instead of maintaining bespoke signing code.
Integration feasibility: Feasible for Laravel applications already using the HTTP client and middleware. The happy path is low effort: install, configure client ID/secret, use Http::withSignature(...), and validate server-side. The artisan command should shorten debugging and support cycles. However, integration is not fully turnkey: signature failures currently render as HTTP 500 unless the host app adds exception mapping in bootstrap/app.php. That mapping must be treated as a required integration step, not an optional README note.
Technical risk: Medium. The largest operational risk is incorrect status semantics: authentication/signature failures returning 500 will pollute error budgets, trigger false incidents, and confuse clients unless mapped to 401/403. Replay protection is only the ±300 s timestamp window; there is no nonce or idempotency mechanism described. That may be acceptable for internal low-risk APIs over TLS, but it is not sufficient for high-value or replay-sensitive operations without additional controls. The optional $secret override in SignatureGenerator::generate() is useful for rotation/testing but is a footgun if exposed through application code paths or logs. Direct Composer requirements on illuminate/http, illuminate/routing, illuminate/console, and guzzlehttp/guzzle increase explicitness but also increase dependency-resolution surface. The package no longer ships tests, CI config, or dev tooling in the published artifact, so consumers cannot run the package’s own test suite from vendor; they must rely on upstream CI and their own integration tests.
Key questions:
^11 || ^12 change affects dev tooling, but the runtime matrix is not clear from the notes.Http::withSignature macro, or must the host app register it?bootstrap/app.php?Http::withSignature() safe with Laravel HTTP client retries, or does it re-sign each attempt correctly?Stack fit: Best fit is Laravel services using Illuminate\Http\Client for outbound calls and middleware for inbound validation. It also fits internal webhook or service-to-service authentication where both sides are Laravel/PHP. RequestSigner broadens fit to PSR-7/Guzzle-oriented code, but the package still pulls Laravel console/routing/http components, so it is less attractive for minimal non-Laravel PHP services. This is message authentication, not a replacement for user auth, OAuth, or authorization policy.
Migration path: For new adoption, implement server-side validation and client-side signing together on a low-risk endpoint first. Add exception mapping before enabling validation broadly. Use auth-signature:sign --debug and --curl to compare expected headers and canonical strings against existing custom signing code. For teams replacing bespoke signing, keep the old path available behind a feature flag until both sides verify in staging. For upgrades from earlier versions, check Composer constraints first, confirm Laravel major compatibility, add the exception mapping, and note that published artifacts no longer include tests or dev tooling.
Compatibility: The host Laravel version must be compatible with the required illuminate/* components and Guzzle. The Http::withSignature macro name could collide with an existing macro, so registration should be verified. Signature validation can break behind path-rewriting proxies, load balancers, or API gateways if the signed path differs from the validated path. Clock skew must be managed via NTP because the timestamp window is only ±300 s. Multipart and duplicate-query canonicalization need explicit validation if those request shapes are in scope. The default 500 response is a compatibility issue for clients expecting 401/403 and must be addressed in the host application.
Sequencing:
bootstrap/app.php exception mapping for signature failures to 401/403.Http::withSignature() for one internal client and verify against ValidateAuthSignature.auth-signature:sign in runbooks and support tooling for header/curl reproduction.Maintenance: The package is small and stateless, but the host team must track Laravel, Guzzle, and package releases. The published artifact no longer includes tests, CI config, or dev tooling; this reduces package size but shifts validation responsibility to upstream CI and consumer integration tests. Secrets become first-class operational assets and need rotation, storage, and audit procedures. The direct illuminate/* requirements make upgrade conflicts more visible but also mean Laravel major upgrades require coordinated package upgrades.
Support: The artisan command is a strong supportability improvement: it can reproduce headers and curl commands without printing secrets, and --debug exposes the canonical string. Still, support teams need a runbook for the common failure modes: wrong secret, clock skew, proxy path mismatch, body canonicalization mismatch, and unmapped 500s. The README clarification that signature failures render as 500 is honest but operationally insufficient by itself; production apps should map failures before rollout.
Scaling: The signing model is stateless and cheap to scale. The ±300 s timestamp window requires no shared nonce store, so it scales horizontally without Redis or database coordination. If the organization later adds nonce-based replay protection, that introduces a shared cache dependency and new failure modes. Request signing overhead should be negligible relative to network I/O, but high-volume clients should verify that signing at send time does not interfere with connection reuse or retries.
Failure modes: Misconfigured secrets produce hard-to-diagnose failures that surface as 500 unless mapped. Clock drift beyond ±300 s rejects otherwise valid requests. Replay within the timestamp window is possible if a signed request is captured and reused; TLS and idempotency keys reduce impact but do not eliminate the risk. Body mutation after signing, unsupported multipart bodies, duplicate query parameter ordering, redirects, and proxy path rewriting can all cause canonical-string mismatches. Secret override misuse can cause requests to be signed with an unintended secret. Retry behavior must be tested because a retried request may need re-signing with a fresh timestamp.
Ramp-up: Ramp-up is low for Laravel developers familiar with middleware and the HTTP client, especially with the new CLI command. TPM should still budget a short spike to validate the supported version matrix, exception mapping, proxy behavior, replay posture, and secret rotation. The package is a good leverage point for standardizing internal service authentication, but only if the team treats status mapping, clock sync, and replay risk as part of the product integration rather than post-launch cleanup.
How can I help you explore Laravel packages today?