Repository navigation
Kubescape findings surface only as a compliance score, so a regression names no resource or line #2862
Description
🤖 Generated by the Agentic Engineer
Part of #2451 — its decomposition item (a) SARIF→Code-Scanning PR gate.
Evidence
ci.yamls 🔎 Scan manifests (Kubescape NSA) — hard gate runs ksail workload scan --framework nsa --exceptions ... --compliance-threshold 95. That is the entire finding surface today: a single pass/fail score in a job log.
Measured on main at 5596d879d (ksail 7.178.1, exceptions applied): the scan produces 4 findings across 2 controls — C-0034 and one other — in k8s/bases/apps/umami/cron-job.yaml, k8s/bases/infrastructure/vault-backup/{job,cron-job}.yaml, and k8s/bases/infrastructure/vault-config/job.yaml. None of that detail reaches anybody. The gate passes at 95, so all four stay invisible; if a fifth appeared and dropped the score, CI would say only "below threshold".
Audience and problem
The engineer draining this backlog, and the maintainer reviewing a PR. A score tells you that posture moved, never what moved — so triaging a regression means re-running the scan locally and diffing by hand. Findings also have no identity across runs: nothing dedups them, nothing closes them when fixed, and nothing shows them on the PR that caused them.
Hypothesis
Kubescape can already emit SARIF 2.1.0 (--format sarif), and it carries per-resource artifactLocation.uri + region.startLine. Uploading that to GitHub Code Scanning gives per-line PR annotations, native dedup via partialFingerprints, auto-close-when-gone, and a persistent Security-tab view — none of which we have to build or maintain.
Success signal
Kubescape findings appear in the repo Security tab and as PR annotations, each linking to the correct existing file and line; a fixed finding disappears without manual bookkeeping.
Smallest useful change
Add two steps to the existing validate job (the scan is ~5s, so it re-scans rather than changing the gates behaviour):
- emit SARIF and re-root its URIs to the repository root;
- upload it with
github/codeql-action/upload-sarifunder a distinctkubescape-nsacategory.
artifactLocation.uri relative to the scanned root (spec.workload.sourceDirectory = k8s), e.g. bases/infrastructure/vault-backup/job.yaml. Code Scanning resolves URIs against the repository root, where that path does not exist. Uploaded unmodified, every annotation silently matches no file — the feature would look shipped and show nothing.
Acceptance criteria
- Kubescape SARIF uploads to Code Scanning on PRs, under its own category, without disturbing CodeQL default setup.
- Every SARIF URI resolves to a file that exists at the repository root (asserted, with a control proving the re-rooting is load-bearing).
- The existing compliance-threshold gate keeps its current behaviour and human-readable output.
- SARIF is still produced when the gate fails — that is when findings matter most.
- Fork PRs, which get a read-only token, skip the upload instead of failing.
Size
S — one workflow change. Items (b) the CRD→issue bridge and (c) Kyverno-Enforce graduation remain open under #2451.
Metadata
Metadata
Assignees
Labels
Type
Fields
Projects
- StatusShow more project fields✅ Done
Activity
coderabbitai commentedon Jul 29, 2026
🔗 Related PRs
#2316 - fix(kubescape): make ClusterSecurityException posture exceptions take effect [merged]
#2443 - fix(kubescape): keep scheduled posture scans local so results persist [merged]
#2794 - fix(opencost): restore usage metrics [merged]
#2830 - feat(ci): publish Kubescape posture findings to Code Scanning [merged]
#2847 - fix(ci): report what the Kubescape scan actually found [merged]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
You can configure auto-planning by selecting labels in the issue_enrichment configuration.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
devantler commentedon Jul 29, 2026
Closing as a duplicate of #2829, which is already closed as completed by #2830 (merged 2026-07-28T17:55:35Z).
I filed this from a worktree based on the monorepos pinned platform gitlink, which was 22 commits behind live
main— somainalready carried the SARIF emit, the path normalisation (scripts/normalize-sarif-paths.sh) and the Code Scanning upload while my checkout showed none of it. My mistake was creating a child of #2451 without first reading the parents existing sub-issues; #2829, #2854 and #2855 already covered its (a)/(b)/(c) decomposition.No work is lost: I am reviewing the merged implementation against the one I had independently derived and will report anything that differs, on #2829 or as a new issue if it is a real defect.