escapestudios/wsse-authentication-bundle
EscapeWSSEAuthenticationBundle provides simple, out-of-the-box WSSE authentication for Symfony applications. Secure stateless API firewalls via security.yml, with configurable token lifetime, custom date formats, and a console command to delete expired nonces.
Architecture fit — the first finding a TPM must surface: this is not a Laravel package. escapestudios/wsse-authentication-bundle is a Symfony bundle. Every integration point in the README is Symfony-specific and pre-Symfony-4: AppKernel::registerBundles(), app/config/security.yml, app/console, and a custom wsse firewall type registered through a DI extension. None of that is loadable in Laravel — there is no service provider, no middleware, no framework hook. So the "Laravel/PHP package" framing in the brief does not survive contact with the code. The actual TPM decision splits in two:
PasswordDigest = base64(sha1(nonce + created + password, true)), timestamp freshness window, nonce replay cache — and write equivalent middleware. That is a normal, bounded piece of work; pretending this is a drop-in is the failure mode to avoid.Integration feasibility. The protocol surface is genuinely small: one hash construction plus three concerns (freshness window, nonce replay cache, credential lookup). The bundle's real added value is narrow but non-trivial — getting the digest byte-handling, skew tolerance, and nonce expiry right is exactly the class of code that produces subtle, hard-to-detect auth bugs when hand-rolled. That justifies a time-boxed evaluation, not a blank cheque.
Technical risk.
app/console, ^2.2 constraint. Zero dependents means zero ecosystem pressure to fix anything — you are the maintainer the day you adopt.PasswordDigest is defined as SHA1 over nonce + created + password, and any counterparty implementing the standard will send SHA1. Switching the encoder will simply reject valid partner requests. The security posture should be addressed by scoping (partner endpoints only, TLS-only, short lifetime), not by changing the digest.Key questions to close before any commitment.
PhpFileCache in %kernel.cache_dir% — see failure modes.)Stack fit. Binary: Symfony 2/3 → viable dependency. Laravel or Symfony 4+/Flex → no direct fit; treat the repo as a protocol specification with reference code and budget middleware work. Do not let the "PHP package" label pull a Symfony bundle into a Laravel service.
Migration path (if adopting).
wsse firewall to the partner-facing route pattern (^/api/partner/.*), keep stateless: true.provider: override rather than the firewall default, so partner credentials resolve from their own user provider, not your primary one.Migration path (if Laravel). Reimplement as a middleware: parse X-WSSE, validate Created against a configurable skew window, reject replayed nonces via an atomic SETNX+TTL in Redis, recompute PasswordDigest and compare with hash_equals, resolve the user from the partner credential store. The bundle's README is the acceptance criteria; its nonce-purge command becomes a Redis TTL, which is strictly better than a cron job.
Compatibility checklist. PHP version constraints in composer.json; Symfony Security component API version (firewall factory signatures changed across 2.x/3.x); Doctrine\Common\Cache availability if you keep the default nonce cache; and whether the bundle's custom-class config (authentication_provider_class, listener_class, entry_point_class, encoder_class) is actually needed or just noise for your deployment.
Sequencing (time-boxed spike, ~2–4 days).
lifetime; set lifetime explicitly (300s or tighter — never -1).Created rejected, tampered digest rejected, clock skew at both boundaries.Maintenance. You are the maintainer. Zero dependents and readme-level maturity mean no upstream cadence to rely on. Budget a standing line item: an annual (or PHP-minor-triggered) review of the vendored source, a pinned-version upgrade path, and a named owner for the fork. This is a small but permanent tax, and it should be visible in the roadmap, not discovered in an incident review.
Support. No vendor, no SLA. Security-sensitive code with no support channel requires an internal runbook: who to page, how to rotate partner credentials, how to disable the firewall quickly if a digest-handling flaw surfaces. Treat this as a security-reviewed adoption, not a routine dependency add.
Scaling. The nonce write is a per-request hot path. Statelessness means the app tier scales horizontally, but only if the nonce store is shared and fast — Redis, not local disk. There is no built-in rate limiting or abuse protection, so an unauthenticated flood still reaches the nonce store; put it behind your edge/API-gateway controls. Default PhpFileCache in %kernel.cache_dir% per node is the classic scaling trap: replay protection silently degrades to per-node, which is effectively no replay protection at all.
Failure modes to design for explicitly.
date_format/lifetime settings are the only knobs; align NTP and test at both window edges.lifetime: -1 (infinite tokens, offered by the bundle) — the README itself says "use with extreme care"; prohibit it by policy and code review.Ramp-up. Low protocol ramp — a mid-level engineer can be productive in a day, and the bundle's config surface is tiny. The non-obvious cost is the security reasoning: knowing why SHA1 is non-negotiable, why the nonce store must be shared and atomic, and what a replay actually looks like in a test. Assign that knowledge to one named engineer and capture it in the runbook; do not let it live only in a partner integration ticket.
Bottom line for the roadmap. Pursue this only as an enterprise/partner integration enabler, time-boxed, scoped to partner endpoints, and wrapped as owned code with an explicit fork plan. Do not let it become the product's authentication model, and do not carry a Symfony bundle into a Laravel stack — in that case, use it as the protocol reference and build the middleware.
How can I help you explore Laravel packages today?