---
title: "Configuration"
description: "Register the JWT guard and configure algorithms, storage, transports, and revocation."
image: "https://adonisjs-jwt.pages.dev/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://adonisjs-jwt.pages.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

## Register `config/auth.ts`

The configure hook exports an initialized key set and refresh store from `config/jwt.ts`. Use this
exact guard registration:

```ts
import { defineConfig } from '@adonisjs/auth'
import { jwtGuard } from '@rikology/adonisjs-jwt'
import { lucidJwtUserProvider } from '@rikology/adonisjs-jwt/providers'
import jwtConfig, { jwtKeySet, jwtRefreshTokenStore } from '#config/jwt'

const authConfig = defineConfig({
  default: 'jwt',
  guards: {
jwt: jwtGuard({
  provider: lucidJwtUserProvider({ model: () => import('#models/user') }),
  keySet: jwtKeySet,
  refreshStore: jwtRefreshTokenStore,
  config: jwtConfig,
}),
  },
})

export default authConfig
```

Protect routes with `middleware.auth({ guards: ['jwt'] })`. Authenticated requests expose the
validated access claims as `ctx.jwtClaims`.

## Generated `config/jwt.ts`

The default is Ed25519, 10-minute access tokens, 30-day non-sliding refresh tokens, bearer
transport, and a public JWKS route:

```ts
const jwtConfig = defineJwtConfig({
  issuer: env.get('JWT_ISSUER'),
  audience: env.get('JWT_AUDIENCE'),
  access: {
algorithm: 'EdDSA',
expiresIn: '10m',
clockTolerance: '30s',
  },
  refresh: {
expiresIn: '30d',
sliding: false,
reuseGraceMs: 2_000,
table: 'jwt_refresh_tokens',
prefix: 'rt_',
tokenSecretLength: 40,
  },
  keys: keyDrivers.env({ privateKeyPem, publicKeyPem, kid: env.get('JWT_KID') }),
  jwks: {
enabled: true,
route: '/.well-known/jwks.json',
cacheMaxAge: 3_600,
  },
  transport: transports.bearer(),
  denylist: { enabled: false },
})
```

Durations accept seconds, minutes, hours, days, weeks, and years, including decimals such as
`1.5h`. Set clock tolerance only high enough for measured clock skew.

## Algorithms and key drivers

| Mode | Configuration | Signing | JWKS output |
| --- | --- | --- | --- |
| EdDSA / ES256 / PS256 / RS256 | `keyDrivers.env({ privateKeyPem, publicKeyPem, kid })` | Yes | Public key |
| HS256 | `keyDrivers.env({ secret, kid })` | Yes | Empty; symmetric secrets are never published |
| Encrypted database | `keyDrivers.database({ table })` | Yes | Active and overlapping public keys |
| External identity provider | `keyDrivers.remoteJwks({ url, ...cacheOptions })` | No | Cached public remote keys |

HS256 secrets must contain at least 32 bytes and must be generated independently from `APP_KEY`.
Remote JWKS mode is verification-only: `login` and token issuance intentionally fail.

## Transport

Bearer mode reads only a strict `Authorization: Bearer <token>` header. Cookie mode is for
first-party browser clients and requires the CSRF contract documented in [Browser cookies and
CSRF](/browser-cookies/).

## Optional immediate revocation

Without a denylist, logout stops renewal while an access JWT remains valid until its short expiry.
Pass `MemoryDenylist` for one-process development or `CacheDenylist` with a shared Adonis Cache
backend in production. Entries contain only the `jti` and expire with the token.

Source: https://adonisjs-jwt.pages.dev/configuration/index.mdx
