Repository navigation
fix(kubescape-bridge): a fingerprint collision with a previously filed theme silently adopts its issue #2934
Description
🤖 Generated by the Agentic Engineer
Evidence
Raised as a P2 by Codex review on #2917 (scripts/kubescape-backlog-bridge/issues.go:687) and
confirmed by reading the code. It is a genuinely different path from the same-run collision
already guarded by errCollidingThemes, which is why the existing guard does not cover it.
planWrites builds claimedBy from the themes present in the current derivation, so it catches
two themes colliding within one run. The lookup byFingerprint[fp] then trusts the fingerprint
alone to identify a tracked issue. A theme filed by an earlier run is not in claimedBy, so a
later theme whose fingerprint collides with it is treated as that same theme and adopts its issue —
updating or reopening it under a different identity, with no errCollidingThemes raised.
Problem
The fingerprint is 64-bit, so a colliding pair is findable in roughly 2^32 trials. Someone able to
influence scanner input can file one key, then supply only the colliding key on a later run, and the
bridge silently rewrites the first issue's content and state under the second key. The audit history
of a security backlog entry is corrupted, and nothing reports an anomaly — the run looks entirely
successful.
Impact is bounded: it needs influence over scanner input and offline collision search, and it
corrupts tracking rather than granting access. It is filed as its own slice rather than fixed inline
because both viable fixes carry a data migration (below), which does not belong in the delivery PR
that surfaced it.
Why this is not a small fix
The tracked entry does not currently retain enough identity to verify a match:
**Surface:**is recoverable from the body (entrySurfaceparses it back), so a
posture-vs-CVE collision is detectable cheaply.- The Key is only present in the issue title, which
renderTitletruncates and digests once it
exceeds GitHub's limit — so it is not reliably recoverable.
A Surface-only check would therefore close cross-surface collisions while leaving same-surface ones
open, and would read as complete while being partial. That is the worse outcome: a guard that looks
like it verifies identity but does not.
Options
- Retain theme identity in the entry — add an explicit identity marker to the rendered body
alongside the existing fingerprint marker, and compare it before adopting a tracked issue.
Existing issues predate the marker, so it needs an absent-marker path that does not re-file
everything as duplicates. - Widen the fingerprint to a collision-resistant length. Simpler to reason about, but it changes
every existing marker, so without a migration every tracked issue is re-created as a duplicate —
exactly the duplicate storm the listing budget exists to prevent.
Either way the migration is the substance of the work, not the comparison.
Acceptance criteria
- A theme whose fingerprint collides with a previously filed entry of a different identity is
refused rather than adopting that entry, and the refusal names both identities. - Already-filed issues carrying the current marker format keep working — no mass re-creation, proven
by a test over entries written in the old format. - The guard is pinned by a test that fails when the identity comparison is removed (ablation, not
just a passing assertion).
Rough size
Small-to-medium: the comparison is a few lines; the migration path and its tests are the bulk.
Metadata
Metadata
Assignees
Labels
Type
Fields
Projects
- StatusShow more project fields✅ Done
Activity
coderabbitai commentedon Aug 3, 2026
🔗 Related PRs
#2404 - fix: tenant artifact verification rejects the dual signing identities from
#2399[merged]#2635 - fix(deploy): reboot stale nodes so containerd adopts refreshed GHCR auth [merged]
#2821 - security: pin the tenant RGD cosign subject to actions and a fixed ref [merged]
#2830 - feat(ci): publish Kubescape posture findings to Code Scanning [merged]
#2876 - feat(security): derive themed, deduped backlog entries from live Kubescape findings [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!
chore: agent-claim #2934 nonce=368e1ce9b8f8a15ca56de1d1237f5ad6