feat(sbommanager): key SBOM name on (digest, syftVersion)#823
feat(sbommanager): key SBOM name on (digest, syftVersion)#823jnathangreeg wants to merge 1 commit into
Conversation
Previously sbom_manager built the SBOMSyft resource name from ImageInfoToSlug(imageTag, imageID), which mixed the image tag into the reservation key. Two references to the same digest under different tags (e.g. myapp:v1 + myapp:latest with identical digest) produced different SBOM names and got tracked as independent reservations even though the underlying SBOM content is byte-identical. Switch the name composition to (digest, syftVersion): - normalizedID is computed first. - The slug is built from (s.version, normalizedID) so the digest hash stub identifies the image and the (sanitized) syft version distinguishes tool-version upgrades. - The original image tag is preserved as ImageTagMetadataKey on the annotations for traceability — tag/name is metadata now, not key. This aligns sbom_manager's reservation contract with the way content-addressed storage layers (e.g. the kubescape/backend gRPC store) actually key SBOMs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe change refactors ChangesImage ID Normalization Deduplication
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
matthyx
left a comment
There was a problem hiding this comment.
Blocking issue: this PR changes the SBOMSyft name contract in node-agent, but kubevuln still looks these objects up by the old image-slug-based name.
In node-agent the name now comes from names.ImageInfoToSlug(s.version, normalizedID) in pkg/sbommanager/v1/sbom_manager.go, while kubevuln still computes/uses names.ImageInfoToSlug(imageTagNormalized, imageHash) / workload.ImageSlug in controllers/http.go and core/services/scan.go, then does a direct SBOMSyfts(...).Get(name) in repositories/apiserver.go.
That changes the shared storage key, so kubevuln will stop finding node-agent-generated SBOMs and will regenerate them instead of reusing them. I think this has to be a coordinated cross-repo change (plus migration/cleanup for existing old-name SBOMSyft objects), or the existing name contract should stay in place and dedupe happen another way.
|
this won't work, we have to find another way without renaming the SBOM... because kubevuln expects a certain name to reuse the SBOM (and it'll be the same for backend) |
Performance Benchmark ResultsNode-Agent Resource Usage
Dedup Effectiveness (AFTER only)
Event Counters
|
|
Confirmed the cross-coupling: kubevuln still computes Converting this PR to draft until we settle on a different approach (no rename). Happy to sync whenever works for you. |
Summary
Aligns
sbom_manager's reservation contract with content-addressed storage: the SBOMSyft resource name is now derived from(imageDigest, syftVersion)rather than(imageTag, imageID). The tag becomes metadata via the existingImageTagMetadataKeyannotation.Why
Two tag aliases of the same image (e.g.
myapp:v1+myapp:latestwith identical digest) currently produce different SBOM names and get tracked as independent reservations — even though the underlying SBOM content is byte-identical. Downstream backends that store SBOMs content-addressed (e.g.kubescape/backend's gRPCPutSBOMStreamkeyed on(image_digest, syft_version)) can't faithfully implement the slug-scoped contract, so the adapter has to either dedupe across tags (which masks per-slug state) or layer machinery to maintain a slug→key index.Per the discussion on armosec/private-node-agent#316: "Make the contract digest-scoped end to end in
node-agenttoo (digest + syftVersionas the real key, tag/name only as metadata)."What changes
pkg/sbommanager/v1/sbom_manager.go:normalizedID := normalizeImageID(...)is computed first.sbomName, err := names.ImageInfoToSlug(s.version, normalizedID)— last 6 chars of the digest hex provide the image identity, the sanitized syft version distinguishes tool-version upgrades.Annotations[ImageTagMetadataKey]for traceability.No interface changes (
SbomClientsignatures unchanged); no in-cluster Storage impl changes; no mock changes. The semantic shift lives entirely in howsbomNameis composed.Behavioral notes
processContainerWithMetadatakeeps the same shape because the annotations on the existing row carry that state.Test plan
pkg/sbommanager/v1/...tests pass.🤖 Generated with Claude Code
Summary by CodeRabbit