-
Notifications
You must be signed in to change notification settings - Fork 207
Update authentication and personalization docs #761
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
e4b7f52
rename "authentication vs personalization"
ethanpalm d1fb5a7
Combine information into overview
ethanpalm 9e30b15
move files & configure redirects
ethanpalm a7a772c
update page titles and docs.json
ethanpalm 2d25e49
add JWT info to auth setup
ethanpalm f9ff80a
add OAuth info
ethanpalm e24acbe
add mintlify auth info
ethanpalm 9f42250
add password info
ethanpalm 24ce1d9
delete individual auth pages; configure redirects
ethanpalm ae6a958
Update sending-data.mdx
ethanpalm b954de7
remove redundant info
ethanpalm 8738911
add JWT personalization info
ethanpalm acd83f4
add shared session info
ethanpalm db30ff4
delete individual personalization pages, add redirects
ethanpalm 56fedca
Update partial-authentication-setup.mdx
ethanpalm 9a5c968
fix broken links
ethanpalm 4a25bed
overview copyedits
ethanpalm d6df618
setup copyedits
ethanpalm 82d4331
copyedit sending data
ethanpalm 8eec89d
clarify hidden page language
ethanpalm bbbc67c
add reviewer feedback ✨
ethanpalm f316d7e
Merge branch 'main' into auth-and-personalization
ethanpalm 6c970c1
emphasize hidden pages are not restricted
ethanpalm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
240 changes: 240 additions & 0 deletions
240
authentication-personalization/authentication-setup.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,240 @@ | ||
| --- | ||
| title: "Authentication Setup" | ||
| description: "Guarantee privacy of your docs by authenticating users" | ||
| icon: "file-lock" | ||
| --- | ||
| Authentication requires users to log in before accessing your documentation. This guide covers setup for each available handshake method. | ||
|
|
||
| **Need help choosing?** See the [overview](/authentication-personalization/overview) to compare options. | ||
|
|
||
| <Info> | ||
| Authentication methods are available on the [Growth and Enterprise plans](https://mintlify.com/pricing?ref=authentication). Please{" "} | ||
| <a href="mailto:[email protected]">contact sales</a> for more information. | ||
| </Info> | ||
|
|
||
| ## Configuring authentication | ||
|
|
||
| Select the handshake method that you want to configure. | ||
|
|
||
| <Tabs> | ||
| <Tab title="JWT"> | ||
| ### Prerequisites | ||
|
|
||
| * An authentication system that can generate and sign JWTs. | ||
| * A backend service that can create redirect URLs. | ||
|
|
||
| ### Implementation | ||
|
|
||
| <Steps> | ||
| <Step title="Generate a private key."> | ||
| 1. In your dashboard, go to [Authentication](https://dashboard.mintlify.com/settings/deployment/authentication). | ||
| 2. Select **Full Authentication** or **Partial Authentication**. | ||
| 3. Select **JWT**. | ||
| 4. Enter the URL of your existing login flow and select **Save changes**. | ||
| 5. Select **Generate new key**. | ||
| 6. Store your key securely where it can be accessed by your backend. | ||
| </Step> | ||
| <Step title="Integrate Mintlify authentication into your login flow."> | ||
| Modify your existing login flow to include these steps after user authentication: | ||
|
|
||
| * Create a JWT containing the authenticated user's info in the `User` format. See [Sending Data](/authentication-personalization/sending-data) 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. | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| ### Example | ||
|
|
||
| Your documentation is hosted 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}`. | ||
|
|
||
| <CodeGroup> | ||
| ```ts TypeScript | ||
| import * as jose from 'jose'; | ||
| import { Request, Response } from 'express'; | ||
|
|
||
| const TWO_WEEKS_IN_MS = 1000 * 60 * 60 * 24 * 7 * 2; | ||
|
|
||
| const signingKey = await jose.importPKCS8(process.env.MINTLIFY_PRIVATE_KEY, 'EdDSA'); | ||
|
|
||
| export async function handleRequest(req: Request, res: Response) { | ||
| const user = { | ||
| expiresAt: Math.floor((Date.now() + TWO_WEEKS_IN_MS) / 1000), // 2 week session expiration | ||
| groups: res.locals.user.groups, | ||
| content: { | ||
| firstName: res.locals.user.firstName, | ||
| lastName: res.locals.user.lastName, | ||
| }, | ||
| }; | ||
|
|
||
| const jwt = await new jose.SignJWT(user) | ||
| .setProtectedHeader({ alg: 'EdDSA' }) | ||
| .setExpirationTime('10 s') // 10 second JWT expiration | ||
| .sign(signingKey); | ||
|
|
||
| return res.redirect(`https://docs.foo.com/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, '') | ||
|
|
||
| @router.get('/auth') | ||
| async def return_mintlify_auth_status(current_user): | ||
| jwt_token = jwt.encode( | ||
| payload={ | ||
| 'exp': int((datetime.now() + timedelta(seconds=10)).timestamp()), # 10 second JWT expiration | ||
| 'expiresAt': int((datetime.now() + timedelta(weeks=2)).timestamp()), # 1 week session expiration | ||
| 'groups': ['admin'] if current_user.is_admin else [], | ||
| 'content': { | ||
| 'firstName': current_user.first_name, | ||
| 'lastName': current_user.last_name, | ||
| }, | ||
| }, | ||
| key=private_key, | ||
| algorithm='EdDSA' | ||
| ) | ||
|
|
||
| return RedirectResponse(url=f'https://docs.foo.com/login/jwt-callback#{jwt_token}', status_code=302) | ||
| ``` | ||
| </CodeGroup> | ||
|
|
||
| ### Redirecting unauthenticated users | ||
|
|
||
| When an unauthenticated user tries to access a protected page, their intended destination is automatically preserved: | ||
|
|
||
| 1. User attempts to visit a protected page: `https://docs.foo.com/quickstart`. | ||
| 2. Redirect to your login URL with a redirect query parameter: `https://foo.com/docs-login?redirect=%2Fquickstart`. | ||
| 3. After authentication, redirect to `https://docs.foo.com/login/jwt-callback?redirect=%2Fquickstart#{SIGNED_JWT}`. | ||
| 4. User lands in their original destination. | ||
| </Tab> | ||
| <Tab title="OAuth 2.0"> | ||
| ### Prerequisites | ||
|
|
||
| * An OAuth server that supports the Authorization Code Flow. | ||
| * Ability to create an API endpoint accessible by OAuth access tokens (optional, to enable personalization features). | ||
|
|
||
| ### Implementation | ||
|
|
||
| <Steps> | ||
| <Step title="Configure your OAuth settings."> | ||
| 1. In your dashboard, go to [Authentication](https://dashboard.mintlify.com/settings/deployment/authentication). | ||
| 2. Select **Full Authentication** or **Partial Authentication**. | ||
| 3. Select **OAuth** and configure these fields: | ||
| * **Authorization URL**: Your OAuth endpoint. | ||
| * **Client ID**: Your OAuth 2.0 client identifier. | ||
| * **Client Secret**: Your OAuth 2.0 client secret. | ||
| * **Scopes**: Permissions to request. Use multiple scopes if you need different access levels. | ||
| * **Token URL**: Your OAuth token exchange endpoint. | ||
| * **Info API URL** (optional): Endpoint to retrieve user info for personalization. If omitted, the OAuth flow will only be used to verify identity and the user info will be empty. | ||
| 4. Select **Save changes**. | ||
| </Step> | ||
| <Step title="Configure your OAuth server."> | ||
| 1. Copy the **Redirect URL** from your [authentication settings](https://dashboard.mintlify.com/settings/deployment/authentication). | ||
| 2. Add the redirect URL as an authorized redirect URL for your OAuth server. | ||
| </Step> | ||
| <Step title="Create your user info endpoint (optional)."> | ||
| To enable personalization features, create an API endpoint that: | ||
| * Accepts OAuth access tokens for authentication. | ||
| * Returns user data in the `User` format. See [Sending Data](/authentication-personalization/sending-data) for more information. | ||
|
|
||
| Add this endpoint URL to the **Info API URL** field in your [authentication settings](https://dashboard.mintlify.com/settings/deployment/authentication). | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| ### Example | ||
|
|
||
| Your documentation is hosted 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**: `['docs-user-info']` | ||
| - **Token URL**: `https://auth.foo.com/exchange` | ||
| - **Info API URL**: `https://api.foo.com/docs/user-info` | ||
|
|
||
| **Create a user info endpoint** at `api.foo.com/docs/user-info`, which requires an OAuth access token with the `docs-user-info` scope, and returns: | ||
|
|
||
| ```json | ||
| { | ||
| "content": { | ||
| "firstName": "Jane", | ||
| "lastName": "Doe" | ||
| }, | ||
| "groups": ["engineering", "admin"] | ||
| } | ||
| ``` | ||
|
|
||
| **Configure your OAuth server to allow redirects** to your callback URL. | ||
| </Tab> | ||
| <Tab title="Mintlify Dashboard"> | ||
| ### Prerequisites | ||
|
|
||
| * Your documentation users are also your documentation editors. | ||
|
|
||
| ### Implementation | ||
|
|
||
| <Steps> | ||
| <Step title="Enable Mintlify dashboard authentication."> | ||
| 1. In your dashboard, go to [Authentication](https://dashboard.mintlify.com/settings/deployment/authentication). | ||
| 2. Select **Full Authentication** or **Partial Authentication**. | ||
| 3. Select **Mintlify Auth**. | ||
| 4. Select **Enable Mintlify Auth**. | ||
| </Step> | ||
| <Step title="Add authorized users."> | ||
| 1. In your dashboard, go to [Members](https://dashboard.mintlify.com/settings/organization/members). | ||
| 2. Add each person who should have access to your documentation. | ||
| 3. Assign appropriate roles based on their editing permissions. | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| ### Example | ||
|
|
||
| Your documentation is hosted at `docs.foo.com` and your team uses the dashboard to edit your docs. 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 added to your organization. | ||
| </Tab> | ||
| <Tab title="Password"> | ||
| <Info> | ||
| Password authentication provides access control only and does **not** support content personalization. | ||
| </Info> | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| * Your security requirements allow sharing passwords among users. | ||
|
|
||
| ### Implementation | ||
|
|
||
| <Steps> | ||
| <Step title="Create a password."> | ||
| 1. In your dashboard, go to [Authentication](https://dashboard.mintlify.com/settings/deployment/authentication). | ||
| 2. Select **Full Authentication** or **Partial Authentication**. | ||
| 3. Select **Password**. | ||
| 4. Enter a secure password. | ||
| 5. Select **Save changes**. | ||
| </Step> | ||
| <Step title="Distribute access."> | ||
| Securely share the password and documentation URL with authorized users. | ||
| </Step> | ||
| </Steps> | ||
|
|
||
| ## Example | ||
|
|
||
| Your documentation is hosted 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. That's it! | ||
| </Tab> | ||
| </Tabs> | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| --- | ||
| title: "Overview" | ||
| description: "Control who sees your documentation and customize their experience" | ||
| icon: "badge-info" | ||
| --- | ||
| <Info> | ||
| Authentication methods are available on the [Growth and Enterprise plans](https://mintlify.com/pricing?ref=authentication). Please{" "} | ||
| <a href="mailto:[email protected]">contact sales</a> for more information. | ||
| </Info> | ||
|
|
||
| There are three approaches to manage access and customize your documentation based on user information. | ||
|
|
||
| * **Authentication**: Complete privacy protection for all content with full content customization. | ||
| * **Partial authentication**: Page-by-page access control with full content customization. | ||
| * **Personalization**: Content customization with **no security guarantees**. All content remains publicly accessible. | ||
|
|
||
| **Choose authentication** if you need complete security and privacy for all your documentation, including pages, images, search results, and AI assistant features. | ||
|
|
||
| **Choose partial authentication** if you want some pages to be public and others private. | ||
|
|
||
| **Choose personalization** if you want to customize content based on user information and your documentation can be publicly accessible. | ||
|
|
||
| ## Handshake methods | ||
|
|
||
| Authentication and personalization offer multiple handshake methods for controlling access to your content. | ||
|
|
||
| ### Available for all methods | ||
|
|
||
| **JSON Web Token (JWT)**: Custom system where you manage user tokens with full control over the login flow. | ||
| * Pros of JWT: | ||
| * Reduced risk of API endpoint abuse. | ||
| * No CORS configuration. | ||
| * No restrictions on API URLs. | ||
| * Cons of JWT: | ||
| * Must be compatible with your existing login flow. | ||
| * Dashboard sessions and docs authentication are decoupled, so your team will log into your dashboard and your docs separately. | ||
| * When you refresh user data, users must log into your docs again. If your users' data changes frequently, they must log in frequently or risk having stale data in your docs. | ||
|
|
||
| **OAuth 2.0**: Third-party login integration like Google, GitHub, or other OAuth providers. | ||
| * Pros of OAuth 2.0: | ||
| * Heightened security standard. | ||
| * No restrictions on API URLs. | ||
| * Cons of OAuth 2.0: | ||
| * Requires significant work if setting up an OAuth server for the first time. | ||
| * Dashboard sessions and docs authentication are decoupled, so your team will log into your dashboard and your docs separately. | ||
|
|
||
| ### Available for authentication and partial authentication | ||
|
|
||
| **Mintlify dashboard**: Allow all of your dashboard users to access your docs. | ||
| * Pros of Mintlify dashboard: | ||
| * No configuration required. | ||
| * Enables private preview deployments, restricting access to authenticated users only. | ||
| * Cons of Mintlify dashboard: | ||
| * Requires all users of your docs to have an account in your Mintlify dashboard. | ||
|
|
||
| **Password**: Shared access with a single global password. Used for access control only. Does not allow for personalization. | ||
| * Pros of password: | ||
| * Simple setup with no configuration required to add new users, just share the password. | ||
| * Cons of password: | ||
| * Lose personalization features since there is no way to differentiate users with the same password. | ||
| * Must change the password to revoke access. | ||
|
|
||
| ### Available for personalization | ||
|
|
||
| **Shared session**: Use the same session token as your dashboard to personalize content. | ||
| * Pros of shared session: | ||
| * Users that are logged into your dashboard are automatically logged into your docs. | ||
| * User sessions are persistent so you can refresh data without requiring a new login. | ||
| * Minimal setup. | ||
| * Cons of shared session: | ||
| * Your docs will make a request to your backend. | ||
| * You must have a dashboard that uses session authentication. | ||
| * CORS configuration is generally required. | ||
|
|
||
| ## Content customization | ||
|
|
||
| All three methods allow you to customize content with these features. | ||
|
|
||
| ### Dynamic `MDX` content | ||
|
|
||
| Display dynamic content based on user information like name, plan, or organization. | ||
|
|
||
| The `user` variable contains information sent to your docs from logged in users. See [Sending data](/authentication-personalization/sending-data) for more information. | ||
|
|
||
| **Example**: Hello, {user.name ?? 'reader'}! | ||
|
|
||
| ```jsx | ||
| Hello, {user.name ?? 'reader'}! | ||
| ``` | ||
|
|
||
| This feature is more powerful when you pair it with custom data about your users. For example, you can give different instructions based on a user's plan. | ||
|
|
||
| **Example**: Authentication is an enterprise feature. { | ||
| user.org === undefined | ||
| ? <>To access this feature, first create an account at the <a href="https://dashboard.mintlify.com/login">Mintlify dashboard</a>.</> | ||
| : user.org.plan !== 'enterprise' | ||
| ? <>You are currently on the ${user.org.plan ?? 'free'} plan. To speak to our team about upgrading, <a href="mailto:[email protected]">contact our sales team</a>.</> | ||
| : <>To request this feature for your enterprise org, <a href="mailto:[email protected]">contact our team</a>.</> | ||
| } | ||
|
|
||
| ```jsx | ||
| Authentication is an enterprise feature. { | ||
| user.org === undefined | ||
| ? <>To access this feature, first create an account at the <a href="https://dashboard.mintlify.com/login">Mintlify dashboard</a>.</> | ||
| : user.org.plan !== 'enterprise' | ||
| ? <>You are currently on the ${user.org.plan ?? 'free'} plan. To speak to our team about upgrading, <a href="mailto:[email protected]">contact our sales team</a>.</> | ||
| : <>To request this feature for your enterprise org, <a href="mailto:[email protected]">contact our team</a>.</> | ||
| } | ||
| ``` | ||
|
|
||
| <Note> | ||
| The information in `user` is only available for logged in users. For | ||
| logged out users, the value of `user` will be `{}`. To prevent the page from | ||
| crashing for logged out users, always use optional chaining on your `user` | ||
| fields. For example, `{user.org?.plan}`. | ||
| </Note> | ||
|
|
||
| ### API key prefilling | ||
|
|
||
| Automatically populate API playground fields with user-specific values by returning matching field names in your user data. The field names in your user data must exactly match the names in the API playground for automatic prefilling to work. | ||
|
|
||
| ### Page visibility | ||
|
|
||
| Restrict which pages are visible to your users by adding `groups` fields to your pages' frontmatter. By default, every page is visible to every user. | ||
|
|
||
| Users will only see pages for `groups` that they are in. | ||
|
|
||
| ```md | ||
| --- | ||
| title: "Managing your users" | ||
| description: "Adding and removing users from your organization" | ||
| groups: ["admin"] | ||
| --- | ||
| ``` | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.