Skip to content

Add agent JWT auth and delegation guides - #1116

Merged
jhrozek merged 6 commits into
mainfrom
rfc8693-delegation-docs
Sep 10, 2026
Merged

Add agent JWT auth and delegation guides#1116
jhrozek merged 6 commits into
mainfrom
rfc8693-delegation-docs

Conversation

@jhrozek

@jhrozek jhrozek commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Description

Adds two vMCP guides covering the embedded authorization server's agent-identity flows:

  • delegate-agent-identity.mdx - RFC 8693 token-exchange delegation with a pre-provisioned delegate client, configured via inboundGrants.tokenExchange.delegateClients and inboundGrants.tokenExchange.issuerPolicies. Covers the three-way consent policy (allowedActors / actorMatcher / allowMayAct), a walked-through exchange with the resulting nested act claim, and secretless private_key_jwt registration.
  • accept-workload-assertions.mdx - the RFC 7523 JWT-bearer grant via inboundGrants.jwtBearer.issuerPolicies, with per-issuer configuration tabs for Okta, Entra, and SPIFFE/SPIRE.

Both are linked from the concepts page and from the vMCP and Kubernetes embedded auth server guides. A new "Minting delegated tokens with delegate clients" section on the concepts page explains why delegation exists and separates minting an act claim from reading one. A new admonition on the Cedar authorization policy reference documents a gotcha found while verifying the demos: the MCP entity doesn't scope per-backend when the Cedar policy lives on a VirtualMCPServer's own authServerConfig.

The existing guides-k8s/embedded-auth-server-k8s.mdx and guides-vmcp/embedded-auth-server-vmcp.mdx pages are updated to the canonical inboundGrants.tokenExchange.delegateClients shape (the flat delegateClients field is deprecated upstream) and gain a Kubernetes-side private_key_jwt DCR section, a trusted-issuer private-CA section, and a worked external-user delegation example.

Field names, CEL admission rule messages, token-endpoint error strings, and the delegated token's claim shape were verified against both the ToolHive source and the (now-current) generated MCPExternalAuthConfig CRD reference.

Type of change

  • New documentation

Related issues/PRs

Refs #1109

Not yet covered, so this does not close the issue:

  • CRD field reference coverage for inboundGrants, issuerPolicies, and allowPrivateKeyJWTRegistration. Those pages are auto-generated from a release asset and land via the release sync, not by hand.
  • AllowClientAssertionAuth (a delegate client authenticating with a self-issued assertion rather than a static secret). The private_key_jwt section is adjacent but covers DCR-registered keypairs, which is a different mechanism.

Reachability note for reviewers

The inboundGrants field shape (and everything under it - tokenExchange.delegateClients, tokenExchange.issuerPolicies, jwtBearer.issuerPolicies) landed on toolhive main via stacklok/toolhive#6499 on 2026-09-07, and is included in the v0.47.0 and v0.47.1 releases (2026-09-08). This branch is rebased onto main after #1141 bumped the toolhive pin to v0.47.0 and re-extracted the CRD schemas, so the generated MCPExternalAuthConfig CRD reference now reflects inboundGrants, issuerPolicies, and allowPrivateKeyJWTRegistration, and every "for the complete field list" cross-link in these guides resolves to current field docs. No follow-up needed on the reachability front.

Submitter checklist

Content and formatting

  • I have reviewed the content for technical accuracy
  • I have reviewed the content for spelling, grammar, and style

Navigation

  • New pages include a frontmatter section with title and description at a minimum
  • Sidebar navigation (sidebars.ts) updated for added, deleted, reordered, or renamed files
  • Redirects added to vercel.json - n/a, no pages moved, renamed, or deleted

Reviewer checklist

Content

  • I have reviewed the content for technical accuracy
  • I have reviewed the content for spelling, grammar, and style

Copilot AI lite review requested due to automatic review settings August 25, 2026 10:52
@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
docs-website Ready Ready Preview Sep 9, 2026 9:21pm UTC

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds new Virtual MCP Server (vMCP) documentation covering embedded auth server agent-identity flows (RFC 8693 delegation and RFC 7523 JWT-bearer), and wires the new guides into navigation and related conceptual context.

Changes:

  • Adds two new vMCP guides: RFC 8693 delegation via delegate clients, and RFC 7523 JWT-bearer workload assertions.
  • Updates the embedded auth server concept page with a new “minting delegated tokens” section and links into the new delegation guide.
  • Updates vMCP and Kubernetes embedded-auth-server guides and the sidebar to surface the new content.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
sidebars.ts Adds the two new vMCP guide pages to the Authentication and authorization section.
docs/toolhive/guides-vmcp/embedded-auth-server-vmcp.mdx Links readers to the new “minting delegated tokens” concepts section for delegation context.
docs/toolhive/guides-vmcp/delegate-agent-identity.mdx New guide documenting RFC 8693 delegation configuration, exchange walkthrough, and troubleshooting.
docs/toolhive/guides-vmcp/accept-workload-assertions.mdx New guide documenting RFC 7523 JWT-bearer grant configuration patterns and troubleshooting.
docs/toolhive/guides-k8s/embedded-auth-server-k8s.mdx Adds a delegation context link to the concepts page from the Kubernetes embedded auth server guide.
docs/toolhive/concepts/embedded-auth-server.mdx Adds a new section explaining why delegation exists and linking to the new delegation guide.
Suppressed comments (5)

docs/toolhive/guides-vmcp/delegate-agent-identity.mdx:252

  • Sentence fragment: "Everything else about the exchange." should be merged into the surrounding sentence so the paragraph reads cleanly.
twice) on the second attempt. Everything else about the exchange. Subject-token
validation against `trustedIssuers`, actor resolution, and the resulting `act`
claim, works exactly as in the pre-provisioned case above; the issued token's

docs/toolhive/guides-vmcp/delegate-agent-identity.mdx:260

  • Section order: these how-to pages are expected to end with "Next steps", then "Related information", then "Troubleshooting" (if present). Here, Troubleshooting appears before Next steps, which makes forward navigation harder.
## Troubleshooting

| Error                                                                                                                                                                                                                            | Likely cause                                                                                                                                                                                                                                                                                                    |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `invalid_client` (exact hint varies by cause: wrong secret, wrong `token_endpoint_auth_method`, or a public client attempting a confidential-only grant)                                                                         | The delegate client must be confidential. Verify `delegateClients[].clientSecretRef` is set and the client authenticated with the matching secret and method.                                                                                                                                                   |

docs/toolhive/guides-vmcp/accept-workload-assertions.mdx:31

  • Reachability: this guide documents trustedIssuers[].jwtBearerGrant, which the PR description calls out as not yet in a released ToolHive version and not present in the pinned docs sync (ToolHive v0.43.0 in .github/upstream-projects.yaml:45-48). Add an availability note so readers don't assume it's available in their current install.
    docs/toolhive/guides-vmcp/accept-workload-assertions.mdx:142
  • Section order: these how-to pages are expected to end with "Next steps", then "Related information", then "Troubleshooting" (if present). Here, Troubleshooting appears before Next steps, which makes forward navigation harder.
## Troubleshooting

Two things vary by issuer and are worth checking first if an exchange fails:
whether the assertion carries a `jti` at all (Entra's `client_credentials`
tokens and plain SPIRE JWT-SVIDs never include one, so ToolHive falls back to

docs/toolhive/guides-vmcp/delegate-agent-identity.mdx:29

  • Reachability: this docs repo is currently pinned to ToolHive v0.43.0 (.github/upstream-projects.yaml:45-48), but this guide references fields called out in the PR description as only on newer/unreleased ToolHive versions (e.g., actorMatcher, allowMayAct, allowPrivateKeyJWTRegistration). Add a short availability note so readers don't try to follow steps that their installed CRDs don't support yet.

## Overview

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/toolhive/concepts/embedded-auth-server.mdx Outdated
Comment thread docs/toolhive/guides-vmcp/delegate-agent-identity.mdx Outdated
Comment thread docs/toolhive/guides-vmcp/accept-workload-assertions.mdx Outdated
jhrozek and others added 5 commits September 9, 2026 12:46
Add two vMCP guides covering the embedded auth server's agent-identity
flows: RFC 8693 token-exchange delegation with a pre-provisioned delegate
client, and the RFC 7523 JWT-bearer grant for clientless workload
assertions. Link both from the concepts page and the vMCP and Kubernetes
embedded auth server guides.

Field names, CEL admission rules, error strings, and the delegated token's
claim shape were verified against the ToolHive source.

Refs #1109

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fold three explanations from the v0.44.0 release-sync branch into the
delegation guide: that a trustedIssuers entry alone doesn't create a usable
exchange path without a delegate client to authenticate, why
allowedDelegateClients binds an external actor to a specific client, and that
"client_id" is a sentinel rather than a claim name.

Point at the generated MCPExternalAuthConfig schema reference for the full
trustedIssuers field list instead of restating it, and repoint the vMCP and
Kubernetes guide cross-references at the delegation guide.

Refs #1109

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Docs used the pre-refactor trustedIssuers/delegateClients field
shape, which no longer matches the CRD. Also fold in gotchas found
while live-verifying the RFC 8693/7523 demos: the allowMayAct CEL
bug, the MCP:: Cedar entity scoping to the VirtualMCPServer's own
name rather than per-backend, and the still-required placeholder
upstreamProviders for JWT-bearer-only configs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reorder Next steps/Related information/Troubleshooting to match
the required closing-section order on the two new vMCP guides, fix
a "let X to Y" grammar slip, a sentence fragment, and stray em
dashes in the new delegation content.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jhrozek
jhrozek force-pushed the rfc8693-delegation-docs branch from e3a133b to 5f71152 Compare September 9, 2026 10:48
@jhrozek
jhrozek marked this pull request as ready for review September 9, 2026 10:52

@danbarr danbarr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Summary

Needs changes. The PR is structurally reachable and current CI is green, but the two new guides add too much overlapping selection and implementation detail to an already dense auth area. The JWT-bearer guide also needs a clearer, executable path.

Primary issues

1. Make the JWT-bearer guide a runnable workflow

accept-workload-assertions.mdx:40 presents the /oauth/token request before configuration. The Okta tab is a full VirtualMCPServer fragment, but the Entra and SPIRE tabs begin at trustedIssuers (lines 91 and 124), leaving readers to infer nesting and merge behavior.

Ask: Configure first, request a token second. Either make every tab a complete, consistently nested resource or label all examples as merge-in fragments and show their insertion point.

The required-placeholder section also says the upstream endpoint must be reachable while its example uses example.invalid (line 157). Replace it with a working limitation/workaround or remove the reachability claim.

2. Establish one place to choose a mechanism

The RFC 8693 page contains a four-row mechanism comparison (delegate-agent-identity.mdx:31); the JWT-bearer page immediately directs readers back to it to make the same choice (accept-workload-assertions.mdx:32). Both pages then repeat most Next steps links in Related information, while the concepts page duplicates a substantial delegation explanation and configuration summary (embedded-auth-server.mdx:152).

Ask: Keep selection guidance in the vMCP authentication overview, make the two guides task-only, remove duplicated related links, and reduce the concepts-page addition to a short conceptual distinction plus the guide link.

Secondary issues

  • Replace the opening at accept-workload-assertions.mdx:12 with a direct outcome: "Use the RFC 7523 JWT-bearer grant to let a trusted workload exchange a signed assertion for a ToolHive token. The workload does not need a ToolHive client registration or shared secret."
  • Replace engineering jargon: "same shape" → "same configuration structure"; "token shape" → "token claims" (delegate-agent-identity.mdx:107); "claim shape" → "delegation chain" (embedded-auth-server.mdx:165).
  • Trim internal framing such as "orthogonal," "what actually authorizes," and validation-rule implementation detail, especially delegate-agent-identity.mdx:63.

Comment thread docs/toolhive/guides-vmcp/accept-workload-assertions.mdx Outdated
Comment thread docs/toolhive/guides-vmcp/delegate-agent-identity.mdx Outdated
Reorder the JWT-bearer guide to configure before requesting a
token, consolidate the duplicated mechanism-comparison table into
one place, dedupe Next steps/Related information links, fix a
reachability contradiction in the upstream placeholder workaround,
and apply word-list and jargon fixes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jhrozek

jhrozek commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

@danbarr Addressed the review in dbe2d61:

Primary issue 1 — runnable JWT-bearer workflow: reordered accept-workload-assertions.mdx into "Configure a trusted issuer" (all three tabs now consistently nested fragments under spec.authServerConfig, Okta's wrapper stripped to match Entra/SPIRE) followed by "Request a token" (the /oauth/token example). Also fixed the example.invalid reachability contradiction — the placeholder note now says ToolHive never contacts that endpoint, so any syntactically valid URL works.

Primary issue 2 — one place to choose a mechanism: the 4-row comparison table moved out of delegate-agent-identity.mdx into embedded-auth-server-vmcp.mdx under a new "Choose a way to get a token" subsection; both guides now link to it instead of repeating it. Also deduped Next steps/Related information links in both new guides, and trimmed the duplicated delegation-rationale paragraph on the concepts page down to one sentence.

Secondary issues: applied the opening-paragraph rewrite and both description-field suggestions verbatim, and swapped the flagged jargon ("same shape" → "same configuration structure", "token shape" → "token claims", "claim shape" → "delegation chain", "orthogonal to" → "separate from", "what actually authorizes" trimmed).

prettier, eslint, and npm run build all pass clean. Ready for another look.

@jhrozek
jhrozek merged commit 5e68d7d into main Sep 10, 2026
14 checks passed
@jhrozek
jhrozek deleted the rfc8693-delegation-docs branch September 10, 2026 09:27
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.

3 participants