Document vMCP embedded auth server and upstream token injection#643
Document vMCP embedded auth server and upstream token injection#643
Conversation
Add a new how-to guide at docs/toolhive/guides-k8s/redis-session-storage.mdx that walks through deploying Redis Sentinel as the session storage backend for the embedded authorization server. The guide uses self-contained Kubernetes manifests instead of the Bitnami Helm chart, which Broadcom moved behind a paid subscription in August 2025. No maintained, freely available Helm chart with Sentinel support exists as a replacement, so the manifests are provided inline. Also adds TLS configuration documentation for Redis connections (both master and Sentinel), updates the auth-k8s guide's session storage snippet for consistency, and resolves a merge conflict in backend-auth.mdx. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace <REDIS_ACL_PASSWORD> with YOUR_REDIS_ACL_PASSWORD (no angle brackets) to avoid confusing ><PLACEHOLDER> syntax in Redis ACL entries. Remove unused vercel.json redirect since the page was never published at the old integrations/ path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Closes #642 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Updates ToolHive documentation to describe vMCP’s embedded authorization server capabilities (including multi-upstream flows) and how upstream tokens can be forwarded/exchanged for backend authentication, plus adds a Redis Sentinel session storage guide.
Changes:
- Document vMCP “upstream token injection” (
upstreamInject) and token exchange with upstream subject tokens (subjectProviderName). - Add embedded authorization server documentation for vMCP (flow, differences vs MCPServer, config examples, and end-to-end walkthrough).
- Add a new Redis Sentinel session storage tutorial and cross-link it from related docs/sidebars.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| sidebars.ts | Adds the new Redis session storage guide to the K8s guides sidebar. |
| docs/toolhive/guides-vmcp/authentication.mdx | Main vMCP auth guide expansion: upstream injection, upstream-subject token exchange, and embedded auth server docs. |
| docs/toolhive/guides-k8s/redis-session-storage.mdx | New end-to-end tutorial for Redis Sentinel-backed session storage. |
| docs/toolhive/guides-k8s/auth-k8s.mdx | Adds a “Configure session storage” section and links to the new Redis guide. |
| docs/toolhive/concepts/vmcp.mdx | Mentions embedded auth server support and fixes benefit count wording. |
| docs/toolhive/concepts/backend-auth.mdx | Updates statements about upstream provider limits and adds cross-references to vMCP docs + session storage docs. |
| Each upstream provider `name` must be a valid DNS label (lowercase alphanumeric | ||
| and hyphens, max 63 characters). This name is what |
There was a problem hiding this comment.
The doc states each upstream provider name “must be a valid DNS label (lowercase alphanumeric and hyphens, max 63 characters)”, but the published CRD reference for UpstreamProviderConfig.name only enforces a minimum length (no DNS-label pattern). Unless there’s an implementation constraint not reflected in the CRD, this should be softened to a recommendation or updated to match the actual validation.
| Each upstream provider `name` must be a valid DNS label (lowercase alphanumeric | |
| and hyphens, max 63 characters). This name is what | |
| Each upstream provider `name` should be a short, DNS-label-style identifier | |
| (lowercase alphanumeric and hyphens, ideally max 63 characters). This name is what |
| By default, upstream tokens are stored in memory and lost on pod restart. For | ||
| production, configure Redis Sentinel by adding a `storage` block to | ||
| `authServerConfig`. The configuration is the same as for the MCPServer embedded | ||
| auth server. See | ||
| [Redis Sentinel session storage](../guides-k8s/redis-session-storage.mdx) for a | ||
| complete walkthrough. |
There was a problem hiding this comment.
This section points readers to the Redis Sentinel session storage guide, but that guide’s configuration examples are written for the MCPServer flow (MCPExternalAuthConfig.spec.embeddedAuthServer.storage), not vMCP’s inline VirtualMCPServer.spec.authServerConfig.storage. Consider adding a short vMCP-specific storage snippet here (or updating the Redis guide) so readers don’t copy/paste an invalid structure.
| ``` | ||
|
|
||
| The next section deploys a three-node Sentinel cluster that monitors the Redis | ||
| master and handles automatic failover: |
There was a problem hiding this comment.
This section says the Sentinel cluster “handles automatic failover”, but the provided manifests only deploy a single Redis master (replicas: 1) and no replicas, so failover can’t actually occur in this example. Consider clarifying that the example provides persistent storage + master discovery, and that automatic failover requires configuring Redis replicas.
| master and handles automatic failover: | |
| master and can coordinate automatic failover when Redis replicas are configured. | |
| In this minimal example with a single Redis master (`replicas: 1`), Sentinel | |
| provides health monitoring and master discovery, but no actual failover: |
| outgoingAuth: | ||
| source: inline | ||
| backends: | ||
| backend-github: |
There was a problem hiding this comment.
In this VirtualMCPServer outgoing auth example, the backend entry is missing the required type field (e.g., type: external_auth_config_ref) for BackendAuthConfig. As written, the YAML won’t match the current CRD/schema and differs from other vMCP docs (e.g., backend-discovery guide).
| backend-github: | |
| backend-github: | |
| type: external_auth_config_ref |
| backend-github: | ||
| externalAuthConfigRef: | ||
| name: inject-github | ||
| backend-okta-app: |
There was a problem hiding this comment.
This combined-outgoing-auth example also omits the required type discriminator for each backend’s auth config (e.g., external_auth_config_ref). Without it, the snippet won’t validate against the CRD and may mislead readers.
| backend-github: | |
| externalAuthConfigRef: | |
| name: inject-github | |
| backend-okta-app: | |
| backend-github: | |
| type: external_auth_config_ref | |
| externalAuthConfigRef: | |
| name: inject-github | |
| backend-okta-app: | |
| type: external_auth_config_ref |
| outgoingAuth: | ||
| source: inline | ||
| backends: | ||
| backend-github: |
There was a problem hiding this comment.
In the complete VirtualMCPServer example, outgoingAuth.backends.backend-github is missing the required type field for BackendAuthConfig (the CRD expects type: external_auth_config_ref when externalAuthConfigRef is used).
| backend-github: | |
| backend-github: | |
| type: external_auth_config_ref |
| When using the embedded auth server, configure `incomingAuth` to validate the | ||
| JWTs it issues. The `issuer` must match `authServerConfig.issuer`, and | ||
| `jwksAllowPrivateIP` must be `true` because the vMCP validates tokens from its | ||
| own in-process auth server via loopback: | ||
|
|
||
| ```yaml title="VirtualMCPServer resource" | ||
| spec: | ||
| incomingAuth: | ||
| type: oidc | ||
| resourceUrl: https://mcp.example.com/mcp | ||
| oidcConfig: | ||
| type: inline | ||
| inline: | ||
| issuer: https://auth.example.com | ||
| audience: https://mcp.example.com/mcp | ||
| jwksAllowPrivateIP: true |
There was a problem hiding this comment.
The text says jwksAllowPrivateIP “must” be true because validation happens via loopback. jwksAllowPrivateIP is specifically about allowing JWKS/OIDC endpoints that resolve to private IPs; if the configured issuer is public (as in the example), this may be unnecessary and the “must”/loopback rationale is likely inaccurate. Consider rewording to describe when it’s actually required (e.g., only when the issuer/JWKS endpoint is in-cluster/localhost/private IP).
Summary
upstream_injectoutgoing auth strategy (vMCP-only)subjectProviderNameon token exchange for hybrid deploymentsCloses #642
Changes
docs/toolhive/guides-vmcp/authentication.mdx(main work):upstreamInjectoutgoing auth strategy)subjectProviderName)docs/toolhive/concepts/vmcp.mdx:docs/toolhive/concepts/backend-auth.mdx:docs/toolhive/guides-k8s/auth-k8s.mdx:Test plan
npm run buildpasses🤖 Generated with Claude Code