AI Agents

  • Fixed

    • (oauth) Omit scope from RFC 7591 registration requests in #1086 by @teemow

    Full Changelog: https://github.com/giantswarm/muster/compare/v5.2.0...v5.2.1

  • Fixed

    • Test framework: expectations are now evaluated by a single implementation for both step kinds, so an assertion means the same thing whether it is written on an MCP tool step or a test_* step. The two paths each carried their own copy of the checks and had drifted three times — json_path (#1036), not_contains and wait_for_state (#1078) were each implemented on one path and silently ignored on the other, so a scenario declaring one on the wrong kind of step passed regardless of the response. Each path now only adapts its own response shape and shares the checks. Two behaviours are unified in the process: error_contains is evaluated whenever it is declared (the test-tool path previously skipped it unless success: false), and a success: false payload now fails an MCP step that expected success (previously checked only for test_* steps). All 186 scenarios are unaffected by both. A new test asserts that every field of TestExpectation is enforced on both paths, and fails the build when an expectation kind is added without being wired up — the class of bug behind #1038.
    • Test framework: status_code in a step’s expected block is now rejected at load time, with a message pointing at json_path. It was accepted by the schema and printed by the reporter but never evaluated by either path, so a scenario asserting an HTTP status asserted nothing. No scenario in the repository used it.
  • Changed

    • components.muster.versionRange default changed from ">=4.1.0 <5.0.0" to "5.x", so the meta-package resolves the current muster line (v5.1.0). The >=4.1.0 floor is subsumed by the major: it existed because the muster values here set observability.metrics.prometheus.prometheusRule, and every 5.x accepts that key. No installation needs to act. muster v5.0.0 (muster#1078) is breaking only for muster instances running without their own OAuth: with no bearer there was no token family, so the transport injected the default-user placeholder and every concurrent MCP client collapsed onto one session — one client’s authenticated backend became visible and callable in every other client’s session, on the first client’s token. Such sessions are now keyed by MCP transport session, which means a session ends with the connection and a reconnecting client re-runs core_auth_login. Every installation of this umbrella runs muster.muster.oauth.server.enabled: true (the default here, overridden in no *-configs installation patch across the 14 deployments), so a real token-family session ID still wins and the crossing is a no-op for the fleet; stdio is unaffected either way. muster v5.1.0 (muster#1079) additionally fails the render on an explicitly emptied rbac.mcpServerEditor.subjects / rbac.workflowEditor.subjects; both are bound to the Giant Swarm admin groups by this chart (since #232) and overridden nowhere, so the guard is satisfied. The crossing also picks up muster#1077 (the chart values-schema fix), which the never-published v4.1.1 chart left unreachable.
  • Fixed

    • The kagent-pg CNPG Cluster now sets inheritedMetadata.labels with observability.giantswarm.io/tenant: giantswarm, which the operator copies onto the PodMonitor it generates. Without it the PodMonitor carried only CNPG’s stock labels and matched neither of alloy-metrics’ discovery selectors, so it was created and silently never scraped (zero cnpg_* series in Mimir). The previous podMonitorRelabelings attempt is removed: it rewrote scraped series, not the PodMonitor object’s labels, so it could never make the monitor discoverable.
  • Changed

    Full Changelog: https://github.com/giantswarm/agent-platform/compare/v2.11.0...v2.11.1

  • Added

    • (muster) Bind mcpserver-editor explicitly to the Giant Swarm admin groups in #232 by @teemow

    Full Changelog: https://github.com/giantswarm/agent-platform/compare/v2.10.0...v2.11.0

  • Added

    • (helm) Document the editor RoleBinding trade-off and fail on empty subjects in #1079 by @teemow

    Full Changelog: https://github.com/giantswarm/muster/compare/v5.0.0...v5.1.0

  • Fixed

    • Security (aggregator): a muster without inbound OAuth no longer shares one client’s downstream logins with every other client. Without a bearer token there is no token family to key a session by, so the transport layer injects the default-user placeholder — and that constant was used as the session key, collapsing every concurrent MCP connection onto a single session. Session-scoped state is keyed by that ID: the OAuth token store, the capability store that backs session-scoped tool visibility (ADR 006), and the session connection pool. So once any one client ran core_auth_login against an OAuth-protected backend, that backend’s tools appeared in list_tools for — and were callable by — every other client of the same muster, using the first client’s token. Requests that carry no authenticated identity are now keyed by their MCP transport session instead (one key per client connection, per ADR 006 §4.1); stdio reports a constant session ID, so the inherently single-user stdio transport keeps one stable session. Consequence for unauthenticated HTTP: a session ends with the connection, so a reconnecting client re-runs core_auth_login for its downstream backends. Enable muster’s own OAuth to get durable per-user sessions that survive reconnects. Covered by the session-multi-user-progressive-auth and session-multi-user-tool-isolation scenarios, whose isolation assertions previously passed vacuously (see below).
    • Test framework: expected.not_contains is now evaluated for test_* steps. The scenario loader accepted the field and the regular tool path implemented it, but the test-tool path only logged a warning and passed, so every absence assertion written on a test_* step was vacuous — including the session-isolation assertions in session-multi-user-progressive-auth and session-multi-user-tool-isolation, which is why the leak above went unnoticed. It now fails the step when the response contains an unexpected string, matching the non-test-tool path.
  • Fixed

    • Helm: values.schema.json no longer rejects valid chart values. podDisruptionBudget.minAvailable accepts a percentage string ("50%") as well as an integer, podDisruptionBudget.maxUnavailable is now a declared value (the PDB template already honoured it, but the schema refused it as an unknown key), and the free-form gatewayAPI.httpRoute.{labels,annotations} / gatewayAPI.backendTrafficPolicy.{labels,annotations} maps accept arbitrary keys. Setting any of these previously failed at helm install/helm template time with values don't meet the specifications of the schema(s).
  • Added

    • (muster) Turn on the MCPServer connection-state alerts in #231 by @teemow

    Full Changelog: https://github.com/giantswarm/agent-platform/compare/v2.9.0...v2.10.0