Getting started
This guide sets up Sésame in an AdonisJS 7 application with Node.js 24 or later and Lucid. Your application supplies user accounts, a login page, and a consent page.
For a Kysely application, install the Kysely store, then continue at Configure the server. For an existing installation, use the migration guides.
Configure browser authentication
Section titled “Configure browser authentication”If your application already has a session guard, keep it as the default. Otherwise, install Auth:
node ace add @adonisjs/auth --guard=sessionAuthorization and consent use the default guard to identify the logged-in user.
Install the package
Section titled “Install the package”With your Lucid database configured, run:
node ace add @julr/sesamenode ace migration:runThe installer adds the provider, commands, named scope middleware, config/sesame.ts, and six migrations. The database now contains clients, codes, tokens, grants, and pending requests.
Configure the server
Section titled “Configure the server”Validate APP_URL in start/env.ts and set it to the public URL of the authorization server. Use HTTPS in production. Do not use the frontend URL or a bind address such as 0.0.0.0.
Edit the generated config:
import env from '#start/env'import { defineConfig, stores } from '@julr/sesame'import type { InferScopes } from '@julr/sesame/types'
const sesameConfig = defineConfig({ issuer: env.get('APP_URL'), store: stores.lucid(), scopes: { read: 'Read access', write: 'Write access', }, defaultScopes: ['read'], loginPage: '/login', consentPage: '/oauth/consent',})
export default sesameConfig
declare module '@julr/sesame/types' { interface SesameScopes extends InferScopes<typeof sesameConfig> {}}For Kysely, keep your connection configuration instead of stores.lucid(). The module augmentation checks scope names in your middleware and guard calls.
The default grants are authorization code and refresh token. For lifetimes and other options, see the configuration reference.
Register the routes
Section titled “Register the routes”Mount OAuth endpoints under /oauth and discovery at the root:
import router from '@adonisjs/core/services/router'import sesame from '@julr/sesame/services/main'
router.group(() => { sesame.registerRoutes()}).prefix('/oauth')
sesame.registerDiscoveryRoutes()Keep the OAuth group accessible without a browser session. External clients call token, introspection, revocation, and registration endpoints directly.
If your application uses CSRF protection, exempt the endpoints called by external clients. Keep protection on browser consent submissions. To change the JWKS path, pass { jwksPath: '/.well-known/jwks.json' } to registerDiscoveryRoutes().
Verify discovery
Section titled “Verify discovery”With the application running, request:
curl http://localhost:3333/.well-known/oauth-authorization-serverThe JSON response contains your issuer and endpoint URLs. Confirm that they use the public issuer and /oauth prefix.
Complete the authorization flow
Section titled “Complete the authorization flow”- Create a client.
- Connect login and consent.
- Protect an API route.
- Authorize the client with PKCE and call that route.
For identity claims, enable OpenID Connect. For a service account, issue a client credentials token.