Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Jose Verifier Laravel Package

facile-it/php-jose-verifier

A lightweight PHP library for validating JWT tokens from OpenID and OAuth2 providers. It builds verifiers and decrypters automatically from issuer and client metadata, fetching public keys from a jwks_uri endpoint, with optional GMP support for better performance.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

facile-it/php-jose-verifier is a framework-agnostic PHP library — no service provider, no facade, no config file, no Laravel contracts. It occupies a specific niche in a Laravel stack: relying-party / resource-server verification of JWTs issued by an external OIDC provider (Keycloak, Auth0, Okta, Entra ID, Cognito). It complements rather than competes with Laravel Passport (which issues its own tokens) and tymon/jwt-auth (self-issued, self-verified tokens). If our product consumes tokens minted by a third-party IdP, this library is a strong fit; if we mint and verify our own tokens, it is the wrong tool.

The API surface is small and stable in shape: three builder/verifier pairs (AccessToken, IdToken, UserInfo), each created from issuer metadata (issuer, jwks_uri) plus client metadata (client_id, optional client_secret, response algorithms). That maps cleanly onto a config/oidc.php file and container singletons — one verifier instance per configured issuer. Builders and verifiers are immutable, which is a genuine architectural asset for Octane/Swoole workers where shared mutable state is a correctness hazard.

Integration feasibility

Feasible with roughly 1–2 days of engineering for a production-quality wrapper — not turnkey, but not a project. Three concrete friction points:

  1. No Laravel glue ships with the package. We own the service provider, config schema, exception-to-HTTP mapping, and middleware. This is expected for a PHP library and is manageable; it just needs to be scoped and owned rather than discovered mid-sprint.
  2. PSR-16 cache mismatch. JWKS caching requires Psr\SimpleCache\CacheInterface, which Laravel's Cache facade does not implement. Without an adapter (Symfony cache bridge or ~50 lines of custom code), every request refetches the remote JWKS — a latency and availability problem, since it puts the IdP's JWKS endpoint on the critical path of every authenticated request.
  3. PSR-18/HTTP discovery. Remote JWKS fetching goes through a PSR-18 client, not Laravel's Http facade. We either bind Guzzle explicitly or add an adapter, and we lose Laravel's HTTP middleware (retries, structured logging, telemetry) unless we wrap the client. Worth deciding deliberately before the first PR.

Technical risk

  • Adoption risk — highest. 5 stars, 0 dependents, single-vendor stewardship (Facile.it). Effective bus-factor of one. This is not grounds for rejection, but it should be an explicit line item in the risk register with a documented "vendor or fork" contingency.
  • Pre-1.0 versioning. Current line is 0.5.x. The 0.4 → 0.5 transition was breaking in practice: builders moved namespace, deprecated web-token/* packages were replaced, JWE compression support was dropped. Under 0.x semver, minor bumps may break us. Pin an exact version and treat upgrades as change-managed work with a test pass, not as composer update background noise.
  • Transitive crypto surface. All real cryptographic work is delegated to web-token/jwt-library. Most future CVEs will land there, not here. Our dependency scanning and patch cadence must target that subtree, and the 1.0.0 upgrade to jwt-library 4.x carries its own documented breaking changes.
  • Capability gaps are real, not cosmetic. No token revocation, no introspection endpoint support, no opaque-token handling. Any requirement for immediate invalidation must be met with short token lifetimes, a local deny-list, or an added introspection call — design around it up front rather than retrofitting it.
  • Performance dependency on ext-gmp. README explicitly recommends it; without it, RSA verification takes a slower path. This is a deployment-image checklist item, and it silently degrades rather than failing loudly — so it needs a health check or build-time assertion.

Key questions

  • Which IdP(s) are in scope, and is a single issuer sufficient for the first release?
  • Do we need id_token validation only, or also access_token and signed/encrypted UserInfo responses?
  • What is our token revocation requirement, and can short TTLs satisfy it?
  • Who owns the wrapper code and the upgrade cadence — is this a platform-team responsibility or the consuming feature team's?
  • Do we accept the bus-factor-1 risk, or do we vendor the package into our monorepo at adoption time?

Integration Approach

Stack fit

The library sits at the authentication boundary of the Laravel app and nothing else. Recommended shape:

  • One config file (config/oidc.php) holding issuer metadata and client metadata per named issuer, sourced from environment variables. Keep client_secret out of the repo and out of the config cache where possible.
  • One service provider that builds and binds verifiers as container singletons, keyed by issuer name, with the PSR-18 client and PSR-16 cache adapter injected.
  • One middleware (or a custom Guard) that extracts the bearer token, resolves the correct verifier, calls verify(), and translates InvalidTokenExceptionInterface into a 401 with a non-leaky error body.
  • One adapter pair: PSR-16 over the Laravel cache store, and a PSR-18 client (Guzzle is the path of least resistance) with retry and timeout configured.

Resist the urge to expose the verifiers directly to controllers. A thin domain-level "authenticated principal" type returned by our own service keeps the library swappable.

Migration path

Greenfield consumption is straightforward: add the dependency, write the wrapper, wire middleware, ship. For teams already using tymon/jwt-auth or Passport for external tokens, migration is not a drop-in — the libraries differ in what they validate (this one validates against remote JWKS and issuer metadata; those validate against a local secret). The realistic migration is: run both implementations in parallel behind a feature flag, shadow-verify a sample of real traffic through the new path, compare accept/reject decisions, then cut over. Budget for this if it is a replacement rather than an addition.

Compatibility

  • PHP: 8.2+ (0.5.x dropped <8.1; 1.0.0 dropped 8.1). Verify against our actual runtime matrix, including any legacy services still on 8.1.
  • Laravel: no declared constraint — it is framework-agnostic, so it will install anywhere, but that also means no framework guarantees.
  • Extensions: ext-gmp should be a hard requirement in composer.json at the app level, not a soft README recommendation.
  • Dependencies: pin facile-it/php-jose-verifier exactly and let web-token/jwt-library float within a constrained range, or pin both. Choose deliberately — pinning both maximizes reproducibility but slows security patching.

Sequencing

  1. Spike: install, wire a bare-bones verifier against a real IdP sandbox, confirm signature verification and JWKS fetch work end-to-end. Half a day.
  2. Build the wrapper: config, service provider, PSR-16 adapter, PSR-18 client, middleware, exception mapping.
  3. Add ext-gmp to all runtime images and CI.
  4. Instrument: log verification failures by reason (expired, bad signature, wrong issuer, wrong audience) — this data is essential for tuning and for incident response.
  5. Roll out behind a flag on a low-traffic surface, then expand.
  6. Document the upgrade runbook and the fork contingency.

Operational Impact

Maintenance

Steady-state maintenance is low but non-zero, and it is not zero because of the package's own code — it is low because the package's code is small. The real maintenance load is: (a) tracking web-token/jwt-library releases and CVEs, (b) absorbing occasional breaking changes on 0.x minor bumps, and (c) maintaining our own wrapper. Assign a named owner. A package with 5 stars and 0 dependents that nobody owns is a package that quietly rots.

Set a review cadence — quarterly is reasonable — and subscribe to GitHub security advisories for both this package and web-token/jwt-library. A composer audit gate in CI is the minimum bar.

Support

There is no commercial support. Upstream responsiveness is unknown and unguaranteed. Our practical support model is: we can read the source (it is small and well-structured), and we can fork it. For a security-critical path, the fork option needs to be plausible rather than theoretical — meaning at least one engineer on the team has read the verification flow and could debug it. If nobody can do that, the risk profile changes materially.

Scaling

The library itself is stateless and CPU-bound; it scales horizontally with the app tier. Two operational dependencies govern real-world scaling:

  • JWKS caching is mandatory, not optional. With the PSR-16 adapter and the default 86400s TTL, remote fetches are rare. Without it, every authenticated request hits the IdP — unacceptable latency, and it makes the IdP a hard dependency for our availability.
  • ext-gmp is a throughput lever. With it, RSA verification is fast enough to be a rounding error; without it, high-RPS services will notice. Validate under expected load before committing.

Consider caching verification results per-token (keyed by token hash) within the token's remaining lifetime if a single token is verified repeatedly on hot paths — the library does not do this for you.

Failure modes

  • JWKS endpoint unavailable. With a cold cache, all verification fails and the app is down for authenticated traffic. Mitigation: warm the cache on deploy, serve stale on fetch failure, and alert on cache miss rate rather than only on error rate.
  • IdP key rotation. Handled transparently by refetching, but only if caching is configured to refresh on unknown kid rather than blindly serving the cached set. Verify this behavior explicitly — it is the single most common production surprise in JWKS-based verification.
  • Clock skew. Token nbf/exp validation is skew-sensitive. Ensure hosts are NTP-synced; a few seconds of drift produces sporadic, hard-to-reproduce 401s.
  • Silent crypto degradation. Missing ext-gmp or a misconfigured algorithm allow-list fails open or fails obscurely depending on configuration. Assert the algorithm allow-list explicitly rather than accepting whatever the token header claims — this is the classic JWT alg: none / algorithm-confusion class of bug.
  • Upstream breaking change. A minor bump breaks a namespace or dependency contract; without pinned versions and an integration test, this surfaces in production.
  • Exception leakage. Overly verbose error mapping exposes whether a token was expired vs. forged vs. wrong-issuer. Log detail internally, return uniform 401s externally.

Ramp-up

For a Laravel engineer familiar with OIDC concepts, the library is a half-day read (the README is good, the API is four classes). The longer ramp is on the domain: JWKS, key rotation, at_hash/c_hash validation, auth_time and require_auth_time, signed vs. encrypted UserInfo, and the algorithm allow-list. Budget 2–3 days for an engineer to be genuinely productive, most of it spent on OIDC semantics rather than on this package's API. The absence of first-party Laravel documentation means our wrapper's docs become the team's reference — write them as part of the integration, not after.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk