Skip to content

Document vMCP embedded auth server and upstream token injection#643

Draft
jhrozek wants to merge 3 commits intomainfrom
vmcp-authserver
Draft

Document vMCP embedded auth server and upstream token injection#643
jhrozek wants to merge 3 commits intomainfrom
vmcp-authserver

Conversation

@jhrozek
Copy link
Copy Markdown
Contributor

@jhrozek jhrozek commented Mar 27, 2026

Summary

  • Document the embedded authorization server for vMCP, including multi-upstream provider support and sequential authorization chaining
  • Document the upstream_inject outgoing auth strategy (vMCP-only)
  • Document subjectProviderName on token exchange for hybrid deployments
  • Update related docs to reflect multi-upstream capability and add cross-references

Closes #642

Draft: This PR is a draft because the upstream ToolHive CRD changes are not fully released yet. PRs stacklok/toolhive#4390, stacklok/toolhive#4391, and stacklok/toolhive#4394 are approved but not yet merged. This documentation should be reviewed and finalized after those PRs land.

Changes

docs/toolhive/guides-vmcp/authentication.mdx (main work):

  • Added "Upstream token injection" section (upstreamInject outgoing auth strategy)
  • Added "Token exchange with upstream tokens" section (subjectProviderName)
  • Added "Embedded authorization server" section with sequence diagram, differences from MCPServer, config skeleton, incoming auth wiring, session storage, and end-to-end example
  • Cross-references existing guides for shared content (key generation, session storage, upstream provider details) to avoid duplication

docs/toolhive/concepts/vmcp.mdx:

  • Added embedded auth server paragraph under "Authentication boundary separation"
  • Fixed "four key benefits" to "five"

docs/toolhive/concepts/backend-auth.mdx:

  • Updated "single upstream provider" to clarify it applies to MCPServer only
  • Removed outdated "chained authentication not yet supported" admonition
  • Added cross-reference to vMCP embedded auth server guide

docs/toolhive/guides-k8s/auth-k8s.mdx:

  • Added cross-reference to vMCP embedded auth server in related information

Test plan

  • npm run build passes
  • Verify YAML examples match final CRD field names after upstream PRs merge
  • Review sequence diagram accuracy against implementation
  • Test cross-references resolve correctly in rendered site

🤖 Generated with Claude Code

jhrozek and others added 3 commits March 12, 2026 22:45
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>
Copilot AI review requested due to automatic review settings March 27, 2026 16:33
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 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 Mar 27, 2026 4:35pm

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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.

Comment on lines +378 to +379
Each upstream provider `name` must be a valid DNS label (lowercase alphanumeric
and hyphens, max 63 characters). This name is what
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
Comment on lines +414 to +419
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.
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
```

The next section deploys a three-node Sentinel cluster that monitors the Redis
master and handles automatic failover:
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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:

Copilot uses AI. Check for mistakes.
outgoingAuth:
source: inline
backends:
backend-github:
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

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).

Suggested change
backend-github:
backend-github:
type: external_auth_config_ref

Copilot uses AI. Check for mistakes.
Comment on lines +259 to +262
backend-github:
externalAuthConfigRef:
name: inject-github
backend-okta-app:
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
outgoingAuth:
source: inline
backends:
backend-github:
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

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).

Suggested change
backend-github:
backend-github:
type: external_auth_config_ref

Copilot uses AI. Check for mistakes.
Comment on lines +390 to +405
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
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

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).

Copilot uses AI. Check for mistakes.
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.

Document vMCP embedded authorization server and upstream token injection

2 participants