diff --git a/integrations/user-auth/choosing-an-auth-method.mdx b/integrations/user-auth/choosing-an-auth-method.mdx
new file mode 100644
index 000000000..e319d4fec
--- /dev/null
+++ b/integrations/user-auth/choosing-an-auth-method.mdx
@@ -0,0 +1,59 @@
+---
+title: 'Choosing an Auth Method'
+description: 'How to decide which auth method is right for your docs'
+---
+
+Before your users can access personalized content, they must be authenticated. Mintlify supports two methods of authenticating users:
+
+1. **Shared Session**: Utilize the same session token used by your dashboard to authenticate users.
+2. **JWT**: Use your own login flow to send user info to your docs via a JWT in the URL.
+
+## Prerequisites
+
+
+
+ - You have a dashboard or other user portal hosted at your domain.
+ - Your users' session credentials are stored as cookies.
+ - You can create a new API endpoint at the same origin or a subdomain of your dashboard.
+ - If your dashboard is at `foo.com`, the **API URL** must start with `foo.com` or `*.foo.com`
+ - If your dashboard is at `dash.foo.com`, the **API URL** must start with `dash.foo.com` or `*.dash.foo.com`
+ - Your docs are hosted at the same domain as your dashboard.
+ - If your dashboard is at `foo.com`, your **docs** must be hosted at `foo.com` or `*.foo.com`
+ - If your dashboard is at `*.foo.com`, your **docs** must be hosted at `foo.com` or `*.foo.com`
+
+
+ - You have some existing login flow.
+ - You can add a final step in this login flow that creates a JWT and redirects to the docs.
+
+
+
+## Pros & Cons
+
+
+
+ Pros:
+
+ - Users that are logged into your dashboard are automatically logged into your docs
+ - Your users' sessions are persistent, meaning you can refresh data without requiring additional login
+ - Minimal setup required
+
+ Cons:
+
+ - Your docs will make a request to your backend, which may be undesirable
+
+
+ Pros:
+
+ - No dashboard needed
+ - Reduced risk of API endpoint abuse
+ - Zero CORS configuration
+
+ Cons:
+
+ - Must build new functionality around your existing login flow
+ - Dashboard sessions and docs authentication are completely decoupled, so users will need to log in to your dashboard and your docs separately
+ - Every time you want to refresh user data, your users must re-login to your docs
+ - If your users' data changes frequently, you must require your users to log in frequently or risk having stale data in the docs
+ - If your users' data rarely changes, this shouldn't be a problem
+
+
diff --git a/integrations/user-auth/jwt.mdx b/integrations/user-auth/jwt.mdx
new file mode 100644
index 000000000..8d67a08ef
--- /dev/null
+++ b/integrations/user-auth/jwt.mdx
@@ -0,0 +1,32 @@
+---
+title: 'JWT Auth'
+description: 'Use a customized login flow to authenticate users'
+---
+
+If you don’t have a dashboard, or if you want to keep your dashboard and docs completely separate, you can use your own login flow to send user info to your docs via a JWT in the URL.
+
+## Implementation
+
+
+
+ Go to your [Mintlify dashboard settings](https://dashboard.mintlify.com/settings/integrations) and generate a private key. Store this key somewhere secure where it can be accessed by your backend.
+
+
+ Create a login flow that does the following:
+ - Authenticate the user
+ - Create a JWT containing the authenticated user's info in the [UserInfo](./sending-data) format
+ - Sign the JWT with the secret
+ - Create a redirect URL back to your docs, including the JWT as a query parameter with the name `user_auth`
+
+
+ Return to your [Mintlify dashboard settings](https://dashboard.mintlify.com/settings/integrations) and add the login URL to your User Auth settings.
+
+
+
+## Example
+
+I want to set up authentication for my docs hosted at `docs.foo.com`. I want my docs to be completely separate from my dashboard (or I don’t have a dashboard at all).
+
+To set up authentication with Mintlify, I go to my Mintlify dashboard and generate a JWT secret. I create a web URL `https://foo.com/docs-login` that initiates a login flow for my users. At the end of this login flow, once I have verified the identity of the user, I create a JWT containing the user’s custom data according to Mintlify’s specification. I sign this JWT with my Mintlify secret, create a redirect URL of the form `https://docs.foo.com?user_auth={SIGNED_JWT}`, and redirect the user.
+
+I then go to the Mintlify dashboard settings and enter `https://foo.com/docs-login` for the Login URL field.
diff --git a/integrations/user-auth/overview.mdx b/integrations/user-auth/overview.mdx
new file mode 100644
index 000000000..f9fa229ce
--- /dev/null
+++ b/integrations/user-auth/overview.mdx
@@ -0,0 +1,81 @@
+---
+title: 'Overview'
+description: 'Give your users a personalized docs experience'
+---
+
+Sometimes, when writing docs, you wish you knew just a little bit about the person reading them. Maybe you only want to show them the information they should care about. Maybe you want to craft examples that they can use out-of-the-box.
+
+With Mintlify, you can add User Auth to identify your users and tailor your docs content to them.
+
+## What is User Auth
+
+User Auth allows you to configure a method for identifying and authenticating your users. Once authenticated, you can share user-specific information that can be used to personalize the docs. This unlocks some powerful features:
+
+1. **Customize MDX content** with a user's information, such as their name, plan, or title.
+2. **Prefill API keys** in the API Playground for streamlined use.
+3. (Coming soon!) **Selectively show pages** in the navigation based on a user's groups.
+
+## What *isn't* User Auth
+
+At this time, User Auth cannot provide any of the following:
+
+1. **Private docs content.** While you can hide pages from unauthenticated users, those pages are still accessible by anyone who can guess the URL. If your documentation contains sensitive information, User Auth is not enough to hide it.
+2. **A Mintlify-backed user database.** Mintlify does not store *any* information about your users. Rather, it relies on your existing infrastructure to serve as the source-of-truth for user data.
+
+If you are interested in private docs content, [contact our team](sales@mintlify.com) to explore solutions.
+
+## How to Use
+
+### Customizing MDX Content
+
+When writing content, you can use the `userContext` variable to access the information you have sent to your docs. Here's a real world example:
+
+User Auth is an enterprise feature. {
+ userContext.org === undefined
+ ? <>To access this feature, first create an account at the Mintlify dashboard.>
+ : userContext.org.plan !== 'enterprise'
+ ? <>You are currently on the ${userContext.org.plan ?? 'free'} plan. To upgrade, navigate to the billing page in the Mintlify dashboard.>
+ : <>As an enterprise organization, you can enable this feature right now from your Mintlify dashboard settings>
+}
+
+```jsx
+User Auth is an enterprise feature. {
+ userContext.org === undefined
+ ? <>To access this feature, first create an account at the Mintlify dashboard.>
+ : userContext.org.plan !== 'enterprise'
+ ? <>You are currently on the ${userContext.org.plan ?? 'free'} plan. To upgrade, navigate to the billing page in the Mintlify dashboard.>
+ : <>As an enterprise organization, you can enable this feature right now from your Mintlify dashboard settings>
+}
+```
+
+
+ The information in `userContext` is only available after a user has logged in. For logged out users, the value of `userContext` will be `{}`. To prevent the page from crashing for logged-out users, always use optional chaining on your `userContext` fields, e.g. `{userContext.org?.plan}`
+
+
+### Prefilling API Keys
+
+If you return API Playground inputs in the user info, they will automatically be prefilled in the API Playground. Make sure the name of the field in the user info is an exact match of the name in the API Playground.
+{/*
+### Showing/Hiding Pages
+
+By default, every page is visible to every user. If you want to restrict which pages are visible to your users, you can add a `groups` field in your page metadata.
+When determining which pages to show to the user, Mintlify will check which groups the user belongs to.
+If the user is not in any of the groups listed in the page metadata, the page will not be shown.
+
+```md
+---
+title: 'Managing Your Users'
+description: 'Adding and removing users from your organization'
+groups: ['admin']
+---
+```
+
+Here's a table that displays whether a page is shown for different combinations of `groups` in UserInfo and page metadata:
+
+| | `groups` not in UserInfo | `groups: []` in UserInfo | `groups: ['admin']` in UserInfo |
+|:-----------------------------------|:------------------------:|:-------------------------:|:--------------------------------:|
+| `groups` not in metadata | ✅ | ✅ | ✅ |
+| `groups: []` in metadata | ❌ | ❌ | ❌ |
+| `groups: ['admin']` in metadata | ❌ | ❌ | ✅ |
+
+Note that an empty array in the page metadata is interpreted as "No groups should see this page." */}
diff --git a/integrations/user-auth/sending-data.mdx b/integrations/user-auth/sending-data.mdx
new file mode 100644
index 000000000..019dc0581
--- /dev/null
+++ b/integrations/user-auth/sending-data.mdx
@@ -0,0 +1,50 @@
+---
+title: 'Sending Data'
+description: 'The types and shape of user data you can send to Mintlify'
+---
+
+Depending on your authentication configuration, your API will respond with either a raw JSON object or a signed JWT. The shape of the data is the same for both:
+
+```tsx
+type UserInfo = {
+ expiresAt?: number;
+ groups?: string[];
+ content?: Record;
+ apiPlaygroundInputs?: {
+ header?: Record;
+ query?: Record;
+ cookie?: Record;
+ server?: Record;
+ };
+};
+```
+
+
+ The time at which this information should expire, in **seconds since epoch**. If the user loads the page and the current time is after this value, the stored data will be deleted.
+ For JWT Auth: This is *not* the same as the `exp` claim of the JWT. The `exp` claim determines when a JWT should no longer be considered valid, and should be set as low as possible. In this case, it can probably be set to 10 seconds or lower. The `expiresAt` field determines when retrieved data should be considered stale, and can be anywhere from one day to several weeks.
+
+
+ A list of groups that the user belongs to. This will determine which pages should be shown to this user. If any of these groups is listed in the `groups` field of a page’s metadata, that page will be shown.
+
+
+ A bag of values that can be accessed from within MDX content using the `userContext` variable. For example, if you have supplied `{ firstName: 'Ronan' }` as your content field, you can use the following in your MDX: `Good morning, {userContext.firstName}!`
+
+
+ User-specific values that will be prefilled in the API playground if supplied. For example, if each of my customers makes requests at a specific subdomain, I can send `{ server: { subdomain: 'foo' } }` as my `apiPlaygroundInputs` field, and this value will be prefilled on any API page with this `subdomain` value.
+
+ The`header`, `query`, and `cookie` fields will only be prefilled if they are part of your [security scheme](https://swagger.io/docs/specification/authentication/). Creating a standard header parameter named `Authorization` is not sufficient to enable this feature. To know if a field will be prefilled, navigate to your existing docs and check if the field is in either the `Authorization` or `Server` section.
+
+
+
\ No newline at end of file
diff --git a/integrations/user-auth/shared-session.mdx b/integrations/user-auth/shared-session.mdx
new file mode 100644
index 000000000..a86f8353b
--- /dev/null
+++ b/integrations/user-auth/shared-session.mdx
@@ -0,0 +1,50 @@
+---
+title: 'Shared Session Auth'
+description: 'Seamlessly share user sessions between your dashboard and your docs'
+---
+
+This method utilizes the session authentication info already stored in your user’s browser to create a seamless documentation experience.
+
+## Implementation
+
+
+
+ Create an API endpoint that uses session authentication to identify users, and responds with a JSON payload following the [UserInfo](./sending-data) format.
+
+ If the API domain does not *exactly match* the docs domain:
+ - Add the docs domain to your API's `Access-Control-Allow-Origin` header (must not be `*`)
+ - Ensure your API’s `Access-Control-Allow-Credentials` header is `true`
+
+ These CORS options only need to be enabled on the *single endpoint* responsible for returning user information. We do not recommend enabling these options on all dashboard endpoints.
+
+
+
+ Go to your [Mintlify dashboard settings](https://dashboard.mintlify.com/settings/integrations) and add the API URL and your Login URL to your User Auth settings.
+
+
+
+## Examples
+
+### Dashboard at subdomain, docs at subdomain
+
+I have a dashboard at `dash.foo.com`, which uses cookie-based session authentication. My dashboard API routes are hosted at `dash.foo.com/api`. I want to set up authentication for my docs hosted at `docs.foo.com`.
+
+To set up authentication with Mintlify, I create another dashboard endpoint `dash.foo.com/api/docs/user-info` which identifies the user using session auth, and responds with their custom data according to Mintlify’s specification. I then add `https://docs.foo.com` to the `Access-Control-Allow-Origin` allow-list **for this route only**, and ensure my `Access-Control-Allow-Credentials` configuration is set to `true` **for this route only**.
+
+I then go to the Mintlify dashboard settings and enter `https://dash.foo.com/api/docs/user-info` for the API URL field.
+
+### Dashboard at subdomain, docs at root
+
+I have a dashboard at `dash.foo.com`, which uses cookie-based session authentication. My dashboard API routes are hosted at `dash.foo.com/api`. I want to set up authentication for my docs hosted at `foo.com/docs`.
+
+To set up authentication with Mintlify, I create another dashboard endpoint `dash.foo.com/api/docs/user-info` which identifies the user using session auth, and responds with their custom data according to Mintlify’s specification. I then add `https://foo.com` to the `Access-Control-Allow-Origin` allow-list **for this route only**, and ensure my `Access-Control-Allow-Credentials` configuration is set to `true` **for this route only**.
+
+I then go to the Mintlify dashboard settings and enter `https://dash.foo.com/api/docs/user-info` for the API URL field.
+
+### Dashboard at root, docs at root
+
+I have a dashboard at `foo.com/dashboard`, which uses cookie-based session authentication. My dashboard API routes are hosted at `foo.com/api`. I want to set up authentication for my docs hosted at `foo.com/docs`.
+
+To set up authentication with Mintlify, I create another dashboard endpoint `foo.com/api/docs/user-info` which identifies the user using session auth, and responds with their custom data according to Mintlify’s specification.
+
+I then go to the Mintlify dashboard settings and enter `https://foo.com/api/docs/user-info` for the API URL field.
\ No newline at end of file
diff --git a/mint.json b/mint.json
index 626959a65..5425d78c6 100644
--- a/mint.json
+++ b/mint.json
@@ -146,6 +146,21 @@
"group": "SDKs",
"pages": ["integrations/sdks/speakeasy", "integrations/sdks/stainless"]
},
+ {
+ "group": "User Auth",
+ "pages": [
+ "integrations/user-auth/overview",
+ {
+ "group": "Authenticating",
+ "pages": [
+ "integrations/user-auth/choosing-an-auth-method",
+ "integrations/user-auth/shared-session",
+ "integrations/user-auth/jwt"
+ ]
+ },
+ "integrations/user-auth/sending-data"
+ ]
+ },
{
"group": "Components",
"pages": [