NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
JWT for Laravel

Installation

Require the package and publish the config. The service provider and the Jwt facade alias are auto-discovered — no manual registration:

composer require roundly-consulting/jwt-for-laravel

php artisan vendor:publish --tag="jwt-config"

jwt-config is the only publish tag — there are no migrations, views or routes. The provider binds every contract to its native implementation, registers the jwt and service-jwt guard drivers and adds the jwt:generate-keys command.

Issuer apps

An issuer app mints user tokens, so it holds the RSA private key. Set the pins, then generate a 2048-bit keypair:

# Pinned into and checked on every user token.
JWT_ISSUER=auth
JWT_AUDIENCE=web

# Optional: the key paths default to storage/jwt-private.key and storage/jwt-public.pem.
# Relative paths resolve from the application root.
# JWT_PRIVATE_KEY_PATH=storage/jwt-private.key
# JWT_PUBLIC_KEY_PATH=storage/jwt-public.pem
php artisan jwt:generate-keys

With no JWT_* key paths set, it writes the private key to storage/jwt-private.key (mode 0600) and the public key to storage/jwt-public.pem — exactly where the config reads them. A stock Laravel .gitignore already excludes /storage/*.key; if you point JWT_PRIVATE_KEY_PATH elsewhere, keep that file out of version control yourself. Relative paths resolve against the application root.

Verify-only apps

Every other service only verifies. Copy the issuer’s public key to JWT_PUBLIC_KEY_PATH (default storage/jwt-public.pem) — no private key is needed, because only minting reads it, so the private key never leaves the issuer:

JWT_ISSUER=auth
JWT_AUDIENCE=web

# No private key. Copy the issuer's public key here.
JWT_PUBLIC_KEY_PATH=storage/jwt-public.pem

JWT_ISSUER and JWT_AUDIENCE are required on both sides. A value that is not set (null or blank) throws JwtMisconfigured as soon as the issuer or verifier is resolved, so an unset pin can never match vacuously.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.