| title | Authentication setup | |||||
|---|---|---|---|---|---|---|
| description | Set up user authentication for your documentation site with OAuth, JWT, or shared links to control access to pages and API references. | |||||
| keywords |
|
Enterprise plans include all authentication methods.
Authentication is only available for documentation hosted on a custom domain or Mintlify subdomain (for example, `docs.example.com` or `example.mintlify.cc`). Authentication is **not supported** when using a [custom basepath](/deploy/docs-subpath) (for example, `example.com/docs`).Authentication requires users to log in before accessing your documentation.
When you enable authentication, users must log in to access any content. You can configure specific pages or groups as public while keeping other pages protected.
Select the handshake method that you want to configure.
Password authentication provides access control only and does **not** support user-specific features like group-based access control or API playground pre-filling.- Your security requirements allow sharing passwords among users.
After you enter a password, your site redeploys. When it finishes deploying, anyone who visits your site must enter the password to access your content.
You host your documentation at docs.foo.com and you need basic access control without tracking individual users. You want to prevent public access while keeping setup simple.
Create a strong password in your dashboard. Share credentials with authorized users.
- Everyone who needs to access your documentation must be a member of your Mintlify organization.
After you enable Mintlify authentication, your site redeploys. When it finishes deploying, anyone who visits your site must log in to your Mintlify organization to access your content.
You host your documentation at docs.foo.com and your entire team has access to your dashboard. You want to restrict access to team members only.
Enable Mintlify authentication in your dashboard settings.
Verify team access by checking that all team members are active in your organization.
- An OAuth or OIDC server that supports the Authorization Code Flow.
- Ability to create an API endpoint accessible by OAuth access tokens (optional, to enable group-based access control).
After you configure your OAuth settings, your site redeploys. When it finishes deploying, anyone who visits your site must log in to your OAuth provider to access your content.
Mintlify calls this endpoint with the OAuth access token to retrieve user information. No additional query parameters are sent.
Add this endpoint URL to the **Info API URL** field in your [authentication settings](https://dashboard.mintlify.com/products/authentication).
You host your documentation at foo.com/docs and you have an existing OAuth server at auth.foo.com that supports the Authorization Code Flow.
Configure your OAuth server details in your dashboard:
- Authorization URL:
https://auth.foo.com/authorization - Client ID:
ydybo4SD8PR73vzWWd6S0ObH - Scopes:
['provider.users.docs'] - Token URL:
https://auth.foo.com/exchange - Info API URL:
https://api.foo.com/docs/user-info - Logout URL:
https://auth.foo.com/logout?returnTo=https%3A%2F%2Ffoo.com%2Fdocs
Create a user info endpoint at api.foo.com/docs/user-info, which requires an OAuth access token with the provider.users.docs scope, and returns:
{
"groups": ["engineering", "admin"],
"expiresAt": 1735689600,
"apiPlaygroundInputs": {
"header": {
"Authorization": "Bearer user_abc123"
}
}
}Configure your OAuth server to allow redirects to your callback URL.
- An authentication system that can generate and sign JWTs.
- A backend service that can create redirect URLs.
After you generate a private key, your site redeploys. When it finishes deploying, anyone who visits your site must log in to your JWT authentication system to access your content.
* Create a JWT containing the authenticated user's info in the `User` format. See [User data format](#user-data-format) for more information.
* Sign the JWT with your secret key, using the EdDSA algorithm.
* Create a redirect URL back to the `/login/jwt-callback` path of your docs, including the JWT as the hash.
You host your documentation at docs.foo.com with an existing authentication system at foo.com. You want to extend your login flow to grant access to the docs while keeping your docs separate from your dashboard (or you don't have a dashboard).
Create a login endpoint at https://foo.com/docs-login that extends your existing authentication.
After verifying user credentials:
- Generate a JWT with user data in Mintlify's format.
- Sign the JWT and redirect to
https://docs.foo.com/login/jwt-callback#{SIGNED_JWT}.
const TWO_WEEKS_IN_MS = 1000 * 60 * 60 * 24 * 7 * 2; const DOCS_HOST = 'docs.example.com';
const signingKey = await jose.importPKCS8(process.env.MINTLIFY_PRIVATE_KEY, 'EdDSA');
export async function handleRequest(req: Request, res: Response) {
const user = {
host: DOCS_HOST, // Must match your docs URL
expiresAt: Math.floor((Date.now() + TWO_WEEKS_IN_MS) / 1000), // 2 week session expiration
groups: res.locals.user.groups,
apiPlaygroundInputs: {
header: {
"Authorization": Bearer ${res.locals.user.apiKey},
},
},
};
const jwt = await new jose.SignJWT(user) .setProtectedHeader({ alg: 'EdDSA' }) .setExpirationTime('10 s') // 10 second JWT expiration .sign(signingKey);
return res.redirect(https://${DOCS_HOST}/login/jwt-callback#${jwt});
}
```python Python
import jwt # pyjwt
import os
from datetime import datetime, timedelta
from fastapi.responses import RedirectResponse
private_key = os.getenv(MINTLIFY_JWT_PEM_SECRET_NAME, '')
DOCS_HOST = 'docs.example.com'
@router.get('/auth')
async def return_mintlify_auth_status(current_user):
jwt_token = jwt.encode(
payload={
'host': DOCS_HOST, # Must match your docs URL
'exp': int((datetime.now() + timedelta(seconds=10)).timestamp()), # 10 second JWT expiration
'expiresAt': int((datetime.now() + timedelta(weeks=2)).timestamp()), # 2 week session expiration
'groups': ['admin'] if current_user.is_admin else [],
'apiPlaygroundInputs': {
'header': {
'Authorization': f'Bearer {current_user.api_key}',
},
},
},
key=private_key,
algorithm='EdDSA'
)
return RedirectResponse(url=f'https://{DOCS_HOST}/login/jwt-callback#{jwt_token}', status_code=302)
When an unauthenticated user tries to access a protected page, the redirect to your login URL preserves the user's intended destination.
- User attempts to visit a protected page:
https://docs.foo.com/quickstart. - Redirect to your login URL with a redirect query parameter:
https://foo.com/docs-login?redirect=%2Fquickstart. - After authentication, redirect to
https://docs.foo.com/login/jwt-callback?redirect=%2Fquickstart#{SIGNED_JWT}. - User lands in their original destination.
When using authentication, all pages require authentication to access by default. You can make specific pages viewable without authentication at the page or group level with the public property.
To make a page public, add public: true to the page's frontmatter.
---
title: "Public page"
public: true
---To make all pages in a group public, add "public": true beneath the group's name in the navigation object of your docs.json.
{
"navigation": {
"groups": [
{
"group": "Public group",
"public": true,
"icon": "play",
"pages": [
"quickstart",
"installation",
"settings"
]
},
{
"group": "Private group",
"icon": "pause",
"pages": [
"private-information",
"secret-settings"
]
}
]
}
}When you use OAuth or JWT authentication, you can restrict specific pages to certain user groups. This is useful when you want different users to see different content based on their role or attributes.
Manage groups through user data passed during authentication. See User data format for details.
{
"groups": ["admin", "beta-users"],
"expiresAt": 1735689600
}Specify which groups can access specific pages using the groups property in frontmatter.
---
title: "Admin dashboard"
groups: ["admin"]
---Users must belong to at least one of the listed groups to access the page. If a user tries to access a page without the required group, they'll receive a 404 error.
- All pages require authentication by default.
- Pages with a
groupsproperty are only accessible to authenticated users in those groups. - Pages without a
groupsproperty are accessible to all authenticated users. - Pages with
public: trueand nogroupsproperty are accessible to everyone.
---
title: "Public guide"
public: true
------
title: "API reference"
------
title: "Advanced configurations"
groups: ["pro", "enterprise"]
---When using OAuth or JWT authentication, your system returns user data that controls session length, group membership, and content personalization.
```tsx Format type User = { host?: string; expiresAt?: number; groups?: string[]; content?: Record; apiPlaygroundInputs?: { server?: Record; header?: Record; query?: Record; cookie?: Record; path?: Record; }; }; ```{
"host": "docs.example.com",
"expiresAt": 1735689600,
"groups": ["admin", "beta-users"],
"content": {
"firstName": "Jane",
"company": "Acme Corp"
},
"apiPlaygroundInputs": {
"header": {
"Authorization": "Bearer user_abc123"
},
"server": {
"baseUrl": "https://api.foo.com"
}
}
}For JWT: This differs from the JWT's exp claim, which determines when a JWT is considered invalid. Set the JWT exp claim to a short duration (10 seconds or less) for security. Use expiresAt for the actual session length (hours to weeks).
Example: A user with groups: ["admin", "engineering"] can access pages tagged with either the admin or engineering groups.
Only values that match the current endpoint's security scheme are applied.
Header values to pre-fill, keyed by header name. Query parameter values to pre-fill, keyed by parameter name. Cookie values to pre-fill, keyed by cookie name. Server variable values to pre-fill, keyed by variable name. Path parameter values to pre-fill, keyed by parameter name.Some features behave differently or are unavailable when you enable authentication. Mintlify does not support serving arbitrary files publicly on an authenticated site. All hosted files, including llms.txt, llms-full.txt, and skill.md, are subject to the same authentication requirements as your documentation pages.
| Feature | Public | Fully authenticated (all pages protected) | Partially authenticated (some public pages) |
|---|---|---|---|
| llms.txt and llms-full.txt | Full support | Available behind authentication, so AI tools may not be able to access the files | Available behind authentication, so AI tools may not be able to access the files |
| MCP server | Full support | Requires authentication to connect | Available without authentication for public pages and with authentication for protected pages |
| Markdown export | Full support | Full support, respects user groups | Full support, respects user groups |
| PDF export | Full support | Not supported | Not supported |
| Search | Full support | Full support, respects user groups | Full support, respects user groups |
| Assistant | Full support | Full support, respects user groups | Full support, respects user groups |
| skill.md | Full support | Not supported | Not supported |
| Sitemap | Full support | Available behind authentication, but excludes pages in groups | Available behind authentication, but excludes pages in groups |
| robots.txt | Full support | Available behind authentication | Available behind authentication |