요약
LocalCloneManager와 GitleaksScanner는 단일 워킹트리만 처리합니다. 동일한 시크릿이 main, develop, 피처 브랜치에 모두 커밋되어 있어도 각각 별개의 finding으로 잡히거나(흔치 않음), 더 흔하게는 스캔 시점에 체크아웃돼 있던 한 브랜치에서만 잡힙니다. 브랜치별 존재 여부를 통합하거나 나열할 방법이 없습니다.
현재 동작
targets.local.yaml은 타깃당 단일 로컬 checkout을 가리킵니다.
Finding.location은 path + line만 가지고 branch 필드가 없습니다.
fingerprint = canonical_json([repo, path, line, rule_id]) — 서로 다른 브랜치라도 같은 path+line이면 충돌, 브랜치 간 이동했을 때는 별개 finding으로 분리.
gitleaks git 모드는 현재 브랜치의 커밋 히스토리만 스캔.
왜 중요한가
- 유출된 시크릿이 여러 브랜치에 동시에 존재하는 경우가 잦습니다. 브랜치마다 1건씩 보고하면 카운트가 부풀고, 한 브랜치에서만 보고하면 다른 브랜치의 잔존 유출을 놓칩니다(키 로테이션 후에도 다른 브랜치는 그대로 노출).
- 실제 대응은 "이 시크릿이 어느 브랜치에 남아 있나?"에 답해야 하는데, 현재 구조로는 답할 수 없습니다.
작업 제안
Finding(또는 sibling 구조)에 branches: list[str]와 브랜치별 locations: list[Location] 추가. 라운드트립 직렬화 유지.
- 스캔 모델 결정. 이슈 스레드에서 검토할 두 가지:
- (a) Multi-checkout: clone manager가 브랜치별로 N개의 워킹트리를 준비, 스캐너를 N회 실행,
(rule_id, secret_hash)로 결과 머지.
- (b) 단일 checkout + git plumbing: 레퍼런스를 열거하고 각 ref에 대해
gitleaks git 실행. 디스크 중복은 없지만 런타임 상한을 잡기 어려움.
- 크로스 브랜치 dedup 키 정의. 후보:
(repo, rule_id, salted_hash(secret)). path/line은 occurrence 하위 레코드로 이동.
- 기본 스캔 대상 브랜치 결정 및 manifest 표현 방식 (
branches: [main, develop] vs branches: all-non-stale 등).
report / gate / evaluate가 브랜치 fan-out을 노출하도록 업데이트.
- 테스트: clone manager의 multi-checkout 테스트, 스캐너의 merge 로직 테스트, multi-branch finding의 JSONL/DynamoDB store 라운드트립 테스트.
완료 기준
Out of scope
- SCM API를 통한 원격 브랜치 디스커버리. 본 이슈 범위는 로컬 clone — 현재 Phase-1 경계와 일치.
요약
LocalCloneManager와GitleaksScanner는 단일 워킹트리만 처리합니다. 동일한 시크릿이main,develop, 피처 브랜치에 모두 커밋되어 있어도 각각 별개의 finding으로 잡히거나(흔치 않음), 더 흔하게는 스캔 시점에 체크아웃돼 있던 한 브랜치에서만 잡힙니다. 브랜치별 존재 여부를 통합하거나 나열할 방법이 없습니다.현재 동작
targets.local.yaml은 타깃당 단일 로컬 checkout을 가리킵니다.Finding.location은path+line만 가지고 branch 필드가 없습니다.fingerprint = canonical_json([repo, path, line, rule_id])— 서로 다른 브랜치라도 같은 path+line이면 충돌, 브랜치 간 이동했을 때는 별개 finding으로 분리.gitleaks git모드는 현재 브랜치의 커밋 히스토리만 스캔.왜 중요한가
작업 제안
Finding(또는 sibling 구조)에branches: list[str]와 브랜치별locations: list[Location]추가. 라운드트립 직렬화 유지.(rule_id, secret_hash)로 결과 머지.gitleaks git실행. 디스크 중복은 없지만 런타임 상한을 잡기 어려움.(repo, rule_id, salted_hash(secret)). path/line은 occurrence 하위 레코드로 이동.branches: [main, develop]vsbranches: all-non-stale등).report/gate/evaluate가 브랜치 fan-out을 노출하도록 업데이트.완료 기준
Out of scope