Release v0.48.0 - #6631
Release v0.48.0#6631
Conversation
Release-Triggered-By: JAORMX
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6631 +/- ##
==========================================
- Coverage 78.89% 78.87% -0.02%
==========================================
Files 781 781
Lines 77784 77784
==========================================
- Hits 61364 61356 -8
- Misses 16415 16423 +8
Partials 5 5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
📝 Generated release notes for
|
| Case | Before | After |
|---|---|---|
| Unsigned candidate under a pinned key | signer-change-blocked (exit 4) |
failed [unsigned-rejected] (exit 3) |
| Keyless candidate whose signature does not verify | signer-change-blocked (exit 4) |
failed (exit 3) |
Before
# Dropped every key pin in the project, including ones still verifying
thv skill upgrade --allow-signer-changeAfter
# To intentionally drop a pin whose candidate still verifies against it:
thv skill uninstall <name> --scope project
thv skill install <source> --scope project --public-key <path> # or omit to land keylessMigration steps
- To intentionally drop a key pin whose candidate still verifies against the pinned key, use the uninstall/reinstall sequence the tool now prints —
--allow-signer-changeis no longer that mechanism. Add--project-rootif you are not in the project directory. - If an upgrade now reports
failedwith a verification error, re-run it: an operational fault no longer silently unpins. - Update CI that distinguishes exit
4(policy rejection) from exit3(failure), or that parsesoutcomes[].status, for keyed skill entries.
PR: #6628
Migration guide: `UpstreamTokenStorage` gained `CompareAndSwapUpstreamTokens`
Affects Go consumers who implement storage.UpstreamTokenStorage (or wrap storage.Storage) outside this repository — for example a Postgres-backed token store, or a decorator passed to authserver.New, runner.NewEmbeddedAuthServer, or upstreamtoken. There is no configuration, CLI, or protocol break, and StoreUpstreamTokens is untouched and still works. In-repo only RedisStorage and MemoryStorage implement it, and the generated mocks were regenerated, so mock users are unaffected.
Before
type MyStore struct{ /* ... */ }
func (s *MyStore) GetUpstreamTokens(ctx context.Context, sessionID, providerName string) (*storage.UpstreamTokens, error)
func (s *MyStore) StoreUpstreamTokens(ctx context.Context, sessionID, providerName string, tokens *storage.UpstreamTokens) errorAfter
// Add this method. The compare and the write must be atomic with respect to
// other writers of the same row.
func (s *MyStore) CompareAndSwapUpstreamTokens(
ctx context.Context,
sessionID, providerName, expectedRefreshToken string,
tokens *storage.UpstreamTokens,
) error {
// Return storage.ErrConcurrentRefresh when the stored refresh token no
// longer equals expectedRefreshToken. Treat an absent/nil row and an empty
// stored RefreshToken as matching an empty expectedRefreshToken.
// A decorator can simply forward to the wrapped store.
}Migration steps
- Add
CompareAndSwapUpstreamTokensto every externalUpstreamTokenStorageimplementation, making the compare and write atomic against other writers of the same row. - Return
storage.ErrConcurrentRefreshon mismatch; treat an absent or nil row and an empty stored refresh token as matching an emptyexpectedRefreshToken. - Decorators wrapping
storage.Storagecan forward straight to the wrapped store. - Note one runtime difference on the refresh path: a refresh that races a logout or a TTL eviction now returns an error (one re-authentication) instead of silently resurrecting the deleted row.
PR: #6548
🆕 New Features
- OIDC upstreams can now register themselves with your identity provider — set
dcrConfigon atype: oidcupstream instead of pre-provisioning aclientId, and ToolHive derives the registration endpoint from the issuer's discovery document (#6544). - Proxies that need to accept slow or large uploads are no longer capped at 30 seconds — set
thv run --proxy-read-timeoutorMCPServer.spec.proxyReadTimeoutto raise the request read timeout (#6285). - Plugins installed with
thv ai-plugin install --public-keynow work beyond install:syncreports them as current instead of drifting on every run,sync --checkpasses on an intact project,upgradeevaluates candidates against the pinned key, andsync --adoptexplains that the plugin must be installed with--public-keyinstead of failing opaquely (#6525). - Projects embedding vMCP as a Go library can install their own dial-time SSRF/DNS-rebinding guard on the connections opened during session initialization, closing a gap relative to the existing tool-call and aggregation guards — note this is an embedder API only, with no CLI or operator flag to enable it yet (#6547).
- Internal scaffolding landed for SPIFFE/SVID client authentication in the embedded auth server; the feature remains disabled and configuration-rejected in this build, and existing secret-,
private_key_jwt-, andjwt-bearer-authenticated clients are unaffected (#6562).
🐛 Bug Fixes
- When authorization policies are enabled, a managed MCP server returning a malformed or ambiguously encoded tool, prompt, or resource list now gets an error instead of having the list forwarded with your policies silently not applied (#6553).
- Virtual MCP's
find_toolnow fails closed rather than returning a partially filtered result, and authorized tools are filtered consistently across both the text and structured parts of the response (#6555). - Dropping a backend from a Kubernetes vMCP deployment now promptly closes that backend's leftover per-session connections, including long-lived SSE streams, instead of leaking them until each client disconnects; affected clients keep their session, but their surviving backends reconnect on the next request (#6549) — Go embedders implementing
server.SessionManagerthemselves need to add the newEvictStaleSessionsmethod.
Known issue in the find_tool hardening above: with Cedar authorization enabled on Virtual MCP with the tool optimizer, a find_tool search matching zero tools currently returns a generic internal error instead of an empty list, because the optimizer emits "tools": null for that case. Other deployments are unaffected.
🧹 Misc
- ToolHive's AI-plugin architecture, lifecycle, trust anchors, and CLI reference documentation now match shipped behavior, with stale claims about public-key verification, Codex registration, and keyless publishing corrected (#6627).
- The issue-triage workflow runs again after switching to a model the Stacklok gateway actually serves (#6557).
- Renovate can resolve the pinned
arduino/setup-taskaction again, clearing a persistent dependency-dashboard warning without changing CI execution (#6565).
📦 Dependencies
| Module | Version |
|---|---|
github.com/lestrrat-go/jwx/v3 |
v4 (major) |
github.com/cenkalti/backoff/v5 |
v7 (major) |
google.golang.org/grpc |
v1.83.2 |
golang.org/x/crypto |
v0.57.0 |
golang.org/x/sys |
v0.48.0 |
golang.org/x/term |
v0.46.0 |
golang.org/x/sync |
v0.23.0 |
golang.org/x/mod |
v0.41.0 |
golang.org/x/time |
v0.16.0 |
golang.org/x/exp/jsonrpc2 |
digest 85c1c22 |
go.starlark.net |
digest 89a6a09 |
modernc.org/sqlite |
v1.58.0 |
github.com/spiffe/go-spiffe/v2 |
v2.8.1 |
github.com/getsentry/sentry-go |
v0.49.0 |
github.com/go-chi/chi/v5 |
v5.3.2 |
github.com/gofrs/flock |
v0.13.1 |
github.com/charmbracelet/x/ansi |
v0.11.8 |
github.com/tidwall/gjson |
v1.19.0 |
github.com/pelletier/go-toml/v2 |
v2.4.3 |
github.com/pressly/goose/v3 |
v3.28.0 |
github.com/go-git/go-billy/v5 |
v5.9.1 |
github.com/moby/moby/api |
v1.56.0 |
github.com/moby/moby/client |
v0.6.0 |
github.com/testcontainers/testcontainers-go |
v0.44.0 |
github.com/1password/onepassword-sdk-go |
v0.4.1 |
github.com/ory/x |
v0.0.729 |
golang.ngrok.com/ngrok/v2 |
v2.2.0 |
aws-sdk-go-v2 monorepo |
grouped update |
| auth and security libraries | grouped update |
| opentelemetry and observability | grouped update |
| testing libraries | grouped update |
github/codeql-action |
v4.38.0 |
codecov/codecov-action |
v7 (major) |
actions/setup-node |
v7 (major) |
slackapi/slack-github-action |
v4 (major) |
helm/kind-action |
v1.15.0 |
zizmorcore/zizmor-action |
v0.6.4 |
codespell-project/actions-codespell |
v2.4.3 |
anthropics/claude-code-action |
v1.0.220 |
| core workflow actions | grouped major update |
| setup and language actions | grouped major update |
| container build actions | grouped update |
helm / helm/helm |
v3.22.0 |
kubernetes-sigs/kind |
v0.33.0 |
node |
v24 (major) |
ghcr.io/stacklok/thv-registry-api |
v1.5.2 |
ghcr.io/modelcontextprotocol/inspector |
v2 (major) |
ghcr.io/zizmorcore/zizmor |
v1.30.1 |
registry |
v3 (major) |
| dockerfile template base images | grouped update |
Full commit log
What's Changed
- Support OIDC dynamic client registration by @jhrozek in Support OIDC dynamic client registration #6544
- Fail closed on malformed protected list responses by @ChrisJBurns in Fail closed on malformed protected list responses #6553
- Fix issue-triage workflow model for Stacklok gateway by @danbarr in Fix issue-triage workflow model for Stacklok gateway #6557
- Use Basic auth for OAuth2 upstreams by @jhrozek in Use Basic auth for OAuth2 upstreams #6543
- Honour a pinned cosign key on plugin sync and upgrade by @samuv in Honour a pinned cosign key on plugin sync and upgrade #6525
- Bump google.golang.org/grpc from 1.83.1 to 1.83.2 by @dependabot[bot] in Bump google.golang.org/grpc from 1.83.1 to 1.83.2 #6558
- Harden find tool response filtering by @ChrisJBurns in Harden find tool response filtering #6555
- Evict vMCP sessions when a backend is dropped by @tgrunnagle in Evict vMCP sessions when a backend is dropped #6549
- Add dial-control option to vMCP session factory by @tgrunnagle in Add dial-control option to vMCP session factory #6547
- Fix setup-task version hints by @rdimitrov in Fix setup-task version hints #6565
- Update go.starlark.net digest to 89a6a09 by @renovate[bot] in Update go.starlark.net digest to 89a6a09 #5779
- Update golang.org/x/exp/jsonrpc2 digest to 85c1c22 by @renovate[bot] in Update golang.org/x/exp/jsonrpc2 digest to 85c1c22 #6172
- Guard rotating refresh-token writes with compare-and-swap by @reyortiz3 in Guard rotating refresh-token writes with compare-and-swap #6548
- Make proxy request read timeout configurable by @Sanskarzz in Make proxy request read timeout configurable #6285
- Update dockerfile template base images by @renovate[bot] in Update dockerfile template base images #6584
- Update anthropics/claude-code-action action to v1.0.219 by @renovate[bot] in Update anthropics/claude-code-action action to v1.0.219 #6568
- Update module github.com/charmbracelet/x/ansi to v0.11.8 by @renovate[bot] in Update module github.com/charmbracelet/x/ansi to v0.11.8 #6569
- Update module github.com/go-chi/chi/v5 to v5.3.2 by @renovate[bot] in Update module github.com/go-chi/chi/v5 to v5.3.2 #6570
- Update module github.com/gofrs/flock to v0.13.1 by @renovate[bot] in Update module github.com/gofrs/flock to v0.13.1 #6572
- Update slackapi/slack-github-action action to v3.0.5 by @renovate[bot] in Update slackapi/slack-github-action action to v3.0.5 #6575
- Update zizmorcore/zizmor-action action to v0.6.4 by @renovate[bot] in Update zizmorcore/zizmor-action action to v0.6.4 #6576
- Update dependency helm to v3.21.4 by @renovate[bot] in Update dependency helm to v3.21.4 #6581
- Update dependency helm/helm to v3.21.4 by @renovate[bot] in Update dependency helm/helm to v3.21.4 #6582
- Update dependency kubernetes-sigs/kind to v0.33.0 by @renovate[bot] in Update dependency kubernetes-sigs/kind to v0.33.0 #6583
- Update setup and language actions (major) by @renovate[bot] in Update setup and language actions (major) #6620
- Update registry Docker tag to v3 by @renovate[bot] in Update registry Docker tag to v3 #6619
- Update module github.com/lestrrat-go/jwx/v3 to v4 by @renovate[bot] in Update module github.com/lestrrat-go/jwx/v3 to v4 #6618
- Update module github.com/cenkalti/backoff/v5 to v7 by @renovate[bot] in Update module github.com/cenkalti/backoff/v5 to v7 #6617
- Update dependency node to v24 by @renovate[bot] in Update dependency node to v24 #6615
- Update module golang.org/x/sys to v0.48.0 by @renovate[bot] in Update module golang.org/x/sys to v0.48.0 #6605
- Update github/codeql-action action to v4.38.0 by @renovate[bot] in Update github/codeql-action action to v4.38.0 #6587
- Update ghcr.io/modelcontextprotocol/inspector Docker tag to v2 by @renovate[bot] in Update ghcr.io/modelcontextprotocol/inspector Docker tag to v2 #6616
- Update module golang.org/x/time to v0.16.0 by @renovate[bot] in Update module golang.org/x/time to v0.16.0 #6607
- Update module modernc.org/sqlite to v1.58.0 by @renovate[bot] in Update module modernc.org/sqlite to v1.58.0 #6608
- Update testing libraries by @renovate[bot] in Update testing libraries #6609
- Update module github.com/moby/moby/api to v1.56.0 by @renovate[bot] in Update module github.com/moby/moby/api to v1.56.0 #6594
- Update container build actions by @renovate[bot] in Update container build actions #6580
- Update module golang.ngrok.com/ngrok/v2 to v2.2.0 by @renovate[bot] in Update module golang.ngrok.com/ngrok/v2 to v2.2.0 #6601
- Update module github.com/tidwall/gjson to v1.19.0 by @renovate[bot] in Update module github.com/tidwall/gjson to v1.19.0 #6600
- Update module github.com/go-git/go-billy/v5 to v5.9.1 by @renovate[bot] in Update module github.com/go-git/go-billy/v5 to v5.9.1 #6571
- Update auth and security libraries by @renovate[bot] in Update auth and security libraries #6577
- Update codecov/codecov-action action to v7 by @renovate[bot] in Update codecov/codecov-action action to v7 #6612
- Update slackapi/slack-github-action action to v4 by @renovate[bot] in Update slackapi/slack-github-action action to v4 #6621
- Update aws-sdk-go-v2 monorepo - autoclosed by @renovate[bot] in Update aws-sdk-go-v2 monorepo - autoclosed #6578
- Update module golang.org/x/term to v0.46.0 by @renovate[bot] in Update module golang.org/x/term to v0.46.0 #6606
- Update actions/setup-node action to v7 by @renovate[bot] in Update actions/setup-node action to v7 #6610
- Update module github.com/1password/onepassword-sdk-go to v0.4.1 by @renovate[bot] in Update module github.com/1password/onepassword-sdk-go to v0.4.1 #6590
- Update module golang.org/x/mod to v0.41.0 by @renovate[bot] in Update module golang.org/x/mod to v0.41.0 #6603
- Update module github.com/pressly/goose/v3 to v3.28.0 by @renovate[bot] in Update module github.com/pressly/goose/v3 to v3.28.0 #6597
- Update module github.com/pelletier/go-toml/v2 to v2.4.3 by @renovate[bot] in Update module github.com/pelletier/go-toml/v2 to v2.4.3 #6596
- Update helm/kind-action action to v1.15.0 by @renovate[bot] in Update helm/kind-action action to v1.15.0 #6588
- Update module golang.org/x/sync to v0.23.0 by @renovate[bot] in Update module golang.org/x/sync to v0.23.0 #6604
- Update core workflow actions (major) by @renovate[bot] in Update core workflow actions (major) #6613
- Update module golang.org/x/crypto to v0.57.0 by @renovate[bot] in Update module golang.org/x/crypto to v0.57.0 #6602
- Update opentelemetry and observability by @renovate[bot] in Update opentelemetry and observability #6574
- Update codespell-project/actions-codespell action to v2.4.3 by @renovate[bot] in Update codespell-project/actions-codespell action to v2.4.3 #6579
- Update dependency helm to v3.22.0 by @renovate[bot] in Update dependency helm to v3.22.0 #6623
- Update anthropics/claude-code-action action to v1.0.220 by @renovate[bot] in Update anthropics/claude-code-action action to v1.0.220 #6622
- Update module github.com/ory/x to v0.0.729 by @renovate[bot] in Update module github.com/ory/x to v0.0.729 #6573
- Update ghcr.io/zizmorcore/zizmor Docker tag to v1.30.1 by @renovate[bot] in Update ghcr.io/zizmorcore/zizmor Docker tag to v1.30.1 #6586
- Update module github.com/spiffe/go-spiffe/v2 to v2.8.1 by @renovate[bot] in Update module github.com/spiffe/go-spiffe/v2 to v2.8.1 #6598
- Update module github.com/moby/moby/client to v0.6.0 by @renovate[bot] in Update module github.com/moby/moby/client to v0.6.0 #6595
- Update module github.com/lestrrat-go/jwx/v3 to v3.3.0 by @renovate[bot] in Update module github.com/lestrrat-go/jwx/v3 to v3.3.0 #6593
- Update module github.com/testcontainers/testcontainers-go to v0.44.0 by @renovate[bot] in Update module github.com/testcontainers/testcontainers-go to v0.44.0 #6599
- Document AI plugin support by @JAORMX in Document AI plugin support #6627
- Update ghcr.io/stacklok/thv-registry-api Docker tag to v1.5.2 by @renovate[bot] in Update ghcr.io/stacklok/thv-registry-api Docker tag to v1.5.2 #6585
- Add SPIFFE client authentication dispatch by @jhrozek in Add SPIFFE client authentication dispatch #6562
- Require a discovery capability for key signing by @samuv in Require a discovery capability for key signing #6560
- Fail closed on keyed skill upgrade verdicts by @samuv in Fail closed on keyed skill upgrade verdicts #6628
- Update module github.com/getsentry/sentry-go to v0.49.0 by @renovate[bot] in Update module github.com/getsentry/sentry-go to v0.49.0 #6591
- Release v0.48.0 by @toolhive-release-app[bot] in Release v0.48.0 #6631
🔗 Full changelog: v0.47.1...v0.48.0
Release v0.48.0
Version Bump
minor release
Files Updated
VERSIONdeploy/charts/operator-crds/Chart.yaml(path:version)deploy/charts/operator-crds/Chart.yaml(path:appVersion)deploy/charts/operator/Chart.yaml(path:version)deploy/charts/operator/Chart.yaml(path:appVersion)deploy/charts/operator/values.yaml(path:operator.image)deploy/charts/operator/values.yaml(path:operator.toolhiveRunnerImage)deploy/charts/operator/values.yaml(path:operator.vmcpImage)Next Steps
Checklist