feat(security): cross-session blast radius for leaked credentials#324
Merged
Conversation
fd88b46 to
d9fe71f
Compare
ea197f0 to
6f7ecc7
Compare
6f7ecc7 to
d4c1f2a
Compare
A leaked credential rarely lives in one session. Spool already collapses repeated occurrences of a value WITHIN a session into one ×N row; this extends that view across the whole archive: a credential finding now shows 'Appears in N sessions across M projects', expandable to the per-session list. This is uniquely possible because Spool indexes every session — the user sees the full Spool-surface exposure of one secret in one place. - Core: occurrencesByValueHash(db, kind, valueHash) aggregates ACTIVE findings sharing a (kind, value_hash) across all sessions/projects, with per-session count + project + lastSeen, ordered most-recent. Dismissed/purged occurrences are excluded (they no longer leak). - IPC channel + preload + renderer api adapter + OccurrenceBySession type threaded through. - UI: BlastRadius component on SecurityPage credential finding rows (high-severity only — identity/PII recurrence across sessions is expected, not actionable). Collapsed quiet line → expandable list, DESIGN-compliant (Lucide 14/12px stroke 1.5, sentence case, warm tokens). Refetches on findings-changed so a purge elsewhere shrinks the radius live. - i18n across all 7 locales. - Tests: core blast-radius.test.ts (cross-session/project counts, active-only, kind-keyed, ordering); IPC OCCURRENCES_BY_VALUE_HASH test; e2e shows the 2-session radius and expands the list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
d4c1f2a to
1e309f6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A high-severity (credential) finding now carries a quiet "Also in N other sessions" line that expands to the per-session list — each row a source dot + session title + project — showing everywhere the same leaked value appears across the whole archive.
Why
Spool already dedupes a value within a session (the ×N badge). The uniquely-Spool insight is cross-session reach: a key that surfaces in 4 other sessions is a far bigger exposure than one confined to where you're looking. The headline is framed around OTHER sessions (the current one is excluded — the in-session ×N badge already covers it), so the line only appears when the secret actually escaped elsewhere.
How it connects
occurrencesByValueHashin core groups active findings by session (joiningsourcesso each row renders with the standard source dot used across the sidebar / library / shares).OccurrenceBySessiontype; the component reads live and debounce-refetches ononChange, so a purge/dismiss elsewhere shrinks the radius.~/.claudesession files are never touched.Test plan
blast-radius.test.ts): per-session aggregation, project/title/uuid/source carried, active-only counting, ordering, empty result.🤖 Generated with Claude Code