Skip to content

Commit 93a3572

Browse files
docs for User Auth (mintlify#194)
* Documentation edits made through Mintlify web editor * Documentation edits made through Mintlify web editor * Documentation edits made through Mintlify web editor * Documentation edits made through Mintlify web editor * Documentation edits made through Mintlify web editor * improve overview info * add docs for shared session * add jwt docs * add docs on shape of data * add usage docs * remove unnecessary optionals * hide hidden pages docs since it's not out yet * address comments * add a better intro on the auth method page * add sales callout * remove "support" lol --------- Co-authored-by: mintlify-development[bot] <109878554+mintlify-development[bot]@users.noreply.github.com> Co-authored-by: Ronan McCarter <[email protected]>
1 parent 8308f65 commit 93a3572

File tree

6 files changed

+287
-0
lines changed

6 files changed

+287
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
title: 'Choosing an Auth Method'
3+
description: 'How to decide which auth method is right for your docs'
4+
---
5+
6+
Before your users can access personalized content, they must be authenticated. Mintlify supports two methods of authenticating users:
7+
8+
1. **Shared Session**: Utilize the same session token used by your dashboard to authenticate users.
9+
2. **JWT**: Use your own login flow to send user info to your docs via a JWT in the URL.
10+
11+
## Prerequisites
12+
13+
<Tabs>
14+
<Tab title="Shared Session">
15+
- You have a dashboard or other user portal hosted at your domain.
16+
- Your users' session credentials are stored as cookies.
17+
- You can create a new API endpoint at the same origin or a subdomain of your dashboard.
18+
- If your dashboard is at `foo.com`, the **API URL** must start with `foo.com` or `*.foo.com`
19+
- If your dashboard is at `dash.foo.com`, the **API URL** must start with `dash.foo.com` or `*.dash.foo.com`
20+
- Your docs are hosted at the same domain as your dashboard.
21+
- If your dashboard is at `foo.com`, your **docs** must be hosted at `foo.com` or `*.foo.com`
22+
- If your dashboard is at `*.foo.com`, your **docs** must be hosted at `foo.com` or `*.foo.com`
23+
</Tab>
24+
<Tab title="JWT">
25+
- You have some existing login flow.
26+
- You can add a final step in this login flow that creates a JWT and redirects to the docs.
27+
</Tab>
28+
</Tabs>
29+
30+
## Pros & Cons
31+
32+
<Tabs>
33+
<Tab title="Shared Session">
34+
Pros:
35+
36+
- Users that are logged into your dashboard are automatically logged into your docs
37+
- Your users' sessions are persistent, meaning you can refresh data without requiring additional login
38+
- Minimal setup required
39+
40+
Cons:
41+
42+
- Your docs will make a request to your backend, which may be undesirable
43+
</Tab>
44+
<Tab title="JWT">
45+
Pros:
46+
47+
- No dashboard needed
48+
- Reduced risk of API endpoint abuse
49+
- Zero CORS configuration
50+
51+
Cons:
52+
53+
- Must build new functionality around your existing login flow
54+
- Dashboard sessions and docs authentication are completely decoupled, so users will need to log in to your dashboard and your docs separately
55+
- Every time you want to refresh user data, your users must re-login to your docs
56+
- If your users' data changes frequently, you must require your users to log in frequently or risk having stale data in the docs
57+
- If your users' data rarely changes, this shouldn't be a problem
58+
</Tab>
59+
</Tabs>

integrations/user-auth/jwt.mdx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
title: 'JWT Auth'
3+
description: 'Use a customized login flow to authenticate users'
4+
---
5+
6+
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.
7+
8+
## Implementation
9+
10+
<Steps>
11+
<Step title="Generate a private key">
12+
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.
13+
</Step>
14+
<Step title="Create a login flow">
15+
Create a login flow that does the following:
16+
- Authenticate the user
17+
- Create a JWT containing the authenticated user's info in the [UserInfo](./sending-data) format
18+
- Sign the JWT with the secret
19+
- Create a redirect URL back to your docs, including the JWT as a query parameter with the name `user_auth`
20+
</Step>
21+
<Step title="Configure your User Auth settings">
22+
Return to your [Mintlify dashboard settings](https://dashboard.mintlify.com/settings/integrations) and add the login URL to your User Auth settings.
23+
</Step>
24+
</Steps>
25+
26+
## Example
27+
28+
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).
29+
30+
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.
31+
32+
I then go to the Mintlify dashboard settings and enter `https://foo.com/docs-login` for the Login URL field.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
title: 'Overview'
3+
description: 'Give your users a personalized docs experience'
4+
---
5+
6+
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.
7+
8+
With Mintlify, you can add User Auth to identify your users and tailor your docs content to them.
9+
10+
## What is User Auth
11+
12+
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:
13+
14+
1. **Customize MDX content** with a user's information, such as their name, plan, or title.
15+
2. **Prefill API keys** in the API Playground for streamlined use.
16+
3. <b className="text-primary">(Coming soon!)</b> **Selectively show pages** in the navigation based on a user's groups.
17+
18+
## What *isn't* User Auth
19+
20+
At this time, User Auth cannot provide any of the following:
21+
22+
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.
23+
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.
24+
25+
<Note>If you are interested in private docs content, [contact our team]([email protected]) to explore solutions.</Note>
26+
27+
## How to Use
28+
29+
### Customizing MDX Content
30+
31+
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:
32+
33+
User Auth is an enterprise feature. {
34+
userContext.org === undefined
35+
? <>To access this feature, first create an account at the <a href="https://dashboard.mintlify.com/login">Mintlify dashboard</a>.</>
36+
: userContext.org.plan !== 'enterprise'
37+
? <>You are currently on the ${userContext.org.plan ?? 'free'} plan. To upgrade, navigate to the <a href="https://dashboard.mintlify.com/settings/billing">billing page</a> in the Mintlify dashboard.</>
38+
: <>As an enterprise organization, you can enable this feature right now from your <a href="https://dashboard.mintlify.com/settings/integrations">Mintlify dashboard settings</a></>
39+
}
40+
41+
```jsx
42+
User Auth is an enterprise feature. {
43+
userContext.org === undefined
44+
? <>To access this feature, first create an account at the <a href="https://dashboard.mintlify.com/login">Mintlify dashboard</a>.</>
45+
: userContext.org.plan !== 'enterprise'
46+
? <>You are currently on the ${userContext.org.plan ?? 'free'} plan. To upgrade, navigate to the <a href="https://dashboard.mintlify.com/settings/billing">billing page</a> in the Mintlify dashboard.</>
47+
: <>As an enterprise organization, you can enable this feature right now from your <a href="https://dashboard.mintlify.com/settings/integrations">Mintlify dashboard settings</a></>
48+
}
49+
```
50+
51+
<Note>
52+
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}`
53+
</Note>
54+
55+
### Prefilling API Keys
56+
57+
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.
58+
{/*
59+
### Showing/Hiding Pages
60+
61+
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.
62+
When determining which pages to show to the user, Mintlify will check which groups the user belongs to.
63+
If the user is not in any of the groups listed in the page metadata, the page will not be shown.
64+
65+
```md
66+
---
67+
title: 'Managing Your Users'
68+
description: 'Adding and removing users from your organization'
69+
groups: ['admin']
70+
---
71+
```
72+
73+
Here's a table that displays whether a page is shown for different combinations of `groups` in UserInfo and page metadata:
74+
75+
| | `groups` not in UserInfo | `groups: []` in UserInfo | `groups: ['admin']` in UserInfo |
76+
|:-----------------------------------|:------------------------:|:-------------------------:|:--------------------------------:|
77+
| `groups` not in metadata | ✅ | ✅ | ✅ |
78+
| `groups: []` in metadata | ❌ | ❌ | ❌ |
79+
| `groups: ['admin']` in metadata | ❌ | ❌ | ✅ |
80+
81+
<Note>Note that an empty array in the page metadata is interpreted as "No groups should see this page."</Note> */}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: 'Sending Data'
3+
description: 'The types and shape of user data you can send to Mintlify'
4+
---
5+
6+
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:
7+
8+
```tsx
9+
type UserInfo = {
10+
expiresAt?: number;
11+
groups?: string[];
12+
content?: Record<string, any>;
13+
apiPlaygroundInputs?: {
14+
header?: Record<string, any>;
15+
query?: Record<string, any>;
16+
cookie?: Record<string, any>;
17+
server?: Record<string, string>;
18+
};
19+
};
20+
```
21+
22+
<ParamField
23+
path="expiresAt"
24+
type="number"
25+
>
26+
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.
27+
<Warning><b>For JWT Auth:</b> 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.</Warning>
28+
</ParamField>
29+
<ParamField
30+
path="groups"
31+
type="string[]"
32+
>
33+
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.
34+
</ParamField>
35+
<ParamField
36+
path="content"
37+
type="object"
38+
>
39+
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}!`
40+
</ParamField>
41+
<ParamField
42+
path="apiPlaygroundInputs"
43+
type="object"
44+
>
45+
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.
46+
47+
<Note>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.</Note>
48+
</ParamField>
49+
50+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: 'Shared Session Auth'
3+
description: 'Seamlessly share user sessions between your dashboard and your docs'
4+
---
5+
6+
This method utilizes the session authentication info already stored in your user’s browser to create a seamless documentation experience.
7+
8+
## Implementation
9+
10+
<Steps>
11+
<Step title="Create your Info API">
12+
Create an API endpoint that uses session authentication to identify users, and responds with a JSON payload following the [UserInfo](./sending-data) format.
13+
14+
If the API domain does not *exactly match* the docs domain:
15+
- Add the docs domain to your API's `Access-Control-Allow-Origin` header (must not be `*`)
16+
- Ensure your API’s `Access-Control-Allow-Credentials` header is `true`
17+
<Warning>
18+
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.
19+
</Warning>
20+
</Step>
21+
<Step title="Configure your User Auth settings">
22+
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.
23+
</Step>
24+
</Steps>
25+
26+
## Examples
27+
28+
### Dashboard at subdomain, docs at subdomain
29+
30+
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`.
31+
32+
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**.
33+
34+
I then go to the Mintlify dashboard settings and enter `https://dash.foo.com/api/docs/user-info` for the API URL field.
35+
36+
### Dashboard at subdomain, docs at root
37+
38+
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`.
39+
40+
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**.
41+
42+
I then go to the Mintlify dashboard settings and enter `https://dash.foo.com/api/docs/user-info` for the API URL field.
43+
44+
### Dashboard at root, docs at root
45+
46+
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`.
47+
48+
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.
49+
50+
I then go to the Mintlify dashboard settings and enter `https://foo.com/api/docs/user-info` for the API URL field.

mint.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,21 @@
146146
"group": "SDKs",
147147
"pages": ["integrations/sdks/speakeasy", "integrations/sdks/stainless"]
148148
},
149+
{
150+
"group": "User Auth",
151+
"pages": [
152+
"integrations/user-auth/overview",
153+
{
154+
"group": "Authenticating",
155+
"pages": [
156+
"integrations/user-auth/choosing-an-auth-method",
157+
"integrations/user-auth/shared-session",
158+
"integrations/user-auth/jwt"
159+
]
160+
},
161+
"integrations/user-auth/sending-data"
162+
]
163+
},
149164
{
150165
"group": "Components",
151166
"pages": [

0 commit comments

Comments
 (0)