Update stacklok/toolhive to v0.49.0 - #1150
Conversation
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @renovate[bot]'s task in 13m 38s —— View job Upstream release docs — toolhive v0.49.0Done. Pushed Doc edits applied
Verified end-to-end, no doc change needed
Build passed. Prettier and ESLint clean.
|
- Restore client_secret_post as the default token_endpoint_auth_method for pre-registered OAuth 2.0 upstreams on both K8s and vMCP embedded auth server pages. - Document AWS STS role-claim shape rule: string or list of strings, other shapes fail closed with a 403. - Add Skill entity, get_skill action, and skills/list response filtering to the Cedar authorization policy reference. - Remove the stale "plugin push is keyless-only" note and describe the restored --key cosign-key-pair signing for locally discovered ToolHive servers.
|
Claude finished @renovate[bot]'s task in 3m 59s —— View job Docs review for v0.49.0 content changes
SummaryAll technical claims verify against the upstream source:
Fixes applied1. 2. Nothing else flaggedThe v0.49.0 breaking-change admonitions on both embedded-auth-server pages carry only the upgrade delta and action, as the style guide allows for versioned admonitions. No factual conflicts with upstream, no other jargon leaks, and no em/en dashes. |
- Rewrite ai-plugin install step in second person; drop 'consumers' engineering jargon. - Drop 'continues to' in the AWS STS fallback sentence; describe current behavior only.
This PR contains the following updates:
v0.48.0→v0.49.0After this PR opens,
.github/workflows/upstream-release-docs.ymladds source-verified content edits for the new release. Forstacklok/toolhive, the same workflow also syncs reference assets (CLI help, Swagger) and regenerates the CRD MDX pages.Release Notes
stacklok/toolhive (stacklok/toolhive)
v0.49.0Compare Source
🚀 Toolhive v0.49.0 is live!
A security- and auth-correctness release: a signer-pin bypass in
thv skill upgradeis closed, the embedded auth server's documented zero-downtime key rotation finally works, and AWS STS role claims now fail closed instead of silently handing out the fallback role. This release also ships a dependency-light generated Go client for the management API, and moves the project to Go 1.27.pkg/vmcp/session.WithDialControlremoved — vMCP embedders who set a dial-control hook on the session factory get a compile error; wrap the hook in the newWithDialControlResolver(migration guide below).oauth2upstreams with a client secret and no explicittokenEndpointAuthMethodgo back to sending credentials in the POST body instead of HTTP Basic; setclient_secret_basicexplicitly if your IdP requires it (migration guide below).go://workloads default togolang:1.27-alpine— builds pinned to Go 1.26 withGOTOOLCHAIN=localfail, andgo://servers that do not compile under Go 1.27 need an explicit image pin (migration guide below).Migration guide:
session.WithDialControl→session.WithDialControlResolverAffects Go embedders of vMCP that called
session.WithDialControl— the option added in v0.48.0 by #6547. The option was address-blind, so every backend received the samenet.Dialer.Controlhook and a per-backend dial policy could not be expressed. It is replaced in place rather than deprecated alongside a second option.On v0.49.0 the old call fails to compile with
undefined: session.WithDialControl.pkg/vmcp/client.WithDialControlis unchanged. Only thepkg/vmcp/sessionoption was renamed — do not migrateclient.WithDialControlcall sites.Before
After
Per-backend policy — the capability this unlocks. Returning
nilfor a workload leaves that backend onhttp.DefaultTransport, byte-for-byte identical to the no-hook path:Migration steps
session.WithDialControl(call site in thepkg/vmcp/sessionpackage — notpkg/vmcp/client, whose identically-named option is unchanged.session.WithDialControlResolver.func(workloadID string) func(network, address string, c syscall.RawConn) error { return hook }to preserve v0.48.0 semantics exactly.workloadIDto vary policy per backend; returnnilto leave a backend untouched.address— deciding allow/deny fromworkloadIDalone provides no network-level protection.PR: #6567
Migration guide: OAuth2 upstream
tokenEndpointAuthMethoddefaultAffects anyone on v0.48.0 with a pure
oauth2-type upstream provider that uses a pre-registeredclientIdplus a client secret and leavestokenEndpointAuthMethodunset.#6543 (shipped in v0.48.0, and only in v0.48.0) added the
token_endpoint_auth_methodfield, but also made an unset field silently default toclient_secret_basicwhenever a secret was configured — flipping every existing pre-registered upstream from POST-body credentials to HTTP Basic with no opt-in. v0.49.0 restores the historical default while keeping the new field.The auth style is strict, not probing: an unset method sends credentials in the token-request POST body and does not retry with Basic. Against a Basic-only IdP the exchange fails with
invalid_client— on both initial login and token refresh.OIDC-type upstreams and Dynamic Client Registration upstreams are unaffected.
Before
After
Raw auth-server run config:
Migration steps
oauth2upstream with a client secret.token_endpoint_auth_methods_supportedin its discovery document, or its client registration. If onlyclient_secret_basicis accepted, act.tokenEndpointAuthMethod: client_secret_basicon every affectedupstreamProviders[].oauth2Config(spec.embeddedAuthServer.upstreamProviders[]forMCPExternalAuthConfig,spec.authServerConfig.upstreamProviders[]forVirtualMCPServer), ortoken_endpoint_auth_methodunderupstreams[].oauth2_configin a raw run config.The CRD schema is unchanged apart from doc text, so there is no CRD upgrade ordering concern.
PR: #6648
Migration guide: AWS STS role claim shapes now fail closed
Affects deployments using an
awsStsexternal auth config with claim-basedroleMappings. Matcher-expression-only configurations are unaffected.Role mappings are evaluated with the CEL expression
claim_value in claims[role_claim_key], and CEL'sinonly has list and map overloads. Two bugs followed: a string role claim raised a swallowed "no such overload" error and silently produced the fallback role even on an exact match, and an object role claim madeintest map-key membership, matching spuriously. Both are now corrected, and unsupported shapes fail closed rather than quietly granting a role.Two behavior changes, both deliberate:
claimnow selects its mapped role instead offallbackRoleArn. Strings that merely contain the value still do not match.Failed to determine IAM rolefrom theaws_stsmiddleware, or a failed backend call withfailed to select IAM rolein vMCP outbound auth.A missing role claim still falls back exactly as before.
Before
{ "sub": "user1", "groups": { "admins": true } } { "sub": "user2", "groups": 7 }After
{ "sub": "user1", "groups": ["admins"] } { "sub": "user1", "groups": "admins" }Migration steps
awsStsconfig and inspect the claim named byawsSts.roleClaim(defaultgroups).fallbackRoleArn. Verify the mapped role's IAM trust policy accepts these subjects and that its permissions suit that population.realm_access.rolesto a top-level key —roleClaimis a flat lookup, not a dot path). Alternatively pointroleClaimat a correctly-shaped claim, or convert those mappings tomatcherCEL expressions, which are evaluated against the raw claims and are unaffected.role claim has unsupported shape, failing closedandclaim-based role mapping evaluation failed, failing closed— they name the offendingrole_arn. Note thatCEL expression evaluation failed, skipping mappingwas promoted from Debug to Warn, so pre-existing matcher-expression bugs will now appear at default log level.PR: #6306 — Closes #6305
Migration guide: Go 1.27 toolchain and
go://builder imageTwo separate audiences.
go://workload users. The default builder image forgo://workloads moved fromgolang:1.26-alpinetogolang:1.27-alpine. Only freshly builtgo://workloads with no override are affected. Go's compatibility promise makes a failure unlikely, but a server relying on a removed deprecated API will not compile.Downstream Go importers of the root module.
github.com/stacklok/toolhivenow declaresgo 1.27.0with notoolchaindirective. Under the defaultGOTOOLCHAIN=autoGo downloads 1.27 transparently; underGOTOOLCHAIN=local, a pinned-toolchain CI, an air-gapped build, or a distro-packaged Go, the build fails hard withgo: go.mod requires go >= 1.27. The nestedgithub.com/stacklok/toolhive/sdk/gomodule deliberately keeps itsgo 1.26.0floor and is not affected.Before
After
Migration steps
go://run, pin per invocation:thv run go://github.com/example/server --runtime-image golang:1.26-alpine.runtime_configs.go.builder_imagein~/.toolhive/config.yamlas above.additional_packagesreplaces rather than appends to the built-in["ca-certificates", "git"], so list them explicitly. Only the builder stage is customizable for Go workloads; the runtime stage is alwaysalpine:3.23.GOTOOLCHAIN=autoand allow Go to fetch the toolchain on demand.github.com/stacklok/toolhive/sdk/goinstead — it retains thego 1.26.0floor.setup-goat the rootgo-version-file: go.modrather than pinning a version.PR: #6639
🆕 New Features
github.com/stacklok/toolhive/sdk/gomodule provides a typed, generated client covering all 77 documented management API operations, with safe default timeout and response-size handling, without pulling in ToolHive's full application dependency graph (#6637).skills/getmaps toAction::"get_skill"on the skill's exact URI, andskills/listresponses are filtered to the skills the caller may get — previously both methods were refused outright by default-deny, andskills/listwithout aget_skillpermit now returns an empty list instead of a 403 (#6512).thv ai-plugin push --key <cosign.key>is available again for publishers using automatic local server discovery, now that key-signed plugins can be verified at install time withthv ai-plugin install --public-keyand pinned intoolhive.lock.yamlfor latersync/upgrade; remote or manually configured API URLs must still sign keylessly (#6528).WARNthat names the store so an unintended downgrade stays visible (#6551).🐛 Bug Fixes
thv skill upgrade --allow-signer-changeno longer doubles as unsigned consent — it previously succeeded against an unsigned candidate, silently dropping a signer-pinned skill's recorded identity and rewriting the lock entry asunsigned: true; boththv skill upgradeandthv ai-plugin upgradenow reportfailed [unsigned-rejected]and name theuninstall … --scope projecttheninstall … --scope project --allow-unsignedsequence that records the exception explicitly (#6629)./.well-known/jwks.jsonnow publishes configured fallback keys alongside the signing key (primary first, de-duplicated bykid), making the documented three-step zero-downtime signing-key rotation actually work instead of a hard cutover that invalidated every outstanding JWT (#6638 — Closes #6451).notifications/progressframes are flushed to the SSE stream, in backend order, before the response closes it (#6491 — Closes #6349).spec.podTemplateSpecno longer get ametadata.generationbump and a spuriousDeploymentUpdatedevent on everystatusReportingIntervaltick, including the 30s default — pod-template drift detection was comparing user-merged label maps for exact equality (#6377 — Fixes #6340).invalid_client,invalid_grant, …) where a wrapped error could previously degrade to a genericserver_error(#6639).🧹 Misc
miniredisimport that broke typecheck — and therefore every test — inpkg/authserver/runneronmain(#6636).📦 Dependencies
github.com/stacklok/toolhive-coreAlso migrates all Redis call sites from the now-deprecated
toolhive-core/rediscompatibility facade toredisconndirectly (#6646).👋 Welcome to our newest contributor: @isaacgao4396 🎉
Full commit log
What's Changed
New Contributors
Full Changelog: stacklok/toolhive@v0.48.0...v0.49.0
🔗 Full changelog: stacklok/toolhive@v0.48.0...v0.49.0
Configuration
📅 Schedule: (in timezone America/New_York)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Never, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.
Docs update for
toolhivev0.49.0At a glance
stacklok/toolhivev0.48.0→v0.49.0Who does what
@reyortiz3 cut this release and owns this PR: review your own changes, chase the remaining approvals, and merge once they're in. You don't need to wait on a review from anyone listed as having no docs impact below.
Everyone with a review request: the target is a review and approval within 2 business days.
Summary of changes
docs/toolhive/guides-k8s/embedded-auth-server-k8s.mdxanddocs/toolhive/guides-vmcp/embedded-auth-server-vmcp.mdxto reflect the restoredclient_secret_postdefault for pre-registered OAuth 2.0 upstream clients (Restore legacy default for OAuth2 upstream auth method toolhive#6648), replacing the stale v0.48.0 admonition with a v0.49.0 note for upgraders coming from v0.48.0.docs/toolhive/integrations/aws-sts.mdxto document the required role-claim shape (string or list of strings), the fail-closed 403 response for other shapes, and the observable log line (Normalize string role claims before claim-based role mapping evaluation toolhive#6306).Skillentity type,Action::"get_skill"action,skills/getattribute table, andskills/listresponse-filtering row todocs/toolhive/reference/authz-policy-reference.mdxso Cedar policy authors can govern the MCP Skills extension (Authorize MCP Skills extension requests toolhive#6512).thv ai-plugin pushsigning section indocs/toolhive/guides-cli/ai-plugins.mdxto document--keycosign key-pair signing (restricted to the locally discovered server) and the matching--public-keyinstall flow, removing the stale "keyless-only" note (Restore capability-gated --key signing on thv ai-plugin push toolhive#6528).No docs impact identified
4 contributor(s) had no-docs-impact commits in this release. No review was requested, and the workflow did not auto-notify them.
Review routing
GitHub could not request the upstream contributor directly, so review went to the human merger of each relevant upstream PR:
Run cost
How this PR was built
Two Claude Opus sessions run per release: a generation pass
(
upstream-release-docsskill, 6 phases) followed by a fresh-context editorial pass (
docs-review). Prettier/ESLintauto-fixes are applied after.
Auto-synced paths — do not hand-edit these in review:
static/api-specs/docs/toolhive/reference/cli/(toolhive only)docs/toolhive/reference/crds/If a "Gaps needing human context" section is present above,
each entry includes a paste-ready Helper prompt for local
Claude a reviewer can use to resolve the gap.