Skip to content

Commit 2d25e49

Browse files
committed
add JWT info to auth setup
1 parent a7a772c commit 2d25e49

File tree

2 files changed

+224
-15
lines changed

2 files changed

+224
-15
lines changed

authentication-personalization/authentication-setup.mdx

Lines changed: 223 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,237 @@ title: "Authentication Setup"
33
description: "Guarantee privacy of your docs by authenticating users"
44
icon: "file-lock"
55
---
6+
Authentication requires users to log in before accessing your documentation. This guide covers setup for each available handshake method.
7+
8+
**Need help choosing?** See the [overview](/authentication-personalization/overview) to compare options.
69

710
<Info>
811
Authentication methods are available on the [Growth and Enterprise plans](https://mintlify.com/pricing?ref=authentication). Please{" "}
912
<a href="mailto:[email protected]">contact sales</a> for more information.
1013
</Info>
1114

12-
Authentication offers full privacy for all of your
13-
documentation content by requiring users to authenticate before viewing any content, such as:
15+
## Configuring authentication
16+
17+
Select the handshake method that you want to configure.
18+
19+
<Tabs>
20+
<Tab title="JWT">
21+
### Prerequisites
22+
23+
* An authentication system that can generate and sign JWTs.
24+
* A backend service that can create redirect URLs.
25+
26+
### Implementation
27+
28+
<Steps>
29+
<Step title="Generate a private key.">
30+
1. In your dashboard, go to [Authentication](https://dashboard.mintlify.com/settings/deployment/authentication).
31+
2. Select **Full Authentication** or **Partial Authentication**.
32+
3. Select **JWT**.
33+
4. Enter the URL of your existing login flow and select **Save changes**.
34+
5. Select **Generate new key**.
35+
6. Store your key securely where it can be accessed by your backend.
36+
</Step>
37+
<Step title="Integrate Mintlify authentication into your login flow.">
38+
Modify your existing login flow to include these steps after user authentication:
39+
40+
* Create a JWT containing the authenticated user's info in the `User` format. See [Sending Data](/authentication-personalization/sending-data) for more information.
41+
* Sign the JWT with your secret key, using the EdDSA algorithm.
42+
* Create a redirect URL back to the `/login/jwt-callback` path of your docs, including the JWT as the hash.
43+
</Step>
44+
</Steps>
45+
46+
### Example
47+
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.
48+
49+
To do this, create a login endpoint at `https://foo.com/docs-login` that extends your existing authentication.
50+
51+
After verifying user credentials:
52+
* Generate a JWT with user data in Mintlify's format.
53+
* Sign the JWT and redirect to `https://docs.foo.com/login/jwt-callback#{SIGNED_JWT}`.
54+
55+
<CodeGroup>
56+
```ts TypeScript
57+
import * as jose from 'jose';
58+
import { Request, Response } from 'express';
59+
60+
const TWO_WEEKS_IN_MS = 1000 * 60 * 60 * 24 * 7 * 2;
61+
62+
const signingKey = await jose.importPKCS8(process.env.MINTLIFY_PRIVATE_KEY, 'EdDSA');
63+
64+
export async function handleRequest(req: Request, res: Response) {
65+
const user = {
66+
expiresAt: Math.floor((Date.now() + TWO_WEEKS_IN_MS) / 1000), // 2 week session expiration
67+
groups: res.locals.user.groups,
68+
content: {
69+
firstName: res.locals.user.firstName,
70+
lastName: res.locals.user.lastName,
71+
},
72+
};
73+
74+
const jwt = await new jose.SignJWT(user)
75+
.setProtectedHeader({ alg: 'EdDSA' })
76+
.setExpirationTime('10 s') // 10 second JWT expiration
77+
.sign(signingKey);
78+
79+
return res.redirect(`https://docs.foo.com/login/jwt-callback#${jwt}`);
80+
}
81+
```
82+
83+
```python Python
84+
import jwt # pyjwt
85+
import os
86+
87+
from datetime import datetime, timedelta
88+
from fastapi.responses import RedirectResponse
89+
90+
private_key = os.getenv(MINTLIFY_JWT_PEM_SECRET_NAME, '')
91+
92+
@router.get('/auth')
93+
async def return_mintlify_auth_status(current_user):
94+
jwt_token = jwt.encode(
95+
payload={
96+
'exp': int((datetime.now() + timedelta(seconds=10)).timestamp()), # 10 second JWT expiration
97+
'expiresAt': int((datetime.now() + timedelta(weeks=2)).timestamp()), # 1 week session expiration
98+
'groups': ['admin'] if current_user.is_admin else [],
99+
'content': {
100+
'firstName': current_user.first_name,
101+
'lastName': current_user.last_name,
102+
},
103+
},
104+
key=private_key,
105+
algorithm='EdDSA'
106+
)
107+
108+
return RedirectResponse(url=f'https://docs.foo.com/login/jwt-callback#{jwt_token}', status_code=302)
109+
```
110+
</CodeGroup>
111+
112+
### Redirecting unauthenticated users
113+
114+
When an unauthenticated user tries to access a protected page, their intended destination is automatically preserved:
115+
116+
1. User attempts to visit a protected page: `https://docs.foo.com/quickstart`.
117+
2. Redirect to your login URL with a redirect query parameter: `https://foo.com/docs-login?redirect=%2Fquickstart`.
118+
3. After authentication, redirect to `https://docs.foo.com/login/jwt-callback?redirect=%2Fquickstart#{SIGNED_JWT}`.
119+
4. User lands in their original destination.
120+
</Tab>
121+
<Tab title="OAuth 2.0">
122+
### Prerequisites
123+
124+
- You have an existing OAuth server that supports the Authorization Code flow.
125+
- You can create a new API endpoint that can be accessed by the returned OAuth access token.
126+
127+
### Implementation
128+
129+
<Steps>
130+
<Step title="Configure your Authentication settings">
131+
Go to your [Mintlify authentication settings](https://dashboard.mintlify.com/products/authentication), select the OAuth option, and fill out the required fields:
132+
133+
- **Authorization URL**: The base URL for the authorization request, to which we will add the appropriate query parameters.
134+
- **Client ID**: An ID for the OAuth 2.0 client to be used.
135+
- **Scopes**: An array of scopes that will be requested. TODO: clarify why there could be multiple
136+
- **Token URL**: The base URL for the token exchange request.
137+
- **Info API URL** (optional): The endpoint that will be hit to retrieve user info. If omitted, the OAuth flow will only be used to verify identity, and the user info will be empty.
138+
</Step>
139+
<Step title="Configure your OAuth client">
140+
Copy the Redirect URL listed in the [Mintlify authentication settings](https://dashboard.mintlify.com/products/authentication) and add it as an authorized redirect URL for your OAuth server.
141+
</Step>
142+
<Step title="Create your Info API (Optional)">
143+
If you want to take advantage of authentication's customization features, you'll need to create an endpoint to retrieve info about your users.
144+
Create an API endpoint that can be accessed with an OAuth access token, and responds with a JSON payload following the [User](../sending-data) format.
145+
146+
Return to your [Mintlify authentication settings](https://dashboard.mintlify.com/products/authentication) and add the Info API URL
147+
to your OAuth configuration.
148+
</Step>
149+
</Steps>
150+
151+
## Example
152+
153+
I have an existing OAuth server that supports the Authorization Code flow. I want to set up authentication for my docs hosted at `foo.com/docs`.
154+
155+
To set up authentication with Mintlify, I create an endpoint `api.foo.com/docs/user-info` which requires an OAuth access token with the `docs-user-info` scope, and responds with the user's custom data according to Mintlify’s specification.
156+
157+
I then go to the dashboard settings, navigate to the Authentication settings, select OAuth, and enter the relevant values for the OAuth flow and Info API endpoint:
158+
- **Authorization URL**: `https://auth.foo.com/authorization`
159+
- **Client ID**: `ydybo4SD8PR73vzWWd6S0ObH`
160+
- **Scopes**: `['docs-user-info']`
161+
- **Token URL**: `https://auth.foo.com/exchange`
162+
- **Info API URL**: `https://api.foo.com/docs/user-info`
163+
164+
Finally, I copy the Redirect URL displayed in the dashboard settings and add it as an authorized redirect URL in my OAuth client configuration settings.
165+
166+
167+
</Tab>
168+
<Tab title="Mintlify Dashboard">
169+
### Prerequisites
170+
171+
- Your documentation readers are also your documentation editors.
172+
173+
### Implementation
174+
175+
### Example
176+
177+
I want to set up authentication for my docs hosted at `docs.foo.com`. I want my docs
178+
to be internal, and the people that will be viewing my docs are the same people that
179+
contribute to my docs.
180+
181+
To set up authentication with Mintlify, I can go to my [dashboard settings](https://dashboard.mintlify.com/products/authentication)
182+
and enable Authentication with the Mintlify Auth Handshake.
183+
184+
I can then ensure that anyone that should be able to read the docs has been added as a user in
185+
my [dashboard settings](https://dashboard.mintlify.com/settings/organization/members).
186+
187+
## Implementation
188+
189+
<Steps>
190+
<Step title="Configure your Authentication settings">
191+
Go to your [Mintlify dashboard
192+
settings](https://dashboard.mintlify.com/products/authentication) and select
193+
the Mintlify Auth Handshake.
194+
</Step>
195+
<Step title="Add users">
196+
Ensure that any users that should be able to view your documentation have
197+
been added as users in your [Mintlify dashboard
198+
settings](https://dashboard.mintlify.com/settings/organization/members).
199+
</Step>
200+
</Steps>
201+
202+
203+
</Tab>
204+
<Tab title="Password">
205+
<Info>
206+
Password authentication is used for access control only. Does not allow for personalizaiton.
207+
</Info>
208+
209+
### Prerequisites
210+
211+
- Your security requirements allow for password sharing between documentation readers.
212+
213+
### Implementation
214+
215+
<Steps>
216+
<Step title="Add a password">
217+
Go to your [dashboard
218+
settings](https://dashboard.mintlify.com/products/authentication) and create
219+
a password.
220+
</Step>
221+
<Step title="Share your password">
222+
Securely share the password with your documentation readers. That's it!
223+
</Step>
224+
</Steps>
14225

15-
- Documentation page content
16-
- Images used in documentation pages
17-
- Search results
18-
- AI assistant interactions
226+
## Example
19227

20-
You can authenticate users through handshake methods such as:
228+
I want to set up authentication for my docs hosted at `docs.foo.com`. I don't want
229+
to have to keep track of who can and cannot access the docs. My main use case for
230+
authentication is to prevent competitors from snooping - password sharing is secure
231+
enough for my team.
21232

22-
- [Password](./authentication-setup/password)
23-
- [JWT](./authentication-setup/jwt)
24-
- [OAuth](./authentication-setup/oauth)
25-
- [Mintlify dashboard](./authentication-setup/mintlify)
233+
To set up authentication with Mintlify, I go to my Mintlify dashboard and add at
234+
least one password. I then share that password, along with the private docs URL,
235+
with potential customers.
26236

27-
Authentication is similar to our [Personalization](./personalization) offering, but with guaranteed privacy. In addition
28-
to securing your documentation content, all features that are available via
29-
Personalization are also available via Authentication.
30237

31-
Check out our docs for more info on [choosing Authentication vs Personalization](./authentication-vs-personalization).
238+
</Tab>
239+
</Tabs>

authentication-personalization/overview.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Authentication and personalization offer multiple handshake methods for controll
4949
**Mintlify dashboard**: Allow all of your dashboard users to access your docs.
5050
* Pros of Mintlify dashboard:
5151
* No configuration required.
52+
* Enables private preview deployments, restricting access to authenticated users only.
5253
* Cons of Mintlify dashboard:
5354
* Requires all users of your docs to have an account in your Mintlify dashboard.
5455

0 commit comments

Comments
 (0)