Skip to content

Commit 2253765

Browse files
feat(mcp): Enterprise-Managed Auth (id-jag) validation + Okta docs (#2798)
* feat(mcp): Enterprise-Managed Auth (id-jag) validation + Okta docs * docs(enterprise): clarify Okta connection is client-side org config, drop wrong client JSON * docs(enterprise): remove em dashes * docs(enterprise): group Entra and Okta under Enterprise-Managed Auth, redirect old azure-apim path * refactor docs --------- Co-authored-by: enesgules <abdullah.enes.gules@gmail.com>
1 parent 73542b7 commit 2253765

13 files changed

Lines changed: 184 additions & 20 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@upstash/context7-mcp": patch
3+
---
4+
5+
Validate Enterprise-Managed Auth (id-jag) access tokens at the MCP server, so MCP clients can authenticate to Context7 through an enterprise IdP (Okta) via the MCP Enterprise-Managed Authorization extension.

docs/docs.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
"theme": "mint",
44
"name": "Context7 MCP",
55
"description": "Up-to-date code docs for any prompt.",
6+
"redirects": [
7+
{
8+
"source": "/enterprise/azure-apim",
9+
"destination": "/enterprise/enterprise-managed-auth/entra"
10+
}
11+
],
612
"colors": {
713
"primary": "#10B981",
814
"light": "#ECFDF5",
@@ -56,7 +62,13 @@
5662
"group": "Enterprise",
5763
"pages": [
5864
"enterprise",
59-
"enterprise/azure-apim",
65+
{
66+
"group": "Enterprise-Managed Auth",
67+
"pages": [
68+
"enterprise/enterprise-managed-auth/entra",
69+
"enterprise/enterprise-managed-auth/okta"
70+
]
71+
},
6072
{
6173
"group": "On-Premise",
6274
"pages": [

docs/enterprise/azure-apim.mdx renamed to docs/enterprise/enterprise-managed-auth/entra.mdx

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "Azure API Management as MCP gateway"
3-
sidebarTitle: "Azure APIM"
3+
sidebarTitle: "Microsoft Entra ID"
44
description: "Route Context7 MCP traffic through Azure API Management with per-user Microsoft Entra ID authentication."
55
---
66

@@ -159,7 +159,7 @@ This app represents the gateway as an Entra resource. Clients request tokens for
159159
7. **Authentication****+ Add a platform****Web** → enter `https://vscode.dev/redirect` as the redirect URI → **Configure**.
160160

161161
<Note>
162-
VS Code with GitHub Copilot uses Microsoft's hosted OAuth broker at `vscode.dev/redirect` rather than a local loopback URI. The redirect URI must be registered on the Gateway app or the sign-in flow fails with `AADSTS500113` or `AADSTS50011`. Add additional redirect URIs (or platforms) here for other MCP clients as you adopt them — each client tool's documentation lists its expected URI.
162+
VS Code with GitHub Copilot uses Microsoft's hosted OAuth broker at `vscode.dev/redirect` rather than a local loopback URI. The redirect URI must be registered on the Gateway app or the sign-in flow fails with `AADSTS500113` or `AADSTS50011`. Add additional redirect URIs (or platforms) here for other MCP clients as you adopt them. Each client tool's documentation lists its expected URI.
163163
</Note>
164164

165165
### Step 3: Wire the permission chain
@@ -347,7 +347,7 @@ The cache duration (`3000` seconds) is slightly below Entra's default access tok
347347

348348
## Part 4: Onboard your tenant in Context7
349349

350-
Context7 validates inbound tokens in two stages: first the token's signature, audience, issuer, and scope are checked against your teamspace's tenant configuration; then the token's `oid` claim is resolved against a list of pre-provisioned users for the teamspace. **Both checks are mandatory** — any developer who has not been added to the teamspace's user list will be rejected with `401` even when their token is otherwise valid.
350+
Context7 validates inbound tokens in two stages: first the token's signature, audience, issuer, and scope are checked against your teamspace's tenant configuration; then the token's `oid` claim is resolved against a list of pre-provisioned users for the teamspace. **Both checks are mandatory.** Any developer who has not been added to the teamspace's user list will be rejected with `401` even when their token is otherwise valid.
351351

352352
An owner or admin of the teamspace configures both from the dashboard. Users can be added one at a time (Step 2) or synced automatically from an Entra security group (Step 3).
353353

@@ -361,9 +361,9 @@ An owner or admin of the teamspace configures both from the dashboard. Users can
361361
</Note>
362362

363363
3. Fill in:
364-
- **Tenant ID** your Entra directory ID
365-
- **Audience** the **MCP API app** Application (client) ID (the second token's audience, not the gateway app)
366-
- **Required scope** `mcp.access`
364+
- **Tenant ID:** your Entra directory ID
365+
- **Audience:** the **MCP API app** Application (client) ID (the second token's audience, not the gateway app)
366+
- **Required scope:** `mcp.access`
367367

368368
4. Click **Test connection**. Context7 fetches your tenant's OpenID Connect discovery document from Microsoft and confirms the issuer matches.
369369

@@ -375,45 +375,45 @@ After saving the tenant configuration, scroll down to the **Microsoft Entra ID u
375375

376376
1. Click **Add user**.
377377
2. Enter the user's:
378-
- **Email** the address they sign in to Entra with.
379-
- **Object ID (oid)** their Entra object ID. Find it in the Entra admin center under **Users → `<name>` → Overview → Object ID**, or have the user run `az ad signed-in-user show --query id -o tsv` after `az login`.
378+
- **Email:** the address they sign in to Entra with.
379+
- **Object ID (oid):** their Entra object ID. Find it in the Entra admin center under **Users → `<name>` → Overview → Object ID**, or have the user run `az ad signed-in-user show --query id -o tsv` after `az login`.
380380
3. Click **Add user** to save.
381381

382-
Context7 creates a Clerk user record for the developer, adds them as a `developer` member of the teamspace, and inserts a `(tenant, oid, teamspace)` mapping. The same email can be added to multiple teamspaces the Clerk user is reused and a separate mapping row is created per teamspace.
382+
Context7 creates a Clerk user record for the developer, adds them as a `developer` member of the teamspace, and inserts a `(tenant, oid, teamspace)` mapping. The same email can be added to multiple teamspaces; the Clerk user is reused and a separate mapping row is created per teamspace.
383383

384384
<Note>
385385
Clicking **Remove** on the Microsoft Entra ID card removes both the tenant configuration **and** all provisioned users for the teamspace in a single step. If you only need to revoke a single user, remove them from the Microsoft Entra ID users card instead.
386386
</Note>
387387

388388
<Note>
389-
Each MCP API app (audience) can be configured for **one** teamspace at a time. If you reuse an audience already claimed by a different teamspace you will see "This audience is already configured for another teamspace" — open the other teamspace's Settings tab and remove the Entra configuration there first, or register a new MCP API app for this teamspace.
389+
Each MCP API app (audience) can be configured for **one** teamspace at a time. If you reuse an audience already claimed by a different teamspace you will see "This audience is already configured for another teamspace". Open the other teamspace's Settings tab and remove the Entra configuration there first, or register a new MCP API app for this teamspace.
390390
</Note>
391391

392392
<Note>
393-
For more than a handful of developers, prefer **Step 3: Auto-provision from an Entra security group** below — adds and revokes track group membership automatically. CSV bulk-import and SCIM provisioning remain on the roadmap; reach out to [context7@upstash.com](mailto:context7@upstash.com) if your scale needs either ahead of general availability.
393+
For more than a handful of developers, prefer **Step 3: Auto-provision from an Entra security group** below. Adds and revokes track group membership automatically. CSV bulk-import and SCIM provisioning remain on the roadmap; reach out to [context7@upstash.com](mailto:context7@upstash.com) if your scale needs either ahead of general availability.
394394
</Note>
395395

396396
### Step 3: Auto-provision from an Entra security group (optional)
397397

398398
For teams of more than a handful of developers, Context7 can sync the teamspace's user list directly from a Microsoft Entra security group. Members added to the group are added to the teamspace automatically; members removed from the group have their access revoked. The sync runs every 30 minutes; an admin can also trigger an immediate sync from the dashboard.
399399

400-
The integration uses Microsoft Graph with **Workload Identity Federation** (WIF) Context7 acts as an OIDC issuer and signs short-lived JWT assertions that your sync app trusts via a federated credential. No shared secret is stored, rotated, or exchanged on either side.
400+
The integration uses Microsoft Graph with **Workload Identity Federation** (WIF). Context7 acts as an OIDC issuer and signs short-lived JWT assertions that your sync app trusts via a federated credential. No shared secret is stored, rotated, or exchanged on either side.
401401

402402
1. **Add Microsoft Graph permissions** to an Entra app registration.
403403

404-
The simplest path is to reuse the **Context7 MCP API** app from [Part 2 Step 1](#step-1-register-the-mcp-api-app) federated identity holds no secret, so reusing it adds no risk. Open that app and add:
404+
The simplest path is to reuse the **Context7 MCP API** app from [Part 2 Step 1](#step-1-register-the-mcp-api-app): federated identity holds no secret, so reusing it adds no risk. Open that app and add:
405405

406406
- **API permissions****+ Add a permission****Microsoft Graph****Application permissions**.
407407
- Search and tick `GroupMember.Read.All` and `User.ReadBasic.All`.
408408
- **Add permissions**, then click **Grant admin consent for `<your tenant>`** at the top of the list.
409409

410410
<Note>
411-
Both permissions are required. `GroupMember.Read.All` alone returns each user's `oid` with all profile fields nulled out, so the sync can't resolve them to emails and drops them surfacing as `0 members` synced. `User.ReadBasic.All` populates `mail`, `userPrincipalName`, and `displayName`.
411+
Both permissions are required. `GroupMember.Read.All` alone returns each user's `oid` with all profile fields nulled out, so the sync can't resolve them to emails and drops them, surfacing as `0 members` synced. `User.ReadBasic.All` populates `mail`, `userPrincipalName`, and `displayName`.
412412
</Note>
413413

414414
2. **Add a federated credential.**
415415

416-
On the same app: **Certificates & secrets****Federated credentials** tab → **+ Add credential****Federated credential scenario: Other issuer**. Open the Context7 dashboard alongside the Entra portal — the **Auto-provisioning from Entra group** card surfaces three values with copy buttons. Paste them as:
416+
On the same app: **Certificates & secrets****Federated credentials** tab → **+ Add credential****Federated credential scenario: Other issuer**. Open the Context7 dashboard alongside the Entra portal. The **Auto-provisioning from Entra group** card surfaces three values with copy buttons. Paste them as:
417417

418418
- **Issuer**: `https://context7.com`
419419
- **Type**: Explicit subject identifier
@@ -425,7 +425,7 @@ The integration uses Microsoft Graph with **Workload Identity Federation** (WIF)
425425

426426
3. **Create or pick an Entra security group** containing the developers who should have access.
427427

428-
Entra admin center → **Groups****+ New group** (type *Security*, membership type *Assigned*). Add developers as **Members**, not Owners Graph's `/members` endpoint doesn't include group owners by default.
428+
Entra admin center → **Groups****+ New group** (type *Security*, membership type *Assigned*). Add developers as **Members**, not Owners. Graph's `/members` endpoint doesn't include group owners by default.
429429

430430
Open the group → **Overview** → copy the **Object ID**.
431431

@@ -446,7 +446,7 @@ Manually-added users (Step 2) and synced users (Step 3) coexist on the same team
446446
</Note>
447447

448448
<Note>
449-
If you want strict separation of concerns, register a dedicated **Context7 Sync** app instead of reusing the MCP API app. Add the same two Graph permissions and the same federated credential to it, and use its client ID in step 4. The choice is purely organizational both produce identical sync behavior.
449+
If you want strict separation of concerns, register a dedicated **Context7 Sync** app instead of reusing the MCP API app. Add the same two Graph permissions and the same federated credential to it, and use its client ID in step 4. The choice is purely organizational; both produce identical sync behavior.
450450
</Note>
451451

452452
<Note>
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: "Enterprise-Managed Auth with Okta"
3+
sidebarTitle: "Okta"
4+
description: "Centrally authorize the Context7 MCP server for your organization through Okta Cross-App Access, so developers connect on first login with no per-user OAuth."
5+
---
6+
7+
Enterprise-Managed Auth (EMA) lets your Okta administrators decide who can use the Context7 MCP server, in the same console where you manage every other app. Developers sign in once with their corporate Okta account and their MCP client is connected automatically. There is no per-user OAuth consent and no API keys to distribute.
8+
9+
It implements the MCP [Enterprise-Managed Authorization](https://modelcontextprotocol.io/extensions/auth/enterprise-managed-authorization) extension: Okta issues a short-lived Identity Assertion (ID-JAG) for the user, Context7 validates it against your Okta tenant, and resolves the user to your teamspace by email.
10+
11+
<Warning>
12+
Enterprise-Managed Auth currently works with **Claude Code** as the MCP client.
13+
</Warning>
14+
15+
<Note>
16+
Okta Cross-App Access (the productized ID-JAG flow) is an Early Access feature. Enable it from **Admin Console → Settings → Features** before you start. EMA also requires a Context7 enterprise teamspace.
17+
</Note>
18+
19+
## How it works
20+
21+
- A developer signs in to their MCP client with your Okta org.
22+
- The client asks Okta for an ID-JAG scoped to Context7. Okta applies your access policy (group, role, conditional access) and issues it only if the user is allowed.
23+
- The client exchanges the ID-JAG with Context7 for an access token, then calls `mcp.context7.com`.
24+
- Context7 validates the ID-JAG against your tenant and, on first sign-in, provisions the user as a teamspace member automatically (matched by email).
25+
26+
Access is governed entirely in Okta. There is no user list to maintain in Context7: anyone your admin assigns to the connected app is provisioned on first sign-in. Removing them from the app blocks new sign-ins immediately, and any active session ends when its short-lived access token expires (within an hour).
27+
28+
## Before you start
29+
30+
- An **Okta org** with **Cross App Access** enabled.
31+
- A **Context7 enterprise teamspace**. The Enterprise-Managed Auth settings appear only for enterprise plans.
32+
- Developers assigned to the connected Okta app. They are provisioned into the teamspace automatically on first sign-in, so there is no manual user list to maintain.
33+
34+
## Part 1: Configure Okta
35+
36+
### Step 1: Enable Cross App Access
37+
38+
In the **Admin Console**, go to **Settings → Features**, find **Cross App Access** under Early Access, and turn it on.
39+
40+
<Frame>
41+
![Cross App Access toggle in Okta Admin Console Settings → Features](/images/enterprise/enterprise-managed-auth/okta-enable-feature.png)
42+
</Frame>
43+
44+
### Step 2: Add Context7 as a resource app
45+
46+
Go to **Applications → Applications → Browse App Catalog**, search for **XAA Resource App**, and click **Add Integration**.
47+
48+
- **Application label:** `Context7`
49+
- **Issuer URL:** `https://context7.com`
50+
51+
Click **Done**.
52+
53+
<Frame>
54+
![Add XAA Resource App general settings with Context7 label and issuer URL](/images/enterprise/enterprise-managed-auth/okta-resource-app.png)
55+
</Frame>
56+
57+
### Step 3: Add your MCP client as a requesting app
58+
59+
Browse the catalog again, search for **XAA Requesting App**, and click **Add Integration**.
60+
61+
- **Application label:** a name for the MCP client (for example `MCP Client`)
62+
- **Issuer URL:** `https://context7.com`
63+
- **Client ID:** the client identifier the MCP client uses (for example `mcpclient-at-context7`)
64+
65+
Click **Done**, then open the **Sign On** tab and note the Client ID and secret if your client needs them.
66+
67+
<Frame>
68+
![Add XAA Requesting App general settings with label, issuer URL, and client ID](/images/enterprise/enterprise-managed-auth/okta-requesting-app.png)
69+
</Frame>
70+
71+
### Step 4: Connect the two apps
72+
73+
Open the requesting app → **Manage Connections** tab. Under **Apps providing consent**, choose **Add resource apps**, select **Context7**, and **Save**.
74+
75+
<Frame>
76+
![Manage Connections tab linking the MCP Client to the Context7 resource app](/images/enterprise/enterprise-managed-auth/okta-manage-connections.png)
77+
</Frame>
78+
79+
### Step 5: Assign your users
80+
81+
On both apps, open the **Assignments** tab and assign the people (or groups) who should have access. Only assigned users can obtain an ID-JAG.
82+
83+
<Frame>
84+
![Assignments tab assigning a user to the app](/images/enterprise/enterprise-managed-auth/okta-assignments.png)
85+
</Frame>
86+
87+
## Part 2: Configure Context7
88+
89+
Sign in to [context7.com/dashboard](https://context7.com/dashboard), select your enterprise teamspace, open the **Enterprise** tab, and select **Okta**.
90+
91+
- **Identity provider issuer:** your Okta org issuer, for example `https://<your-org>.okta.com`.
92+
- **Scope** (optional): scopes to grant on the issued access token. Leave blank to pass through whatever Okta authorizes.
93+
94+
Click **Configure**, enter the issuer, and **Save**. Context7 validates the issuer against your tenant's OpenID Connect metadata on save.
95+
96+
<Frame>
97+
![Context7 dashboard Enterprise-Managed Auth settings card with the Okta issuer field](/images/enterprise/enterprise-managed-auth/context7-ema-config.png)
98+
</Frame>
99+
100+
<Note>
101+
Use your **org** authorization server issuer (`https://<your-org>.okta.com`), not a custom authorization server. Cross-App Access apps cannot use custom authorization servers.
102+
</Note>
103+
104+
## Part 3: How developers connect
105+
106+
Enterprise-Managed Auth is wired on the **client** side by your organization, not per developer. The Okta sign-in isn't triggered by a server URL someone pastes. It happens because Claude Code is configured to use your enterprise IdP for managed connectors.
107+
108+
Your admin connects the Okta org to Claude and enables the Context7 MCP server (`https://mcp.context7.com/mcp`) as a managed connector. After that, anyone using Claude Code with their corporate Okta identity gets Context7 automatically: Claude Code obtains an ID-JAG from Okta and exchanges it with Context7 for an access token. There is no token to paste and no per-user OAuth.
109+
110+
See Claude's [Enterprise-Managed Auth](https://claude.com/blog/enterprise-managed-auth) documentation for the client-side admin setup.
111+
112+
## Troubleshooting
113+
114+
### `unauthorized_client` / "client cannot use a custom authorization server"
115+
116+
The sign-in or token-exchange used a custom authorization server. Use the org authorization server endpoints (`https://<your-org>.okta.com/oauth2/v1/...`).
117+
118+
### A valid Okta user can't be provisioned
119+
120+
Context7 provisions members from the `email` claim on the ID-JAG, so the connected app must request the `email` scope at sign-in (it's included in the setup above). If provisioning still fails, the teamspace may be at its member limit.
121+
122+
### The user receives no token at all
123+
124+
The user is not assigned to the connected apps in Okta, or the connection between the requesting and resource apps was not saved. Re-check Steps 4 and 5.
125+
126+
## What this does not cover
127+
128+
- **Identity providers other than Okta.** EMA currently supports Okta as the IdP. For Microsoft Entra, see [Microsoft Entra ID](/enterprise/enterprise-managed-auth/entra).
129+
- **Group-based authorization inside Context7.** Okta decides who can obtain a token; Context7 authorizes against teamspace membership. Restricting which libraries a group can access is not configured here.
231 KB
Loading
119 KB
Loading
214 KB
Loading
138 KB
Loading
84.3 KB
Loading
72.8 KB
Loading

0 commit comments

Comments
 (0)