Skip to content

Add IdP integration guides for vMCP (Entra ID and Okta)#810

Merged
jhrozek merged 14 commits into
mainfrom
entra-guides
May 5, 2026
Merged

Add IdP integration guides for vMCP (Entra ID and Okta)#810
jhrozek merged 14 commits into
mainfrom
entra-guides

Conversation

@jhrozek
Copy link
Copy Markdown
Contributor

@jhrozek jhrozek commented Apr 27, 2026

Summary

  • Adds step-by-step guides for connecting a VirtualMCPServer to Microsoft Entra ID and Okta using the embedded OAuth 2.0 authorization server
  • The guides cover the full setup path: configure the IdP to include group/role membership in access tokens, deploy the VirtualMCPServer with the embedded auth server as the broker, and write Cedar policies that map IdP groups to fine-grained per-tool access control
  • Adds a lightweight landing page (vmcp-idp-overview.mdx) as an IdP picker with prerequisites, linking to the per-IdP guides

Closes #407

Files added

  • integrations/vmcp-idp-overview.mdx — landing page, prerequisites, IdP picker
  • integrations/vmcp-entra-id.mdx — app registration, API scope exposure, App Roles, user/group assignments, VirtualMCPServer YAML; all portal steps have CLI equivalents in collapsible blocks; uses the roles claim
  • integrations/vmcp-okta.mdx — custom authorization server, OIDC app, groups scope and claim, access policy, VirtualMCPServer YAML; uses the groups claim; documents API Access Management add-on requirement

Both guides include consistency checklists (group name matching across IdP, claim filter, and Cedar policies), deployment steps, and troubleshooting sections.

Files updated

  • guides-vmcp/authentication.mdx and guides-vmcp/intro.mdx — inbound links to the new guides
  • sidebars.ts — nested "Identity provider integration" sub-category under Integrations

Test plan

  • npm run build passes with no new broken anchors
  • IdP integration sub-category appears in the sidebar under Integrations
  • Overview page links to both IdP-specific guides
  • Both guides link forward to Cedar policies and auth framework docs
  • CLI collapsibles in the Entra guide render and collapse correctly

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings April 27, 2026 21:40
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs-website Ready Ready Preview, Comment May 1, 2026 10:20am

Request Review

Copy link
Copy Markdown
Collaborator

@danbarr danbarr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR adds a useful set of IdP integration guides that fill a real gap (full end-to-end Entra ID and Okta walkthroughs for vMCP with the embedded auth server). The structure is solid and the troubleshooting and CLI-equivalent details show real subject matter expertise. I have one IA decision that's worth making before merge, plus a handful of editorial issues.

Question on scope

The PR also pins-to-caret-bumps the @docusaurus/* deps in package.json from 3.10.0 to ^3.10.0. That's unrelated to this PR, did it come along accidentally? The versions are deliberately pinned.

Primary issues

1. Sidebar collision between two "Okta" pages in Integrations

After this PR, the Integrations sidebar contains both:

  • "Role-based authorization with Okta" → integrations/okta.mdx (existing tutorial: single MCPServer + RBAC)
  • "Identity provider integration" → "Connect ToolHive to Okta" → integrations/vmcp-okta.mdx (new: vMCP + embedded auth server)

A reader looking for "Okta integration" sees two siblings with overlapping titles and no signposting between them. The two guides cover genuinely different scenarios, but the navigation does not communicate that. Decide on a navigation story:

  • Move/rename the existing okta.mdx under the new "Identity provider integration" category (e.g., as "Single MCPServer with Okta RBAC") so all Okta content sits together, or
  • Rename the new page to make the distinction explicit in the sidebar (e.g., "Okta with vMCP and embedded auth server"), and add a cross-link at the top of each Okta page pointing at the other.

Either way, vmcp-idp-overview.mdx should mention the existing okta.mdx tutorial as the "single backend / no vMCP" alternative, since today it only routes readers to the two new guides and to the generic vMCP authentication doc.

2. Misleading link target on first mention of VirtualMCPServer

vmcp-entra-id.mdx (lines 8-9):

This guide covers the full setup for connecting a VirtualMCPServer to Microsoft Entra ID.

The anchor text "VirtualMCPServer" links to the authentication guide, but a reader clicking it expects a definition of what a VirtualMCPServer is. Either link to guides-vmcp/intro.mdx (which actually introduces the concept), drop the link, or rephrase so the link text matches the destination ("connecting vMCP authentication to Microsoft Entra ID"). The Okta guide doesn't have an equivalent intro link, so the two guides are out of sync on this opening either way.

3. Em dashes throughout new content

Project style guide forbids em dashes; pre-commit/Prettier won't catch these. There are 11 occurrences across the two guides:

  • vmcp-entra-id.mdx: lines 467, 500
  • vmcp-okta.mdx: lines 41, 59, 70, 97, 128, 155, 293, 329, 330

Replace each with commas, period+new sentence, or restructure as the style guide describes.

4. Unintroduced acronym: "Org Authorization Server"

vmcp-okta.mdx (lines 26-29):

You must use a custom authorization server (not the Org Authorization Server). The Org AS cannot add groups claims to access tokens...

"Org Authorization Server" is an Okta-specific concept that's never defined for the reader. Add a one-sentence definition the first time it appears (e.g., "the default Org Authorization Server that ships with every Okta tenant"), and pick one term ("Org Authorization Server" or "Org AS") instead of mixing.

Secondary issues

Issue Recommendation
vmcp-okta.mdx lines 7-9 - circular opening: "Okta Groups are the standard mechanism for group-based access control in Okta." Tighten: "This guide uses Okta Groups to place group values in the groups claim of the access token, which vMCP uses for Cedar policy evaluation."
Front-matter description on vmcp-okta.mdx is short (~75 chars) and the vmcp-idp-overview.mdx description cuts mid-word at the 70-char DocCard boundary Expand the Okta description (e.g., add "with the embedded auth server"). For the overview, lead with reader value before implementation detail: "Connect ToolHive to your corporate IdP so MCP clients authenticate with existing credentials and group memberships."
Duplicate "should have its own app registration" warning in vmcp-entra-id.mdx (lines 351-357) and vmcp-okta.mdx (lines 177-184), with the Okta version pointing at the overview page that doesn't elaborate Move this guidance to the overview page once and link to it from both, or drop the link in the Okta version since it doesn't lead anywhere meaningful
Two :::warning admonitions stacked back-to-back at vmcp-entra-id.mdx lines 344-357 Promote the rename-assignments rule to body prose under the Consistency checklist; keep one warning
:::warning[Gotcha] heading at vmcp-okta.mdx line 100 - "Gotcha" is informal Use a neutral title like "Filter type matters" or no custom title
Placeholder inconsistency in vmcp-entra-id.mdx: <client-id> (lowercase) in URL contexts, <YOUR_CLIENT_ID> (allcaps) in YAML Pick one casing per the project rule that placeholders use <ALL_CAPS>; if <client-id> is intentional because it mirrors an Entra-rendered URI, add a one-line note explaining why
Namespace handling - the YAML manifests have no namespace set, but the kubectl create secret step uses -n <your-namespace> Either add namespace: <your-namespace> to each resource or add a one-line note that all resources are assumed to live in the same namespace
vmcp-idp-overview.mdx "Next steps" links only to two concept pages Add a forward-momentum link to "Connect clients to MCP servers", matching the pattern in the per-IdP guides
Inbound coverage: the new pages are reachable from the vMCP intro and authentication guide, but not from the vMCP quickstart "What's next?" or from auth-k8s.mdx (which currently only points at the existing okta.mdx) Add a "Next steps" link from the vMCP quickstart and a sibling link in auth-k8s.mdx alongside the existing Okta tutorial reference

What works well

  • The "What you'll need" checklist at the top of each provider guide is genuinely useful and uncommon in this doc set; it gives readers a place to collect values as they go.
  • The <details>-collapsed CLI equivalents are well-judged: portal walkthrough is the primary path, automation is available without crowding the page.
  • The Consistency checklists in both guides catch the single most common failure mode (role/group name mismatch across three places). This is the kind of subject-matter detail that's hard for an LLM to invent and clearly came from real setup experience.
  • The Cedar policy block, including the deny-overrides example for delete_namespace, gives readers a meaningful starting point rather than a bare permit(...).

Comment thread package.json
jhrozek and others added 2 commits April 30, 2026 14:29
Teams running VirtualMCPServer on Kubernetes want to use their existing
corporate SSO (Entra ID or Okta) instead of maintaining a separate
credential store. These guides cover the full setup: configuring the IdP
to issue group membership in access tokens, deploying the VirtualMCPServer
with the embedded auth server as the broker, and writing Cedar policies
that map IdP groups to fine-grained per-tool access control.

Three new pages under integrations/:

- vmcp-idp-overview.mdx: landing page with prerequisites and IdP picker
- vmcp-entra-id.mdx: app registration, API scope exposure, App Roles,
  user/group assignments, VirtualMCPServer YAML; all portal steps have
  CLI equivalents in collapsible blocks; uses the roles claim
- vmcp-okta.mdx: custom authorization server, OIDC app, groups scope and
  claim, access policy, VirtualMCPServer YAML; uses the groups claim;
  documents API Access Management add-on requirement for custom AS

Both guides include consistency checklists (group name matching across
IdP, claim filter, and Cedar policies), deploy steps with a Kubernetes
secret for the client secret, and troubleshooting sections covering the
most common configuration mistakes.

Also: inbound links from guides-vmcp/authentication.mdx and intro.mdx,
nested "Identity provider integration" sub-category in sidebars.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cross-link Okta tutorial and vMCP Okta guide
@jhrozek
Copy link
Copy Markdown
Contributor Author

jhrozek commented Apr 30, 2026

Re: Primary #1 — Sidebar collision between two "Okta" pages

Addressed in a29e866.

I went with the "rename + cross-link" path rather than moving the existing tutorial. The existing integrations/okta.mdx is really a generic OIDC RBAC tutorial that uses Okta as the worked example (it explicitly says the pattern applies to any provider) — moving it under "Identity provider integration" would mislabel it. The sidebar labels are already distinct ("Role-based authorization with Okta" vs "Connect ToolHive to Okta"), so I kept those and added the missing signposting:

  • vmcp-idp-overview.mdx now has a :::note linking to okta.mdx as the "single backend without vMCP" alternative
  • vmcp-okta.mdx has a :::note near the top linking to the existing tutorial
  • okta.mdx has a reciprocal :::note linking to the new vMCP guide

Repoint VirtualMCPServer link to vMCP intro
@jhrozek
Copy link
Copy Markdown
Contributor Author

jhrozek commented Apr 30, 2026

Re: Primary #2 — Misleading link target on VirtualMCPServer

Addressed in 747a2a7.

Repointed the Entra guide's VirtualMCPServer link to guides-vmcp/intro.mdx (which actually defines the concept). Also rephrased the Okta guide's intro to add the same parallel link, so the two guides now open the same way.

Replace em dashes per style guide
@jhrozek
Copy link
Copy Markdown
Contributor Author

jhrozek commented Apr 30, 2026

Re: Primary #3 — Em dashes

Addressed in 2bc5cc0. All 12 occurrences across vmcp-entra-id.mdx and vmcp-okta.mdx replaced with periods (sentence splits), commas, colons, or restructured prose per the style guide. Verified clean with grep.

jhrozek added 10 commits April 30, 2026 22:04
Define Org authorization server on first use
Tighten Okta intro to avoid circular phrasing
Tighten front matter descriptions
Centralize 'one app per vMCP' guidance in overview
Promote rename-assignments rule to prose
Replace 'Gotcha' admonition title with neutral wording
Note same-namespace assumption for deploy section
Add connect-clients link to overview Next steps
Add inbound links from vMCP quickstart and auth-k8s

:::note[Single backend without vMCP?]

If you only need to authenticate users to a single MCPServer (no aggregation, no
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in a29e866. Took the rename + cross-link path: the existing integrations/okta.mdx is really a generic OIDC RBAC tutorial that uses Okta as the worked example, so moving it under "Identity provider integration" would mislabel it. Kept the sidebar labels distinct ("Role-based authorization with Okta" vs "Connect ToolHive to Okta") and added cross-links: this overview flags the existing tutorial as the single-backend alternative, and both Okta pages link to each other.

---

This guide covers the full setup for connecting a
[VirtualMCPServer](../guides-vmcp/intro.mdx) to Microsoft Entra ID. App Roles
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 747a2a7. Repointed to guides-vmcp/intro.mdx (which actually defines the concept). Also added a parallel intro sentence to the Okta guide so the two open the same way.


:::note

Creating a custom authorization server requires the Okta API Access Management
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 2bc5cc0. All 12 occurrences across both guides replaced with periods, commas, colons, or restructured prose per the style guide. Verified clean with grep.

### Step 1: Create a custom authorization server

You **must** use a custom authorization server, not the
[Org authorization server](https://developer.okta.com/docs/concepts/auth-servers/#org-authorization-server).
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in d07f9cd. Replaced with a definition on first use linking to the canonical Okta concepts page. Switched to sentence case ("Org authorization server") matching Okta's own usage, dropped the "Org AS" abbreviation, and reframed the reason — per the linked Okta docs, the actual constraint is broader than just groups claims (the Org AS is not designed for external resource server validation, and is non-customizable).

---

This guide covers the full setup for connecting a
[VirtualMCPServer](../guides-vmcp/intro.mdx) to Okta. Okta Groups are the
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in b8e4141. Tightened the opening to drop the "in Okta... in Okta" circularity.

---
title: Connect ToolHive to an enterprise identity provider
description:
Connect ToolHive to your corporate IdP so MCP clients authenticate with
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 7a4203a. Rewrote all three descriptions to lead with reader value, with the first 70 characters meaningful at the DocCard cutoff. Also rewrote the Entra description for parallelism (not flagged, but inconsistent with the others).

:::

## One application per VirtualMCPServer

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9bc4000. Moved the rule to a dedicated "One application per VirtualMCPServer" section in the overview; both per-IdP warnings now contain a single sentence pointing here.

3. **Cedar policies** (see [Deploy to ToolHive](#deploy-to-toolhive)):
`THVGroup::"mcp-developers"` must match the app role Value exactly

Changing the Value in place 1 does not update existing assignments in place 2.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 147f966. Promoted the rename-assignments rule to body prose under the Consistency checklist; the only remaining warning is the "one app per vMCP" pointer (per Secondary #7).

every access token. Note that the groups claim has a hard limit of 100 groups.
If the filter matches more than 100, the token request fails.

:::warning[Filter type matters]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in cc596a9. Renamed to :::warning[Filter type matters]. Also updated the cross-reference in Troubleshooting that previously said "see step 4 gotcha".

- [ ] Application (client) ID
- [ ] Client Secret
- [ ] Tenant ID
- [ ] Application ID URI (e.g. `api://<CLIENT_ID>`)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in fc3314b. Normalized all placeholders to ALL_CAPS without YOUR_ prefix: <CLIENT_ID>, <TENANT_ID>, <CLIENT_SECRET>, <VMCP_ENDPOINT>, <NAMESPACE>, <OKTA_DOMAIN>. Also caught a stray {tenant-id} (curly braces, lowercase) in the same pass.


## Deploy to ToolHive

All resources in this section are assumed to live in the same namespace. Either
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 7047883. Added a short note at the top of "Deploy to ToolHive" in both guides telling the reader that all resources are assumed to live in the same namespace, and to either set namespace: on each resource or use kubectl apply -n <NAMESPACE>.


## Next steps

- [Connect clients to MCP servers](../guides-k8s/connect-clients.mdx)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 7cffe12. Added "Connect clients to MCP servers" to the overview Next steps.

backends into a single endpoint.

- [Configure authentication](../guides-vmcp/authentication.mdx) for production
- [Connect ToolHive to an enterprise identity provider](../integrations/vmcp-idp-overview.mdx)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in dd8b4af. Added a forward link from the vMCP quickstart Next steps and a sibling reference in guides-k8s/auth-k8s.mdx next to the existing okta.mdx link.

Copy link
Copy Markdown
Collaborator

@danbarr danbarr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, and honestly this is exactly the kind of scenario-based structure that I think more of our auth docs could benefit from. The "values to collect as you go" checklist at the top, the consistency checklists for matching role/group names across IdP and Cedar, and the cross-links to the existing Okta tutorial do a lot of heavy lifting for readers. CLI collapsibles are a nice touch too. Thanks for addressing the initial review!

@jhrozek jhrozek merged commit a41410b into main May 5, 2026
30 checks passed
@jhrozek jhrozek deleted the entra-guides branch May 5, 2026 09:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Gap]: Improve Entra ID authentication docs for ToolHive

2 participants