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

Jwt Authentication Bundle Laravel Package

php-istio/jwt-authentication-bundle

A Symfony bundle that authenticates requests using JWT tokens issued by Istio's request authentication policy, validating headers and claims so your PHP services can trust identity passed through the service mesh.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package — the repo is php-istio/jwt-authentication-bundle and v2.0.0 is a major bump whose headline change is Symfony 6 support. So the first step for a Laravel developer is deciding why you'd pull it in:

  1. You're running Laravel behind Istio with RequestAuthentication + AuthorizationPolicy, and you want in-app JWT validation (defense in depth, local testing without the sidecar, or per-route claims checks). In that case treat the bundle as a reference implementation of Istio JWT validation, not as a drop-in dependency.
  2. You're writing a Symfony service in the same mono-repo/platform as your Laravel apps. Then it's a normal composer require php-istio/jwt-authentication-bundle:^2.0 and register the bundle in config/bundles.php.

Minimal Laravel-side steps if you go the "reference implementation" route:

composer require php-istio/jwt-authentication-bundle:^2.0
  • Read the bundle's DependencyInjection/ extension class first — it's the authoritative list of config keys (issuer, audience, JWKS/public key source, header name).
  • Read the security authenticator/factory next — that's where the token is extracted from the request and validated.
  • First real use case: a JwtFromIstio middleware or a Laravel Guard that takes the bearer token, validates signature/iss/aud/exp, maps sub/custom claims to an Eloquent user, and rejects anything the sidecar should already have rejected (belt and braces).

If you're not on Istio, stop here — this package buys you nothing over firebase/php-jwt or lcobucci/jwt.

Implementation Patterns

Pattern 1 — Symfony app: install and configure the bundle. Register the bundle, then configure issuer/audience/keys in config/packages/istio_jwt_authentication.yaml (exact key names per the bundle's README — verify against Configuration.php, don't trust blog posts). Point the security.yaml firewall at the bundle's authenticator factory.

Pattern 2 — Laravel: borrow the validation core behind an interface. Wrap the bundle's token validator (or reimplement its checks) behind a small contract so your app code doesn't depend on Symfony's TokenInterface:

interface IstioTokenValidator {
    /** @throws InvalidToken */
    public function validate(string $rawToken): Claims;
}

Bind it in a service provider, then use it from middleware:

final class AuthenticateIstioJwt
{
    public function __construct(private IstioTokenValidator $validator) {}

    public function handle($request, Closure $next)
    {
        $claims = $this->validator->validate($request->bearerToken() ?? '');
        Auth::setUser(new IstioUser($claims->sub, $claims->all()));

        return $next($request);
    }
}

Pattern 3 — JWKS with caching. Istio's RequestAuthentication publishes keys at a JWKS endpoint. Don't fetch it per request. Cache the key set (Cache::remember, 10–60 min TTL, keyed by kid) and refresh on unknown kid once, then fail closed. Watch for clock skew: allow ~60s leeway on exp/nbf.

Pattern 4 — Claim-based authorization. Put your policy in the JWT, not in Laravel gates you have to keep in sync with Istio. Map a claim (e.g. groups or a custom roles) to Laravel's Gate::before so both layers agree.

Pattern 5 — Local development without a sidecar. Have a LocalJwtServiceProvider (or .env flag) that swaps in a dev key pair so php artisan serve works without Envoy. Keep the production binding strict — never allow unsigned tokens in production.

Integration tips.

  • Validate iss against the cluster-specific Istio issuer (https://kubernetes.default.svc.cluster.local by default), not a generic one.
  • Preserve the raw token if you call upstream services — don't mint a second token.
  • Log kid, iss, aud on failure, never the token itself.

Gotchas and Tips

  • It's not a Laravel package. There's no service provider, no publishable config, no config/*.php. Installing it pulls Symfony contracts (security-bundle, framework-bundle, http-foundation). Check composer why symfony/security-bundle after install — a stray Symfony security stack in a Laravel app is a real maintenance smell.
  • v2.0.0 is a major bump for a minor-sounding change. "Add support for Symfony 6" almost certainly means Symfony 6's PHP 8.1+ floor and dropped support for Symfony 4/5 in the same release. Pin ^2.0 deliberately and run your test suite on the PHP version you actually deploy. If you were on 1.1.x with Symfony 5, expect a hard stop.
  • The bundle was at 1.1.0 for a reason — it's small and single-maintainer. v2.0.0 lists one contributor's first PR. Budget for vendoring or wrapping the few hundred lines you actually need rather than depending on release cadence.
  • Don't let it make you lazy about the sidecar. Istio RequestAuthentication rejects invalid tokens at the mesh edge; the app-layer check exists to catch misconfigured AuthorizationPolicy and direct-to-pod traffic. Test that a request bypassing Envoy is still rejected.
  • Config quirks to verify against source, not docs: key resolution (inline PEM vs file vs JWKS URL), algorithm allow-list (reject none and HMAC-vs-RSA confusion explicitly), and whether the audience check is exact-match or subset.
  • Debugging: decode the token payload first (base64url split) before blaming the validator. A 401 with a valid-looking token is usually iss mismatch (trailing slash!), clock skew, or a kid cache miss.
  • Extension points that survive a version bump: your own IstioTokenValidator adapter and the claim→user mapping. Everything Symfony-flavoured (TokenInterface, firewall config) is what v2.0.0 may have changed — keep that surface thin.
  • Fallback plan: if the Symfony coupling becomes painful, lcobucci/jwt + a JWKS cache gives you the same guarantees in ~80 lines with no framework baggage. Given the size of this bundle, that's a legitimate choice, not a cop-out.
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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route