Skip to content

fix(kubescape): keep scheduled posture scans local so results persist#2443

Merged
botantler-1[bot] merged 2 commits into
mainfrom
claude/kubescape-scan-keeplocal-fix
Jul 4, 2026
Merged

fix(kubescape): keep scheduled posture scans local so results persist#2443
botantler-1[bot] merged 2 commits into
mainfrom
claude/kubescape-scan-keeplocal-fix

Conversation

@devantler

Copy link
Copy Markdown
Contributor

🤖 Generated by the Daily AI Assistant

Why

The Kubescape compliance dashboard has been frozen on week-old results — every control shows failing and the score reads 0, even for workloads already exempted by policy (e.g. privilege escalation on longhorn/velero/coroot). Since the scanner was bumped to v4.0.9, the scheduled posture scan has aborted before it can save any results, so the exceptions and fresh findings never surface.

What

Forces the scheduled scan to run local-only so it stops trying to submit its report to the cloud — the step that crashes on a volume-mount bug in the current chart. Fresh results then persist every run, with the existing exceptions applied, unfreezing the whole dashboard. No functional scanning is lost (this cluster has no cloud account anyway).

Interim override mirroring a merged-but-unreleased upstream chart fix (kubescape/helm-charts#862, issue #857); drop it once that ships in a chart release past 1.40.2.

The scheduled configuration scan has aborted every run since the v4.0.9
scanner bump (#2316), freezing the Kubescape compliance dashboard on stale
06-17 results: every control — including those already exempted by the
ClusterSecurityException CRs (e.g. C-0016 on longhorn/velero/coroot) — shows
failing and the score reads 0.

Root cause: with kubescapeOffline enabled, chart 1.40.2 still leaves the
scheduled scan's request-body Submit path active, so the scanner tries to
submit its report to the ARMO cloud and write a generated account ID to
/home/nonroot/.kubescape/config.json. That path is an empty emptyDir mounted
via subPath, which kubelet materialises as a directory, so the write fails
("is a directory"), the scan is marked failed, and no fresh
WorkloadConfigurationScan results are persisted.

Force the scheduled scan to keep results local (scanV1.keepLocal:true), which
makes the scanner run local-only — no cloud submit, no account-ID write, the
config.json mount never opened — so scans complete and persist fresh results
each run, with the existing exceptions applied. This mirrors the merged but
unreleased upstream fix (kubescape/helm-charts#862, issue #857); drop the
override once the chart releases past 1.40.2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c0f3d52a-3252-4e7b-b4dd-28c2affb3775

📥 Commits

Reviewing files that changed from the base of the PR and between d8deb0f and bfb4de6.

📒 Files selected for processing (1)
  • k8s/bases/infrastructure/controllers/kubescape/helm-release.yaml
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • devantler-tech/actions (auto-detected)
  • devantler-tech/aws (auto-detected)
  • devantler-tech/reusable-workflows (auto-detected)
  • devantler-tech/ksail (auto-detected)
  • devantler-tech/ascoachingogvaner (auto-detected)
  • devantler-tech/wedding-app (auto-detected)
  • devantler-tech/agent-skills (auto-detected)
📜 Recent review details
⚠️ CI failures not shown inline (2)

GitHub Actions: 🔀 Enable Auto-Merge / 0_auto-merge.txt: fix(kubescape): keep scheduled posture scans local so results persist

Conclusion: failure

View job details

##[group]Run set +e
 �[36;1mset +e�[0m
 �[36;1mREVIEW_OUTPUT=$(gh pr review "$PR_NUMBER" --approve --repo "$REPOSITORY" 2>&1)�[0m
 �[36;1mREVIEW_EXIT_CODE=$?�[0m
 �[36;1mset -e�[0m
 �[36;1m�[0m
 �[36;1mif [[ $REVIEW_EXIT_CODE -eq 0 ]]; then�[0m
 �[36;1m  echo "✅ PR #${PR_NUMBER} approved"�[0m
 �[36;1melif [[ "$REVIEW_OUTPUT" == *"Can not approve your own pull request"* ]]; then�[0m
 �[36;1m  echo "::warning::Could not approve PR #${PR_NUMBER} because GitHub does not allow self-approval. Skipping approval."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Failed to approve PR #${PR_NUMBER}."�[0m

GitHub Actions: 🔀 Enable Auto-Merge / auto-merge: fix(kubescape): keep scheduled posture scans local so results persist

Conclusion: failure

View job details

##[group]Run set +e
 �[36;1mset +e�[0m
 �[36;1mREVIEW_OUTPUT=$(gh pr review "$PR_NUMBER" --approve --repo "$REPOSITORY" 2>&1)�[0m
 �[36;1mREVIEW_EXIT_CODE=$?�[0m
 �[36;1mset -e�[0m
 �[36;1m�[0m
 �[36;1mif [[ $REVIEW_EXIT_CODE -eq 0 ]]; then�[0m
 �[36;1m  echo "✅ PR #${PR_NUMBER} approved"�[0m
 �[36;1melif [[ "$REVIEW_OUTPUT" == *"Can not approve your own pull request"* ]]; then�[0m
 �[36;1m  echo "::warning::Could not approve PR #${PR_NUMBER} because GitHub does not allow self-approval. Skipping approval."�[0m
 �[36;1melse�[0m
 �[36;1m  echo "::error::Failed to approve PR #${PR_NUMBER}."�[0m
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{yaml,yml}: Use Kustomize overlays rather than editing base resources directly; k8s/bases/ is immutable from overlays and changes should be made with patches: in provider or cluster overlays.
Keep manifest changes small and use YAML/schema validation before submitting a manifest PR; for files with cluster context, prefer ksail workload validate / kubectl kustomize / kubectl apply --dry-run=client as appropriate.

Files:

  • k8s/bases/infrastructure/controllers/kubescape/helm-release.yaml
k8s/**

📄 CodeRabbit inference engine (AGENTS.md)

k8s/**: Respect Flux dependency order: bootstrapinfrastructure-controllersinfrastructureapps, with the prod-only infrastructure-overprovisioning layer hanging off infrastructure without gating apps.
Follow the hierarchical Kustomization flow: base configurations in k8s/bases/ feed provider overlays in k8s/providers/, which feed cluster overlays in k8s/clusters/.

Files:

  • k8s/bases/infrastructure/controllers/kubescape/helm-release.yaml
k8s/bases/infrastructure/**

📄 CodeRabbit inference engine (AGENTS.md)

k8s/bases/infrastructure/**: Under k8s/bases/infrastructure/, organize resources component-folder-first: a component's HelmRelease/HelmRepository and its own CRs should live together in a folder named after the component unless a split is required.
Split a custom resource into its own plural-Kind folder only when it cannot live with its component, such as for CRD dependency ordering or because it is cluster-scoped/cross-cutting.

Files:

  • k8s/bases/infrastructure/controllers/kubescape/helm-release.yaml
k8s/bases/infrastructure/**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

k8s/bases/infrastructure/**/*.{yaml,yml}: For component-folder files, name manifests after the resource Kind in kebab-case; if a folder contains multiple resources of the same Kind, qualify filenames with a purpose suffix.
For CR-folder files, omit the folder-implied Kind from the filename and use the verb-purpose.yaml form.
Name Flux Kustomization resources flux-kustomization*.yaml; keep the kustomize build file named exactly kustomization.yaml.

Files:

  • k8s/bases/infrastructure/controllers/kubescape/helm-release.yaml
🧠 Learnings (1)
📚 Learning: 2026-07-01T21:13:36.950Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 2359
File: k8s/bases/apps/actual-budget/helm-release.yaml:62-111
Timestamp: 2026-07-01T21:13:36.950Z
Learning: When reviewing Kustomize/Helm YAML in this repo, keep the base vs provider overlay split: `k8s/bases/apps/**` and `k8s/bases/infrastructure/**` should contain each app’s full, environment-agnostic configuration (including base-level postRenderer Kustomize patches such as deployment strategy, topology spread, probes, and env injection). `k8s/providers/{docker,hetzner}/**` should only add small provider-specific deltas (e.g., `interval`, `persistence.size`) via patch files (like `k8s/providers/<provider>/apps/<app>/patches/helm-release-patch.yaml`). If configuration is identical across providers (e.g., OIDC/OAuth env vars where `${domain}` is resolved per cluster via envsubst), it belongs in the base and must not be duplicated into provider overlays.

Applied to files:

  • k8s/bases/infrastructure/controllers/kubescape/helm-release.yaml
🔀 Multi-repo context devantler-tech/ksail, devantler-tech/reusable-workflows, devantler-tech/actions

Linked repositories findings

devantler-tech/ksail

  • pkg/client/kubescape/client.go and pkg/client/kubescape/buildscaninfo_test.go are the only Kubescape-specific code paths found. The repo’s scan command docs and CLI reference also mention ksail workload scan and --exceptions in docs/src/content/docs/cli-flags/workload/workload-scan.mdx. I did not find references to keepLocal, kubescapeOffline, riskAcceptance, or kubescapeScheduler, so this repo does not appear to consume the HelmRelease fields changed by the PR. [::devantler-tech/ksail:]

devantler-tech/reusable-workflows

  • No matches for Kubescape-related terms (kubescape, keepLocal, kubescapeOffline, kubescapeScheduler, v1beta1, etc.). No cross-repo impact identified. [::devantler-tech/reusable-workflows:]

devantler-tech/actions

  • No matches for Kubescape-related terms (kubescape, keepLocal, kubescapeOffline, kubescapeScheduler, v1beta1, etc.). No cross-repo impact identified. [::devantler-tech/actions:]
🔇 Additional comments (3)
k8s/bases/infrastructure/controllers/kubescape/helm-release.yaml (3)

20-107: LGTM!


159-176: LGTM!


127-158: 🎯 Functional Correctness

Out-of-scope hunk The nodeAgent.resources block and kubescape.image.tag: v4.0.10 override are already present; this PR only adds the keepLocal changes.

			> Likely an incorrect or invalid review comment.

📝 Walkthrough

Walkthrough

This PR updates the Kubescape HelmRelease values file to add inline documentation explaining a limitation in offline posture scanning behavior on chart version 1.40.2, and adds a scheduler requestBody override that sets scanV1.keepLocal: true so scheduled scans run local-only.

Changes

Kubescape offline posture fix

Layer / File(s) Summary
Document offline limitation and enforce keepLocal
k8s/bases/infrastructure/controllers/kubescape/helm-release.yaml
Expands comments explaining the offline scan behavior and adds a kubescapeScheduler.requestBody override that sets scanV1.keepLocal: true for scheduled scans.

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: keeping scheduled Kubescape scans local so results persist.
Description check ✅ Passed The description matches the change and explains the local-only scan fix and why it was needed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Daily AI Assistant

Heads-up on the sequencing: unfreezing scans here is necessary but not sufficient to make posture exceptions apply. The scanner's CRD exceptions getter in v4.0.9 lists the CRs at kubescape.io/v1, but the chart's CRDs serve only v1beta1 — the List 404s and, as the merged/secondary source, is silently swallowed (kubescape#2366 fixes the version; first shipped in image v4.0.10). So once this PR lands and scans resume, exempted controls would still render as failing under v4.0.9.

Bumping the scanner to v4.0.10 is #2452. The full offline pipeline is #2316 (merged: reader + RBAC) → this (#2443, unfreeze) → #2452 (v4.0.10, read CRs at v1beta1) — after which the per-control authoring PRs (#2442/#2446/#2440/#2434) take effect.

(Note: this corrects the assumption baked into #2316 that v4.0.9's getter reads the right version — it doesn't.)

Keep #2452's v4.0.10 scanner override and this branch's keepLocal
scheduler request-body — both layers of the posture fix are required.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@botantler-1 botantler-1 Bot enabled auto-merge July 4, 2026 16:36
@botantler-1 botantler-1 Bot added this pull request to the merge queue Jul 4, 2026
Merged via the queue into main with commit bcd9858 Jul 4, 2026
15 checks passed
@botantler-1 botantler-1 Bot deleted the claude/kubescape-scan-keeplocal-fix branch July 4, 2026 16:40
@github-project-automation github-project-automation Bot moved this from 🫴 Ready to ✅ Done in 🌊 Project Board Jul 4, 2026
@botantler-1

botantler-1 Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.97.3 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

1 participant