jdr/jws-ecdsa
A PHP package for signing and verifying JSON Web Signatures (JWS) with ECDSA. It provides a straightforward API for generating compact JWS tokens and validating signatures in Laravel and other PHP applications, useful for secure token exchange and standards-based JWT/JWS workflows.
Architecture fit
jdr/jws-ecdsa is a narrow adapter, not a platform component. It contributes ECDSA (ES256/ES384/ES512) signer implementations to lcobucci/jwt's Signer abstraction — no service provider, no persistence, no transport layer. Architecturally it is a strategy object inside the token-signing boundary, which means it can be fully hidden behind an internal TokenSigner interface and treated as swappable implementation detail. That isolation is the single most important property from a product standpoint: it caps lock-in and makes the build-vs-adopt-vs-native decision reversible at near-zero cost.
Integration feasibility
Mechanically trivial — a Composer dependency plus a config/DI binding (e.g., a tymon/jwt-auth signer entry or a custom guard). The package is not where the effort lives. The real workstream is EC key lifecycle: generation, secure storage, rotation, kid propagation, and public-key distribution (JWKS) to every verifier. My estimate: ~0.5 engineer-day for the integration spike, and 1–3 engineer-weeks for key management, external interoperability testing, and security sign-off. Those should be separate tickets with separate owners; conflating them is how this lands as a schedule surprise.
Technical risk
lcobucci/jwt Signer contract and exception types changed materially across v3→v4→v5. A hard incompatibility is plausible and would end the evaluation.lcobucci/jwt v4+, native Lcobucci\JWT\Signer\Ecdsa\* classes exist. If that is our baseline, this package has no reason to exist in our stack.Key questions
lcobucci/jwt and Laravel versions are actually pinned, and does native ECDSA already satisfy the requirement? This is a one-command check and should gate everything else.lcobucci/jwt covers it and scope changes materially.Stack fit
Usable anywhere lcobucci/jwt is: auth guards, middleware, queue and CLI workers. Recommended pattern is to bind the signer and parsed key as container singletons so key material is not re-parsed per request, and to expose signing only through an internal interface so the concrete signer class never leaks into application code. Hard prerequisite: OpenSSL with EC support in every runtime — FPM, containers, CI, and workers. Minimal/Alpine images occasionally lack the curves, so verify with openssl_get_curve_names() early rather than discovering it in one pod.
Migration path Three branches, decide once and document:
Lcobucci\JWT\Signer\Ecdsa\* and close the ticket as "no action."Compatibility Pin exact versions of both packages. Run a small CI matrix over PHP 8.x, the chosen JWT major, and OpenSSL versions. Critically, validate against at least one external verifier — a second service or a standards-compliant library in another language. Self-verification proves nothing about encoding correctness.
Sequencing
lcobucci/jwt (gate: if present, stop).Each gate should have an owner and a written exit criterion; this is a decision record as much as an engineering task.
Maintenance Code surface is tiny, so if frozen the burden is near zero. The risk is the absence of upstream maintenance, not complexity. Mitigation: fork under organizational ownership, pin, subscribe to automated dependency alerts, and schedule a periodic review rather than assuming patches will arrive.
Support
No vendor SLA, no documentation beyond a README, no issue-triage commitment. We inherit 100% of incident ownership. Required before go-live: an internal runbook covering key generation, rotation, kid handling, and verification-failure triage, plus a named escalation team (platform/security).
Scaling ECDSA signing is CPU-cheap and yields smaller tokens than RSA; throughput and horizontal scaling are unaffected. The only real efficiency concern is per-request key parsing — cache the parsed key and signer. No capacity planning exercise is warranted.
Failure modes
Curve/hash mismatch; DER-vs-raw encoding rejected by strict JOSE verifiers; rotated or missing keys causing mass verification failure; kid missing or mismatched; OpenSSL EC absent in a subset of pods; silent algorithm downgrade if signer config is misread. Mitigations: CI round-trip tests against external verifiers, a startup self-check that signs and verifies a sample token, explicit algorithm allow-listing, and alerting on verification-error rate.
Ramp-up Low for anyone with JWT familiarity — roughly half a day to integrate and test. The dominant cost is key management and security review, not code. For stakeholders: low effort, low lock-in, contingent value. The capability is real and cheap, but it is an enabler on the identity roadmap, not a strategic dependency. Recommended position: pursue only if the native-support check fails and a named consumer requires ECDSA; otherwise close as evaluated-no-action.
How can I help you explore Laravel packages today?