AI Agents

  • Fixed

    • The egress rules to kagent’s built-in tool server name the namespace the kagent chart renders it into (giantswarm/agent-platform#421): the kagent-tools subchart renders its Deployment and Services into kagent.kagent-tools.namespaceOverride, else the kagent release’s namespace, and the kagent chart composes the kagent-tool-server RemoteMCPServer URL from the same key — but the connectivity chart’s controller egress and the actors’ egress-gateway rule fell back to the kagent namespace (kagent.namespaceOverride, which moves the controller and not the subchart), and the meta chart set no override for the tools subchart. On graveler, the one installation with kagent.kagent-tools.enabled: true, the server rendered into agent-platform, the URL followed it, the rule said kagent, and the controller’s discovery ran into Cilium’s default-deny: Accepted: False — context deadline exceeded, a reconciler error a minute (no fleet agent binds the server; the Generic chart binds muster). Now the meta chart keeps the tool server in the kagent namespace with every other kagent subchart (kagent.kagent-tools.namespaceOverride: kagent; the connectivity chart carries no default of its own for the key, so the two charts can never read it differently), and the connectivity chart derives the rules’ namespace exactly as the kagent chart does — the override, else the release namespace (agent-platform.kagentTools.*, one derivation for both policies) — so the rules follow wherever the chart renders the server, override or not. make verify-kagent-netpol asserts both fallbacks and, through tests/verify-kagent-tools-namespace.py, renders the kagent chart the range resolves to with the values the meta chart forwards and ties the rules’ namespace and port to the rendered Deployment’s namespace and the RemoteMCPServer URL. Installations act: none — the release rolls through both ranges; on an installation with the tool server on, its Deployment, Services, ServiceAccount and ClusterRoleBinding subject move from the release namespace to the kagent namespace (Helm delete + create), and the RemoteMCPServer becomes Accepted: True on the controller’s next retry.
  • Fixed

    • A connectivity release no longer restarts the portal (giantswarm/agent-platform#424): the Backstage config-reload hook hashed the whole rendered app-config ConfigMap, metadata included, and labels.common carries helm.sh/chart: agent-platform-connectivity-<version> — the connectivity chart is versioned with the meta chart, so the checksum it stamped into the Backstage Deployment moved on every release and rolled the pod (~60 s until Ready; the terminated pod’s in-flight streams to kagent surfaced as The kagent API is not available / “Could not load this session”) with no app-config change behind it (4.9.1 and 4.9.2 on the first 4.x installation, 2026-09-13). The hook now hashes the ConfigMap’s .data only — the app-config document the pod mounts — so the checksum is stable across releases and still moves on a real change (identity block, installation name, agentPlatform.*, hostnames); the render fails loudly if the app-config renders without data. make verify-wiring asserts both: two renders differing only in .Chart.Version yield the same checksum, and each of an installation-name, tenant-identity and issuer change yields a different one. Installations act: none — the release rolls through the connectivity range; the first release carrying it rolls the portal one last time (the checksum’s shape changes), every one after it leaves the pod alone.
  • Fixed

    • The atenet router reaches the worker pods on 8443 (giantswarm/agent-platform#383): substrate-atenet-router allowed the router’s egress to the worker pods on 443 only, but the router tunnels a turn’s A2A request to the actor through the worker’s mTLS CONNECT listener on 8443 (ateom --atunnel-connect-listen-address :8443), so under Cilium’s default-deny every turn on a fleet installation failed with upstream call failed: Connect: deadline has elapsed — graveler’s cut-over (giantswarm/giantswarm#37745) needed a hand-applied bridge policy. The policy now allows 443 and 8443; make verify-kagent-netpol asserts both. Installations act: none — the release rolls through the connectivity range; graveler’s bridge policy substrate-atenet-router-connect-cutover-bridge is removed once it is live there.
  • Changed

    Full Changelog: https://github.com/giantswarm/klaus/compare/v0.1.13...v0.1.14

  • Fixed

    • The substrate-control-plane PolicyException matches Substrate’s control plane by resource name (giantswarm/agent-platform#419): the substrate chart’s ate-api-server and ate-controller Deployments carry no metadata.labels (only their pod templates do), and Kyverno evaluates the autogen rules at Deployment admission against the Deployment’s own labels, so the app In [...] selector never matched them and a cluster enforcing the restricted Pod Security Standard through Kyverno (every Giant Swarm management cluster) denied the substrate install — graveler’s cut-over (giantswarm/giantswarm#37745) needed a hand-applied bridge exception. The exception now matches ate-api-server*, ate-controller*, atenet-router*, atenet-egress*, dns* in the Substrate namespace. make verify-kyverno now evaluates every exception against the controller’s own labels and name, so a label-less Deployment fails the check instead of the install. Installations act: none — the release rolls through the connectivity range; graveler’s bridge exception substrate-control-plane-cutover-bridge is removed once it is live.
  • Fixed

    • The hook Jobs are policed by the chart (giantswarm/agent-platform#413): every hook of this chart — the kagent namespace hook, the two storage-version hooks, the self hooks, the ordered teardown — runs kubectl against the apiserver under the hook identity’s pod labels (app.kubernetes.io/instance: <release>, app.kubernetes.io/component: hooks), and the chart rendered no network policy for them; on a cluster that is default-deny for every endpoint (Cilium policyEnforcementMode: always) the pre-upgrade backup hook of 4.7.13+ looped on dial tcp <apiserver>:443: i/o timeout until its deadline and every meta-chart upgrade failed — the first 4.x installation sat on 4.7.12 from 2026-09-11 23:55Z for that reason. templates/hooks/netpol.yaml renders one policy for the hook identity as a hook object (a pre-install/pre-upgrade hook runs before the release’s manifests exist): weight -10 next to the identity’s ServiceAccount and ClusterRoleBinding, the same delete policy, at all five hook events with the bundled engine and at the storage-version hooks’ four without it; egress to the apiserver only — the kube-apiserver entity in the cilium flavour, networkPolicy.kubernetes.apiServerCIDR in the kubernetes one — gated on networkPolicy.enabled and networkPolicy.flavor like every policy the platform renders. make verify-hooks-netpol asserts both flavours, the events per engine shape, the off switches and that every hook Job’s pod carries the selected labels. An installation that hand-wrote such a policy (the connectivity hooks’ sibling, #367) can drop the meta release’s copy once this release is in. No fleet installation acts — the release stays inert behind the fleet’s <4.0.0 bound.
    • The storage-version backup hook no longer lists the cluster’s Helm release Secrets with their payloads in one call (giantswarm/agent-platform#414): the re-point step (#398) fetched every helm.sh/release.v1 Secret cluster-wide through a client-side jsonpath listing — kubectl get collects the whole objects before such a printer runs — so the pod’s memory grew with the cluster’s Helm history and was OOM-killed at its 128Mi limit on the first 4.x installation (351 release Secrets, 61 MB of payload), failing the hook right after no kagent CRD stores v1alpha2: nothing to migrate. The listing is now the apiserver’s Table (kubectl get … --no-headers, names only), each Secret is read and decoded on its own onto the emptyDir as before, and jq runs only on a manifest that names kagent.dev/v1alpha2 at all (grep first) — memory bounded by the largest single release, not their sum. make verify-kagent-storage-version asserts the Table listing, the absence of a client-side printer and the pre-filter ahead of jq.
  • Added

    • The chart provisions Agent Substrate’s snapshot store on CAPA (giantswarm/agent-platform#411, giantswarm/giantswarm#37705 wave 1e): kagent.harness.snapshotStore.crossplane renders the S3 Bucket (lifecycle expiration aws.lifecycleDays, 30 days by default; public-access block; TLS-only policy; never deleted by Crossplane, kept by Helm) and the IAM Role trusted by Substrate’s atelet and ate-api-server ServiceAccounts in ate-system through the installation’s IRSA OIDC provider, the way postgres.backup.crossplane renders the kagent-pg backup bucket (the Crossplane helpers and the bucket/trust/policy partials are shared: agent-platform.crossplane.*). The meta chart derives kagent.harness.snapshotLocation = s3://<aws.bucketName>/<prefix> for the kagent release (an explicit value that differs fails the render naming both keys), holds the block back from the kagent chart (components.kagent.omitKeys takes dotted paths), and forwards the role’s ARN as eks.amazonaws.com/role-arn on the substrate release’s atelet.serviceAccount.annotations and ateApiServer.serviceAccount.annotations (Substrate 0.0.27-gs.8; a differing explicit role fails the render, an installation’s other annotations stay). Off by default; make verify-substrate-store, ci/test-substrate-store-aws-values.yaml; UPGRADE.md.
  • Fixed

    • (deps) Update module github.com/giantswarm/selfupdate-cosign to v0.2.0 in #1208 by @renovate[bot]

    Full Changelog: https://github.com/giantswarm/muster/compare/v5.18.3...v5.18.4

  • Fixed

    • (deps) Update module github.com/giantswarm/selfupdate-cosign to v0.2.0 in #480 by @renovate[bot]

    Full Changelog: https://github.com/giantswarm/klaus/compare/v0.1.12...v0.1.13

  • Fixed

    • (deps) Update module github.com/giantswarm/selfupdate-cosign to v0.2.0 in #348 by @renovate[bot]

    Full Changelog: https://github.com/giantswarm/klausctl/compare/v0.4.5...v0.4.6