Access ControlJWT
Access Control

JWT Authentication

Authenticate users with JSON Web Tokens and control access with roles.

JWT authentication is available on Enterprise plans or higher.

Authenticate users with JSON Web Tokens (JWT) signed with Ed25519 (EdDSA). This method integrates your documentation with your existing authentication system and supports per-user role-based access control and personalization.

Prerequisites

  • An Enterprise plan or higher
  • An authentication system that can generate and sign JWTs
  • A backend service that can create redirect URLs back to your docs

Set up

Select JWT in the dashboard

In your dashboard, go to Settings > Access Control, select Private, then choose JWT as the authentication method.

Generate a signing key

Click Generate signing key in the dashboard. This creates an Ed25519 keypair:

  • The public key is stored by Documentation.AI and used to verify incoming JWTs.
  • The private key is shown once for you to download. Store it securely where your backend can access it.

The private key is only shown once. Download it immediately and store it securely. If you lose it, generate a new keypair using the Regenerate button.

Configure login URL

Enter the URL of your existing login page. When an unauthenticated user visits your docs, they are redirected to this URL.

Configure optional settings

  • Issuer: Expected iss claim in the JWT. If set, tokens with a different issuer are rejected.
  • Audience: Expected aud claim in the JWT. Typically your docs domain.
  • Session duration: How long a user stays authenticated after signing in (default: 14 days).

Copy the callback URL

Copy the Callback URL shown in the dashboard. You will redirect users to this URL after they authenticate.

Save and re-publish

Save your settings and re-publish your documentation.

Integrate with your backend

After a user successfully authenticates in your system:

1. Create the JWT

Build a JWT with the following claims:

{
  "host": "docs.example.com",
  "firstname": "Alice",
  "company": "Acme Inc",
  "accessRoles": ["engineering", "sre"],
  "iat": 1743523200,
  "exp": 1743523230
}
ClaimRequiredDescription
hostNoThe docs site hostname (for personalization)
firstnameNoUser's first name (for personalization)
companyNoUser's company name (for personalization)
accessRolesNoArray of role strings for role-based access control. Omit if not using scoped access. Use ["*"] for full access.
iatYesIssued-at timestamp (standard JWT claim)
expYesExpiration timestamp. Keep this short (30 seconds recommended) since this is a handshake token, not the session.

If you set Issuer or Audience in the dashboard, include matching iss and aud claims.

2. Sign the JWT

Sign the JWT using the Ed25519 (EdDSA) algorithm with the private key you downloaded during setup.

import { SignJWT, importPKCS8 } from 'jose';

const privateKey = await importPKCS8(privateKeyPem, 'EdDSA');

const jwt = await new SignJWT({
  host: 'docs.example.com',
  firstname: 'Alice',
  company: 'Acme Inc',
  accessRoles: ['engineering', 'sre'],
})
  .setProtectedHeader({ alg: 'EdDSA' })
  .setIssuedAt()
  .setExpirationTime('30s')
  .sign(privateKey);

3. Redirect to the callback URL

Redirect the user to the callback URL shown in your dashboard, passing the signed JWT as the token parameter:

https://docs.example.com/api/auth/jwt/callback?token=eyJ...&redirect=/getting-started

The optional redirect parameter preserves the user's intended destination. If omitted, the user lands on the docs homepage.

Authentication flow

Key rotation

To rotate the signing key, click Regenerate in the dashboard. This generates a new keypair:

  • Download the new private key and deploy it to your backend.
  • The old private key's tokens will fail verification immediately.
  • Active sessions (cookie-based) remain valid until they expire.

Rotate keys during scheduled maintenance or incident response.

Example

You host docs at docs.example.com and your company login is https://login.example.com. Configure JWT authentication so users sign in with your existing identity system, then return to the docs site with a signed token.