Skip to content

v1.23.1

Latest

Choose a tag to compare

@github-actions github-actions released this 04 Aug 03:22
ef60aba

KubeBolt 1.23.1 — cross-organization metric read, and four fixes behind it

1.23.1 is a security patch over 1.23.0. Drop-in — no schema change, no
migration, no agent bump (the node agent stays at 1.3.1).

Upgrade if you run KubeBolt with more than one organization. The rest of this
release is worth having; the first item is worth acting on.

Security

Cross-organization metric read. Any authenticated user — a viewer included —
could read another organization's series by naming the tenant in their own
PromQL. injectLabelMatcher left a {...} selector alone when it already
mentioned the label the server was about to inject, so a client-supplied
tenant_id or cluster_id survived into the query and the server's own scope
was never applied.

Those labels are now stripped from client input before the server injects its
own, so the server is the sole source of scope. Validated read-only against a
production cluster.

Both metric paths are covered — instant and range — along with the
subquery/nested-selector shapes that a hand-written PromQL can reach.

Fixes

  • Insights outlived their cause. A rule fired, and the insight then aged out
    on a timer rather than when the underlying condition cleared. A recovered
    workload could stay flagged for up to an hour. Every rule is now a predicate
    over current state: a historical artefact may arm an alert but never keeps one
    alive. Persisted insights are hydrated at boot, so a restart no longer strands
    active ones. An invariant test covers all 24 rules and fails if a new rule is
    added that violates the property.

  • A nameless fallback AI provider broke Kobi turns. When the fallback was
    configured without a provider name, a recoverable error on the primary turned
    into a bare unknown provider: and the whole turn failed — the fallback made
    things worse than having none. Reproduced locally in both directions.

  • Settings errors said only that they failed. A rejected settings save
    answers with {error, field, message}, where error is the category and
    message is the reason. The client read error first, so every settings form
    showed a flat "validation failed" and discarded the only part that said what to
    fix — including the Slack webhook validator, whose message carries the real
    parse error.

  • The cluster map showed phantom external endpoints. The (external) region
    filled with nodes nothing connected to. Pods were filtered by kind and
    namespace, but the loop building external nodes walked every flow in the
    cluster, so a namespace-scoped view still got a node for every destination
    anyone had talked to; their edges were then dropped, leaving the nodes
    orphaned. They were not destinations without connections — every one is built
    from a flow — they were destinations whose connection came from a namespace
    the viewer had already excluded. On one dev cluster a vulnerability scanner
    pulling its database from CDNs accounted for 96 of the distinct external
    addresses while the two visible namespaces contributed one between them.

Upgrading

helm upgrade kubebolt oci://ghcr.io/clm-cloud-solutions/kubebolt/helm/kubebolt --version 1.23.1

No values change, no agent action required.


Install

Helm (recommended for Kubernetes)

helm install kubebolt oci://ghcr.io/clm-cloud-solutions/kubebolt/helm/kubebolt
kubectl port-forward svc/kubebolt 3000:80

Single Binary (download below)

# macOS Apple Silicon
curl -LO https://github.com/clm-cloud-solutions/kubebolt/releases/download/v1.23.1/kubebolt-darwin-arm64
chmod +x kubebolt-darwin-arm64 && mv kubebolt-darwin-arm64 /usr/local/bin/kubebolt

# Linux amd64
curl -LO https://github.com/clm-cloud-solutions/kubebolt/releases/download/v1.23.1/kubebolt-linux-amd64
chmod +x kubebolt-linux-amd64 && sudo mv kubebolt-linux-amd64 /usr/local/bin/kubebolt

kubebolt --kubeconfig ~/.kube/config

All platform binaries are attached below. Verify with sha256sum -c CHECKSUMS.txt.

Docker (single container)

docker run -p 3000:3000 -v ~/.kube:/root/.kube:ro \
  ghcr.io/clm-cloud-solutions/kubebolt:1.23.1

Homebrew (macOS, Linux)

brew install clm-cloud-solutions/tap/kubebolt

kubectl krew plugin

kubectl krew index add clm https://github.com/clm-cloud-solutions/krew-index.git
kubectl krew install clm/kubebolt
kubectl kubebolt

Docker Compose

git clone https://github.com/clm-cloud-solutions/kubebolt.git
cd kubebolt/deploy && docker compose up -d

Container Images

  • Single container (binary + frontend): ghcr.io/clm-cloud-solutions/kubebolt:1.23.1
  • API only: ghcr.io/clm-cloud-solutions/kubebolt/api:1.23.1
  • Web only: ghcr.io/clm-cloud-solutions/kubebolt/web:1.23.1

Changelog

Fixes

  • fix(map): only show external endpoints reachable from a visible pod ()
  • fix(web): show why a settings save was rejected, not just that it was ()
  • fix(copilot): stop a nameless fallback provider from breaking Kobi turns ()
  • fix(security): strip client-supplied tenant_id/cluster_id from PromQL ()
  • fix(web): make the useWebSocket test typecheck ()
  • fix(insights): clear on observed recovery, not on a clock ()

Documentation

  • docs(insights): revise the flap-damping analysis; add ==> Go build + vet
    ==> Go test -race
    ? github.com/kubebolt/kubebolt/apps/api/cmd/mcp [no test files]
    ? github.com/kubebolt/kubebolt/apps/api/cmd/server [no test files]
    ok github.com/kubebolt/kubebolt/apps/api/internal/agent 1.190s
    ok github.com/kubebolt/kubebolt/apps/api/internal/agent/channel 2.134s
    ok github.com/kubebolt/kubebolt/apps/api/internal/api 2.665s
    ok github.com/kubebolt/kubebolt/apps/api/internal/audit 1.010s
    ok github.com/kubebolt/kubebolt/apps/api/internal/auth 103.515s
    ok github.com/kubebolt/kubebolt/apps/api/internal/cluster 1.226s
    ok github.com/kubebolt/kubebolt/apps/api/internal/config 1.021s
    ok github.com/kubebolt/kubebolt/apps/api/internal/copilot 1.213s
    ok github.com/kubebolt/kubebolt/apps/api/internal/helm 1.053s
    ok github.com/kubebolt/kubebolt/apps/api/internal/insights 1.044s
    ok github.com/kubebolt/kubebolt/apps/api/internal/integrations 1.159s
    ? github.com/kubebolt/kubebolt/apps/api/internal/logging [no test files]
    ok github.com/kubebolt/kubebolt/apps/api/internal/mcp 1.079s
    ? github.com/kubebolt/kubebolt/apps/api/internal/metrics [no test files]
    ? github.com/kubebolt/kubebolt/apps/api/internal/models [no test files]
    ok github.com/kubebolt/kubebolt/apps/api/internal/notifications 1.016s
    ok github.com/kubebolt/kubebolt/apps/api/internal/settings 1.116s
    ok github.com/kubebolt/kubebolt/apps/api/internal/updatecheck 1.011s
    ok github.com/kubebolt/kubebolt/apps/api/internal/usage 1.011s
    ok github.com/kubebolt/kubebolt/apps/api/internal/websocket 1.260s
    ==> Web test (full suite, as CI runs it) ()

Other

  • Merge pull request #174 from clm-cloud-solutions/develop ()
  • chore(release): 1.23.1 — cross-organization metric read, and four fixes behind it ()
  • Merge pull request #173 from clm-cloud-solutions/fix/cluster-map-external-scope ()
  • Merge pull request #172 from clm-cloud-solutions/fix/settings-error-detail ()
  • test(web): pin that an API error surfaces the reason, not the category ()
  • Merge pull request #171 from clm-cloud-solutions/fix/kobi-fallback-provider ()
  • Merge pull request #170 from clm-cloud-solutions/fix/cross-org-metrics-scope ()
  • Merge pull request #169 from clm-cloud-solutions/fix/insights-lifecycle ()