---
title: "The Jwt facade — JWT for Laravel | Roundly"
description: "One entry point to mint, verify and log out, with Jwt::guard() and Jwt::services() handles, JWKS publishing and a recording fake."
url: https://roundly-consulting.com/open-source/docs/jwt-for-laravel/jwt-facade
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[JWT for Laravel](https://roundly-consulting.com/open-source/docs/jwt-for-laravel.md)

# The Jwt facade

The Jwt facade is the one obvious entry point. It is auto-registered as the global alias Jwt — or import RoundlyConsulting\\Jwt\\Facades\\Jwt:

```php
use RoundlyConsulting\Jwt\Facades\Jwt;
use RoundlyConsulting\Jwt\UserTokens\AccessTokenRequest;

// Mint an access token with a fluent, self-documenting request.
$issued = Jwt::mintAccessToken(
    AccessTokenRequest::for($user->id)
        ->email($user->email, verified: $user->hasVerifiedEmail())
        ->tokenVersion($user->token_version)
        ->permissions('posts.view', 'posts.edit')
);

$claims = Jwt::verify($issued->token);   // RS256 + iss/aud pinned
Jwt::logout($issued);                     // denylist it (one-call logout)
$current = Jwt::guard('api')->claims();   // current request's claims on that guard, or null
```

## The whole surface

```php
// User tokens (RS256), for the configured jwt.audience
Jwt::mintAccessToken($request);  Jwt::mint($sub, $scope, $ttl, $claims, $aud);
Jwt::mintChallengeToken($sub);   Jwt::mintEmailVerifyToken($sub, $email);
Jwt::verify($jwt, ?$aud);

// One jwt guard — its own audience, settings and current claims
Jwt::guard('clients')->mintAccessToken($request);   // aud = the guard's audience
Jwt::guard('clients')->mint($sub, $scope, $ttl, $claims);
Jwt::guard('clients')->verify($jwt);
Jwt::guard('clients')->claims();      // ?Claims of the current request on that guard
Jwt::guard('clients')->settings();    // JwtGuardSettings
Jwt::guard('clients')->audience();    // string

// Service tokens (HS256)
Jwt::services()->issue('billing', ['job' => 'sync']);
Jwt::services()->verify($jwt);
Jwt::services()->request('billing')->post(...);      // Http client with a fresh bearer
Jwt::services()->authenticate($pendingRequest, 'billing');
Jwt::services()->claims();            // ?Claims of the calling service (service-jwt guard)

// Denylist & logout
Jwt::denylist()->has($jti);  Jwt::denylist()->deny($jti, $until);  Jwt::denylist()->denyToken($issued);
Jwt::logout($issued);        Jwt::denyClaims($claims);

// Key publishing
Jwt::publicKey();   // RsaKey — the configured verification key
Jwt::jwks();        // ['keys' => [[kty, n, e, alg, use, kid?]]] — serve as /.well-known/jwks.json
```

| Method | Returns | Purpose |
| --- | --- | --- |
| `mintAccessToken(AccessTokenRequest $request)` | IssuedToken | Mint an access token from the fluent request, for the configured audience. |
| `mint($subject, $scope, $ttl, $extraClaims = [], $audience = null)` | IssuedToken | Mint any scope with an explicit TTL — a Scope case or a free string. The TTL is not bounded: 0 or below mints an already-expired token (0 still verifies within jwt.leeway). |
| `mintChallengeToken($subject, $extraClaims = [])` | IssuedToken | Mint a 2fa\_pending token using challenge\_ttl. |
| `mintEmailVerifyToken($subject, $email)` | IssuedToken | Mint an email\_verify token carrying the email, using verify\_ttl. |
| `verify($jwt, $audience = null)` | Claims | Verify an RS256 user token; dispatches TokenVerificationFailed and rethrows on failure. |
| `guard(string $name)` | GuardTokens | One jwt guard — mint, verify, claims, settings, audience. Throws JwtMisconfigured for a non-jwt guard. |
| `services()` | Services | HS256 service tokens — issue, verify, request, authenticate, claims. |
| `denylist()` | Denylist | The jti denylist store. |
| `logout(IssuedToken $token)` | void | Denylist a freshly issued token until its own expiry. |
| `denyClaims(Claims $claims)` | void | Denylist a token from its verified claims (jti + exp). |
| `publicKey()` | RsaKey | The configured verification key; KeyLoadFailed when none is configured. |
| `jwks()` | array | The RFC 7517 JWK Set of publicKey() — serve it as /.well-known/jwks.json. |
| `fake()` | JwtFake | Facade only: swap in the recording fake — see Testing. |

Every call routes to a container-bound contract resolved lazily, so a verify-only app with no private key can still resolve the facade, and host overrides and test doubles keep working.

## The guard handle

Jwt::guard($name) returns a GuardTokens handle scoped to one jwt guard’s settings. Its mints and verifies go through the manager, so TokenVerificationFailed fires and Jwt::fake() records them:

| Method | Returns | Purpose |
| --- | --- | --- |
| `mint($subject, $scope, $ttl, $extraClaims = [])` | IssuedToken | Mint any scope for the guard’s audience — the same unbounded TTL as Jwt::mint(): 0 or below mints an already-expired token. |
| `mintAccessToken(AccessTokenRequest $request)` | IssuedToken | Mint an access token for the guard’s audience; a request naming another audience throws JwtMisconfigured. |
| `verify(string $jwt)` | Claims | Verify against the guard’s audience — another guard’s token fails with ClaimMismatch. |
| `claims()` | ?Claims | The current request’s verified claims on this guard, or null. Never another guard’s. |
| `settings()` | JwtGuardSettings | The effective options the jwt driver builds the guard from. |
| `audience()` | string | auth.guards.<name>.audience, else jwt.audience. |

## The services handle

Jwt::services() returns a Services handle that resolves the ServiceTokenIssuer and ServiceTokenVerifier contracts on every call, so a host rebinding either is honoured — see Service tokens:

| Method | Returns | Purpose |
| --- | --- | --- |
| `issue(?string $audience = null, array $claims = [])` | IssuedToken | Issue a token; audience defaults to service.audience, registered claim names are rejected. |
| `verify(string $jwt)` | Claims | Verify an inbound token addressed to this service. |
| `request(?string $audience = null)` | PendingRequest | A new outbound request carrying a fresh token. |
| `authenticate(PendingRequest $request, ?string $audience = null)` | PendingRequest | Attach a fresh token to an existing outbound request. |
| `claims(?string $guard = null)` | ?Claims | The calling service’s verified claims on a service-jwt guard — the first with a caller, or exactly $guard. |

## Publishing the verification key

Services that verify your tokens can fetch the public key as a standard JWK Set. jwks() publishes jwt.public\_key\_path with alg RS256, use sig and — when JWT\_KID is set — the same kid the issuer writes into token headers:

```php
Route::get('/.well-known/jwks.json', fn () => response()->json(Jwt::jwks()));
```

## 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](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## 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.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/jwt-for-laravel.md)
