Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/upstream-projects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ projects:

- id: toolhive
repo: stacklok/toolhive
version: v0.57.0
version: v0.58.0
# toolhive is a monorepo covering the CLI, the Kubernetes
# operator, and the vMCP gateway. It also introduces cross-
# cutting features that land in concepts/, integrations/,
Expand Down
11 changes: 11 additions & 0 deletions docs/toolhive/concepts/embedded-auth-server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,17 @@ If the refresh token is also expired or has been revoked by the upstream
provider, ToolHive returns a `401` response, prompting re-authentication through
the OAuth flow.

ToolHive also checks the upstream credential when an MCP client redeems its own
ToolHive refresh token. Before issuing new tokens, the embedded authorization
server reads the session's stored upstream tokens and refreshes any that have
expired. If the upstream credential is no longer usable (for example, the
provider rejects the refresh with `invalid_grant`, or no upstream refresh token
is stored), the token endpoint responds with HTTP `400` and `invalid_grant`.
This sends the client through a full authorization instead of looping on
refreshed tokens that still fail with `401`. When the outcome is uncertain, such
as a network error, a `5xx` or `429` response from the provider, or a check that
takes longer than 10 seconds, ToolHive issues the new tokens.

## Key characteristics

- **In-process execution:** The authorization server runs within the ToolHive
Expand Down
14 changes: 8 additions & 6 deletions docs/toolhive/guides-vmcp/delegate-agent-identity.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ curl -s -X POST https://vmcp.example.com/oauth/register \
The response carries a `client_id` and **no `client_secret`**. The keypair
itself is the credential. To authenticate at the token endpoint, the agent signs
a `client_assertion` JWT with its private key (`iss` and `sub` set to its own
`client_id`, `aud` set to ToolHive's token endpoint, with a unique `jti`), then
`client_id`, `aud` set to the auth server's `issuer`, with a unique `jti`), then
presents it alongside the subject token:

```bash title="POST /oauth/token"
Expand All @@ -265,11 +265,13 @@ curl -s -X POST https://vmcp.example.com/oauth/token \
No `client_secret` parameter appears anywhere in this request. ToolHive
validates the `client_assertion`'s signature against the JWKS declared at
registration and rejects a replayed `client_assertion` (the same `jti` presented
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
`act.sub` is the DCR-assigned `client_id` instead of a statically configured
one.
twice) on the second attempt. ToolHive also accepts the token endpoint URL as
the `aud` value, or an `aud` array that contains either value. These forms are
deprecated, and a future release will require the issuer as the only audience.
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 `act.sub` is the
DCR-assigned `client_id` instead of a statically configured one.

ToolHive rejects registrations whose keys fall outside these limits:

Expand Down
10 changes: 10 additions & 0 deletions docs/toolhive/guides-vmcp/embedded-auth-server-vmcp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,16 @@ client. For local development, a plain-HTTP loopback issuer also works when you
set `insecureAllowConfidentialOverLoopbackHTTP: true`; ToolHive rejects a
plain-HTTP non-loopback issuer.

To revoke a delegate client, remove its entry from `delegateClients`. Each vMCP
replica serves only the delegate clients its own configuration declares, and
answers requests from any other delegate client in storage with
`invalid_client`, as if the client were unknown. Access tokens already issued to
the removed client stay valid until they expire. With Redis storage, the
client's record stays in Redis; to delete it, remove the
`<KEY_PREFIX>client:<CLIENT_ID>` key. During a rolling update, replicas still
running the previous configuration answer a newly added delegate client with
`invalid_client` until they're replaced.

To accept subject tokens minted by an external OIDC issuer, pair this with an
`inboundGrants.tokenExchange.issuerPolicies` entry. For why delegation exists,
the consent policy options, and a worked exchange, see
Expand Down
6 changes: 3 additions & 3 deletions docs/toolhive/reference/helm/operator-crds.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ Control CRD installation and preservation with these Helm values.
This reference lists values declared in the chart's default `values.yaml`.
Templates can also accept optional settings and inherited `global` values.

Chart: `toolhive-operator-crds`. Chart version: `0.57.0`. Source:
[`values.yaml`](https://github.com/stacklok/toolhive/blob/v0.57.0/deploy/charts/operator-crds/values.yaml)
at `v0.57.0`.
Chart: `toolhive-operator-crds`. Chart version: `0.58.0`. Source:
[`values.yaml`](https://github.com/stacklok/toolhive/blob/v0.58.0/deploy/charts/operator-crds/values.yaml)
at `v0.58.0`.

## Values

Expand Down
18 changes: 9 additions & 9 deletions docs/toolhive/reference/helm/operator.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Configure the ToolHive operator with these Helm values.
This reference lists values declared in the chart's default `values.yaml`.
Templates can also accept optional settings and inherited `global` values.

Chart: `toolhive-operator`. Chart version: `0.57.0`. Source:
[`values.yaml`](https://github.com/stacklok/toolhive/blob/v0.57.0/deploy/charts/operator/values.yaml)
at `v0.57.0`.
Chart: `toolhive-operator`. Chart version: `0.58.0`. Source:
[`values.yaml`](https://github.com/stacklok/toolhive/blob/v0.58.0/deploy/charts/operator/values.yaml)
at `v0.58.0`.

## Values

Expand Down Expand Up @@ -68,7 +68,7 @@ features:
gc:
gogc: 75
gomemlimit: 110MiB
image: ghcr.io/stacklok/toolhive/operator:v0.57.0
image: ghcr.io/stacklok/toolhive/operator:v0.58.0
imageDiscovery:
enabled: false
resources: {}
Expand Down Expand Up @@ -153,8 +153,8 @@ serviceAccount:
labels: {}
name: toolhive-operator
tolerations: []
toolhiveRunnerImage: ghcr.io/stacklok/toolhive/proxyrunner:v0.57.0
vmcpImage: ghcr.io/stacklok/toolhive/vmcp:v0.57.0
toolhiveRunnerImage: ghcr.io/stacklok/toolhive/proxyrunner:v0.58.0
vmcpImage: ghcr.io/stacklok/toolhive/vmcp:v0.58.0
volumeMounts: []
volumes: []
```
Expand Down Expand Up @@ -255,7 +255,7 @@ Key containing the password in `existingSecret`. When empty, uses

**Type:** `string`

**Default:** `"ghcr.io/stacklok/toolhive/operator:v0.57.0"`
**Default:** `"ghcr.io/stacklok/toolhive/operator:v0.58.0"`

Container image for the operator.

Expand All @@ -271,15 +271,15 @@ Image pull policy for the operator container and image-discovery containers.

**Type:** `string`

**Default:** `"ghcr.io/stacklok/toolhive/proxyrunner:v0.57.0"`
**Default:** `"ghcr.io/stacklok/toolhive/proxyrunner:v0.58.0"`

Container image for ToolHive proxy runners created by the operator.

### `operator.vmcpImage`

**Type:** `string`

**Default:** `"ghcr.io/stacklok/toolhive/vmcp:v0.57.0"`
**Default:** `"ghcr.io/stacklok/toolhive/vmcp:v0.58.0"`

Container image for Virtual MCP Server (vMCP) deployments created by the
operator.
Expand Down
Loading