Repository navigation
v0.64.0
·
29 commits
to main
since this release
🚀 Toolhive v0.64.0 is live!
This release hardens the embedded authorization server. It closes a client-assertion replay gap, rejects ID-JAGs presented as access tokens, and stops deeply nested JWTs before fosite parses them. The operator now exposes the auth server's TLS listener port.
🆕 New Features
- When
embeddedAuthServer.tlsListeneris enabled, MCPServer, MCPRemoteProxy and VirtualMCPServer workloads now get anhttps-authcontainer port and a Service port 8443 (appProtocol: https), so the listener can be reached through the Service. Affected workloads roll their pods once on the next reconcile. For a VirtualMCPServer withserviceType: LoadBalancerorNodePort, port 8443 is now reachable from outside the cluster; it serves the same auth server routes already public on thehttpport. Workloads without the listener don't change (#7065)
🐛 Bug Fixes
private_key_jwtclient assertions withexp: 0, anexpthat overflows, or presented in the last second before expiry are now refused with HTTP 401invalid_client. Before, they could be replayed because theirjtireplay marker had already expired (#7087)- JWTs whose
typmarks them as ID-JAGs (oauth-id-jag+jwt) are now rejected wherever an access token is expected, including resource-server bearer auth and token-exchange subject/actor tokens. This prevents token-type confusion when an issuer signs both with the same key (#7089) - Client assertions and OpenID Connect
requestobjects whose payload is not valid JSON, or is nested deeper than 10000 levels, are now refused before fosite parses them. This mitigates the go-jose v3 stack-exhaustion advisory GHSA-vvm8-gf78-28g4 (#7090) - A Redis failure while recording a client assertion's
jtinow returns the standard OAuth error codeserver_errorinstead oferror. The HTTP status is still 500 (#7086) - The gjson identity modifiers used by paths like
access_token|@upstreamjwt|subare now registered automatically byauthserver.Newandupstream.NewOAuth2Provider, so standalone embedders no longer need to register them by hand (#7063) authserver.Newnow returns a true nilServeron error instead of a typed-nil pointer. CallingClosemore than once no longer repeats cleanup or panics. Storage ownership rules for embedders are now documented (#7071)- Fixed a missing import that kept the auth server storage integration tests from compiling under
-tags integration(#7085)
🧹 Misc
- CLI help now shows boolean flags as
--flag[=true|false]after the spf13/pflag v1.1.0 upgrade. Flag parsing and pass-through of unknown flags are unchanged (#7083) - Added a depguard rule that blocks new non-test imports of go-jose v3 and fosite's
token/jwt, so new JWT parsing can't bypass the unsafe-JWS guard (#7097) - The ID-JAG JOSE
typvalue is now defined once asoauthproto.JWTTypeIDJAG(#7070) - Made the Redis connection-failure tests deterministic by using a client that can never connect, instead of a closed port (#7080)
mockoidcsubject assertions in the integration tests now pass with both the old and the new mockoidc versions (#7078)- Raised the golangci-lint CI timeout to 10 minutes (#7084)
- Trimmed CODEOWNERS so automatic review requests are opt-in (#7093)
📦 Dependencies
| Module | Version |
|---|---|
github.com/spf13/pflag |
v1.1.0 |
github.com/aws/aws-sdk-go-v2 |
v1.47.8 |
github.com/aws/aws-sdk-go-v2/config |
v1.33.16 |
github.com/aws/aws-sdk-go-v2/service/sts |
v1.51.9 |
github.com/cenkalti/backoff/v7 |
v7.0.3 |
github.com/go-jose/go-jose/v4 |
v4.1.9 |
github.com/gofrs/flock |
v0.13.2 |
github.com/modelcontextprotocol/registry |
v1.8.8 |
github.com/onsi/ginkgo/v2 |
v2.34.0 |
github.com/stacklok/toolhive-catalog |
v0.20261103.0 |
github.com/stacklok/toolhive-core |
v0.0.59 |
github.com/stacklok/toolhive-core/redisconn |
v0.0.59 |
github.com/testcontainers/testcontainers-go |
v0.45.0 |
github.com/tidwall/gjson |
v1.20.2 |
modernc.org/sqlite |
v1.62.0 |
github.com/oauth2-proxy/mockoidc |
digest e06ed0b |
golang.org/x/exp/jsonrpc2 |
digest 47ce03d |
go.starlark.net |
digest 4f4267f |
alpine |
3.24.4 |
ghcr.io/modelcontextprotocol/inspector |
2.14.0 |
ghcr.io/zizmorcore/zizmor |
1.32.0 |
python, registry, index.docker.io/library/alpine |
digest updates |
node (GitHub Actions) |
26 |
anthropics/claude-code-action |
v1.0.269 |
docker/login-action |
v4.8.0 |
github/codeql-action |
v4.39.3 |
helm/kind-action |
v1.15.2 |
sigstore/cosign-installer |
v4.1.3 |
Full commit log
What's Changed
- Initialize identity modifiers for standalone use by @jhrozek in #7063
- Name the ID-JAG JWT type once by @jhrozek in #7070
- Update docker images by @renovate[bot] in #7075
- Update golang.org/x/exp/jsonrpc2 digest to 47ce03d by @renovate[bot] in #7074
- Update go.starlark.net digest to 4f4267f by @renovate[bot] in #6746
- Make mockoidc subject assertions version-agnostic by @jhrozek in #7078
- Update dependency node to v26 by @renovate[bot] in #7017
- Make Redis connection-failure tests deterministic by @jhrozek in #7080
- Update github.com/oauth2-proxy/mockoidc digest to e06ed0b by @renovate[bot] in #7073
- Clarify authserver ownership and fix nil error returns by @jhrozek in #7071
- Update docker images by @renovate[bot] in #7082
- Update github actions by @renovate[bot] in #7076
- Raise golangci-lint timeout to 10 minutes by @jhrozek in #7084
- Bump spf13/pflag to v1.1.0 by @jhrozek in #7083
- Update go modules by @renovate[bot] in #7077
- Expose auth server TLS listener port in operator by @jhrozek in #7065
- Fix missing fosite import in DCR cap integration test by @jhrozek in #7085
- Report jti recording failures as server_error by @jhrozek in #7086
- Prevent ID-JAGs from being used as access tokens by @jhrozek in #7089
- chore: trim CODEOWNERS to opt-in review requests by @rdimitrov in #7093
- Refuse deeply nested JWT payloads before fosite by @aponcedeleonch in #7090
- Refuse client assertions without a positive exp by @jhrozek in #7087
- Restrict go-jose v3 imports with depguard by @aponcedeleonch in #7097
- Release v0.64.0 by @toolhive-release-app[bot] in #7098
Full Changelog: v0.63.0...v0.64.0
🔗 Full changelog: v0.63.0...v0.64.0