Files
keyhunter/.planning/phases/07-import-cicd/07-02-SUMMARY.md
2026-04-05 23:56:12 +03:00

3.9 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, decisions, metrics, requirements
phase plan subsystem tags requires provides affects tech-stack key-files decisions metrics requirements
07-import-cicd 02 importer
importer
gitleaks
json
csv
normalization
pkg/engine/finding.go
pkg/importer/importer.go
GitleaksImporter (gitleaks JSON)
GitleaksCSVImporter (gitleaks CSV)
normalizeGitleaksRuleID
buildGitleaksFinding
pkg/importer/
added patterns
Header-indexed CSV parsing for column-order resilience
Shared finding-builder helper across JSON/CSV paths
Suffix-stripping rule-ID normalization
created modified
pkg/importer/gitleaks.go
pkg/importer/gitleaks_test.go
pkg/importer/testdata/gitleaks-sample.json
pkg/importer/testdata/gitleaks-sample.csv
RuleID normalization strips suffixes (-api-key, -access-token, -secret-key, -secret, -token, -key) in that order; unknown patterns are lowercased only
CSV reader resolves columns by header name (not position) for forward-compat with Gitleaks column-order drift
StartLine parse errors in CSV are swallowed (LineNumber=0) — findings remain ingestible
Confidence fixed to 'medium' because Gitleaks does not verify keys
duration completed tasks files tests
~4m 2026-04-05 1 4 8
IMP-02

Phase 7 Plan 02: Gitleaks Importer Summary

One-liner: Gitleaks JSON and CSV output ingests into normalized engine.Finding records with provider-name normalization (e.g., openai-api-key -> openai) and header-indexed CSV parsing for column-order resilience.

What was built

  • GitleaksImporter (Name() = "gitleaks") decodes a JSON array of Gitleaks finding records into []engine.Finding.
  • GitleaksCSVImporter (Name() = "gitleaks-csv") reads CSV with a mandatory header row, resolves columns by name so column order drift does not break ingestion.
  • normalizeGitleaksRuleID trims common Gitleaks suffixes (-api-key, -access-token, -secret-key, -secret, -token, -key) after lowercasing; unknown patterns pass through lowercased (e.g., github-pat -> github-pat).
  • buildGitleaksFinding is a private helper used by both JSON and CSV paths so the two stay in lockstep: sets SourceType="import:gitleaks", Confidence="medium", VerifyStatus="unverified", Verified=false, and falls back from File to SymlinkFile when blank.
  • Fixtures with 3 records each (OpenAI / AWS / generic) in matching JSON and CSV shapes.

Tests

All 8 tests under go test ./pkg/importer/... -run Gitleaks -v pass:

  • TestGitleaksImporter_Name — Name() assertions for both importers
  • TestGitleaksImporter_JSON — 3-record fixture, provider names, line numbers, SourceType, Confidence, masked key
  • TestGitleaksImporter_CSV — same assertions against CSV fixture
  • TestGitleaksImporter_NormalizeRuleID — table: openai/aws/anthropic/generic/github-pat + case variants
  • TestGitleaksImporter_EmptyArray[] returns empty slice, nil error
  • TestGitleaksImporter_EmptyCSV — header-only returns empty slice, nil error
  • TestGitleaksImporter_InvalidJSON — returns wrapped error
  • TestGitleaksImporter_SymlinkFallback — uses SymlinkFile when File is blank

Full package go test ./pkg/importer/... also passes (trufflehog/dedup tests from the parallel 07-01 plan continue to pass alongside).

Commits

  • bd8eb9b feat(07-02): add Gitleaks JSON + CSV importers

Deviations from Plan

None - plan executed exactly as written. The Importer interface file (pkg/importer/importer.go) was already present from the parallel wave-1 Plan 07-01, so this executor did not need to create it (plan explicitly allowed for either case).

Self-Check: PASSED

  • FOUND: pkg/importer/gitleaks.go
  • FOUND: pkg/importer/gitleaks_test.go
  • FOUND: pkg/importer/testdata/gitleaks-sample.json
  • FOUND: pkg/importer/testdata/gitleaks-sample.csv
  • FOUND commit: bd8eb9b
  • Tests: 8/8 passing
  • Build: go build ./pkg/importer/... clean