mopa/wsse-authentication-bundle
A Symfony bundle that adds WSSE authentication for APIs, validating X-WSSE headers with username, created timestamp, and digest so clients can authenticate requests using Web Services Security tokens.
Architecture fit. This is not a Laravel package — it is a Symfony2 bundle (mopa/wsse-authentication-bundle) that plugs into the Symfony Security component via a custom AuthenticationProvider, a firewall listener, a WsseToken, and a nonce cache. Its integration surface is Symfony's DI container (XML/YAML service definitions), the security.firewalls config tree, and Symfony\Component\Security\Core\* interfaces. None of that exists in Laravel's guard/middleware model. There is no path to composer require this into a Laravel application; its value to us is as a reference implementation of the WSSE UsernameToken digest and replay-protection pattern, not as a dependency.
Integration feasibility. The protocol logic worth harvesting is small — roughly 200–400 LOC: parse the Authorization: WSSE profile="UsernameToken" header, Base64-decode the UsernameToken, extract Username, PasswordDigest, Nonce, Created, verify Base64(SHA1(nonce + created + password)), validate the Created timestamp against a clock-skew window, and record the nonce in a TTL cache to block replay. Reimplementing that as a Laravel middleware plus a custom guard is a 3–5 day task for one engineer including test coverage. Reusing the package directly is not feasible on PHP 8.x / Laravel 10–11; the code targets PHP 5.3-era syntax and Symfony 2.0/2.1 APIs that were removed years ago.
Technical risk.
SHA1(nonce + created + password). That is incompatible with bcrypt/argon2 hashing and would force a reversible or plaintext credential store. If we build this, we must deviate from the spec (HMAC with a stored per-client secret) or scope WSSE strictly to a dedicated API-credential table that never touches user passwords.Key questions.
Stack fit. Poor as a dependency, adequate as a pattern source. Target implementation: a WsseAuthenticate middleware registered on the relevant API route group, delegating credential lookup to a dedicated WsseCredential model (client id, secret/key, active flag, allowed clock skew), with Illuminate\Support\Facades\Cache backed by Redis for the nonce store. Do not attempt to graft Symfony's AuthenticationProvider semantics onto Laravel's Guard; a middleware that resolves the client and calls Auth::setUser() (or simply authorizes the request) is simpler and matches Laravel idioms.
Migration path. Treat this as greenfield server-side implementation, not a migration:
Created, replayed nonce, malformed Base64, missing header, clock skew at both boundaries.Compatibility. Package itself: incompatible with modern PHP/Symfony, untestable on our matrix — record as "reference only." Our implementation: PHP 8.2/8.3, Laravel 10/11, Redis 7, PHPUnit/Pest. If a Symfony service ever needs to consume the same API, the middleware logic ports cleanly to a Symfony listener, so keep the digest/verification code framework-agnostic in a small Wsse support class.
Sequencing. Lock the algorithm decision (spec digest vs. HMAC variant) before implementation — it drives the credential schema and cannot be changed later without breaking clients. Then nonce store, then middleware, then conformance tests, then shadow rollout. Coordinate the enforce step with the partner's release calendar.
Maintenance. We own 100% of it. Budget ~2–4 engineering days per year for dependency drift (Laravel major upgrades, Redis client changes) plus incident time. Keeping the surface small — one middleware, one support class, one migration — keeps that number defensible. Do not vendor the bundle's code; rewrite from the spec so we are not carrying GPL/unknown-provenance fragments or dead Symfony scaffolding.
Support. No upstream, no community, no CVE feed. Internal documentation and a named owner are prerequisites, not nice-to-haves. Partner-facing support for digest failures will land on our on-call unless we ship a diagnostic path.
Scaling. The nonce cache is the scaling chokepoint: it must be shared across all app instances and atomic. Use Redis SET key NX EX <skew_window> and treat a failed set as a replay. Size at roughly one key per authenticated request within the skew window — trivial volume, but it makes Redis a hard dependency on the auth path. Horizontal scaling of the app tier is otherwise unaffected; the scheme is stateless apart from the cache.
Failure modes.
Ramp-up. Low individual learning cost: the protocol is well documented and the code surface is a few hundred lines; a mid-level engineer is productive in a day. The organizational cost is higher — this is a legacy auth scheme with a permanent ownership tail and no vendor to escalate to, so it should be adopted only where a partner contract forces it, and documented as a deliberate exception to our standard auth stack.
How can I help you explore Laravel packages today?