로컬 checkout에서 secret 유출 가능성을 찾고, 검토 가능한 결과로 정리하는 local-first scanner입니다.
첫 번째 목표는 “한 번 실행해 보는 도구”가 아닙니다. 같은 입력에서 같은 스캔 결과와 판단을 다시 만들 수 있는 작은 파이프라인을 완성하는 것이 목표입니다.
targets.local.yaml -> workspace -> Gitleaks -> Finding -> local store -> report -> gate
이 저장소는 공개 저장소입니다. 실제 대상 목록, 스캔 결과, 외부 보안 도구 export, credential, 내부 이름, 원본 finding은 커밋하지 않습니다.
그런 자료는 private/ 또는 저장소 밖에 둡니다.
현재 구현은 로컬 실행 경로에 집중되어 있습니다.
targets.local.yaml에 적힌 로컬 checkout을 읽습니다.- Gitleaks를 실행해 secret 후보를 찾습니다.
- 스캐너 결과를 내부 표준 모델인
Finding으로 바꿉니다. - 결과를 JSONL 또는 DynamoDB-compatible local store에 저장합니다.
- 저장된 결과로 report와 gate 판단을 다시 만듭니다.
- synthetic corpus로 precision, recall, false negative를 계산합니다.
- Ollama-compatible verifier로 finding의 triage 상태를 보조합니다.
자세한 진행 상황은 progress dashboard와 project overview에 정리되어 있습니다.
현재 다루는 일:
- 로컬 filesystem checkout 스캔
- Gitleaks 기반 secret detection
Finding모델로 결과 정규화- 로컬 저장소에 스캔 이력과 finding 저장
- 저장된 결과 기반 report/gate 생성
- synthetic corpus 기반 품질 측정
- redacted metadata만 사용하는 verifier 실험
현재 지원 범위에 포함하지 않는 일:
- 실제 외부 보안 도구 export 또는 alert data 커밋
- 조직 전체 repository discovery
- 관리형 클라우드 실행 환경 연동
- 내부 endpoint 또는 알림 시스템 연동
- Gitleaks를 대체하는 primary scanner 도입
- SAST/SCA 확장
전제: uv, gitleaks v8, security-scanner source checkout, 스캔할 별도 로컬 checkout이 준비되어 있습니다.
아래 명령은 security-scanner 저장소 root에서 실행합니다. targets.local.yaml에는 스캔 대상 저장소 경로를 적습니다.
uv sync
cp examples/targets.local.example.yaml targets.local.yaml
# targets.local.yaml에 로컬 checkout 경로를 적습니다.
uv run security-scanner scan --manifest targets.local.yaml --output private/findings.jsonl
uv run security-scanner report --findings private/findings.jsonl
uv run security-scanner gate --findings private/findings.jsonl --max 0private/는 gitignore 대상입니다. 실제 스캔 결과와 로컬 설정은 이 경계 안에 두세요.
단계별 설명, manifest 필드, 트러블슈팅은 시작하기 가이드를 참고하세요.
DynamoDB-compatible backend는 로컬에서 조회 패턴을 검증하기 위한 저장소입니다. 관리형 저장소 연동은 현재 지원 범위가 아닙니다.
로컬 DB는 저장소에 포함된 docker-compose.yml의 DynamoDB Local 컨테이너로
띄웁니다. Host에서는 http://localhost:4567에서 응답하고, 데이터는 named
Compose volume에 유지됩니다.
docker compose up -d dynamodb-localHost의 4567 포트가 이미 사용 중이면 SECURITY_SCANNER_DYNAMO_HOST_PORT로
바꿔 띄울 수 있습니다. Worker 컨테이너는 compose 내부 endpoint를 사용하므로
그대로 동작합니다.
SECURITY_SCANNER_DYNAMO_HOST_PORT=14567 docker compose up -d dynamodb-local새 PC에서 public HTTPS repo 하나를 바로 검증하려면 Docker 경로를 사용할 수 있습니다.
SECURITY_SCANNER_QUICKSTART_TARGET=https://github.com/<owner>/<repo> \
docker compose up --build --abort-on-container-exit --exit-code-from worker worker커스텀 GitLab 도메인은 URL만으로 provider를 판별할 수 없으므로 provider hint를 함께 지정합니다.
SECURITY_SCANNER_QUICKSTART_TARGET=https://source.example.test/<group>/<repo> \
SECURITY_SCANNER_SCM_PROVIDER=gitlab \
docker compose up --build --abort-on-container-exit --exit-code-from worker workeruv run security-scanner init-storage \
--storage-backend dynamodb \
--dynamodb-endpoint-url http://localhost:4567 \
--dynamodb-table security_scanner_local_dev
uv run security-scanner scan \
--manifest targets.local.yaml \
--storage-backend dynamodb
uv run security-scanner report \
--storage-backend dynamodb \
--scan-run-id scan_<id>
uv run security-scanner gate \
--storage-backend dynamodb \
--scan-run-id scan_<id> \
--max 0스캔을 실행하면 Scan run ID가 출력됩니다. 특정 실행 결과만 보고 싶으면 그 값을 --scan-run-id로 넘깁니다. 저장소 전체를 대상으로 판단할 때만 생략합니다.
카탈로그(add-target)에 등록한 여러 저장소를 한 번에 스캔하는 scan-all 흐름은 시작하기 가이드의 "주기 스캔 로컬 테스트" 절을 참고합니다. 기본 scan-all은 verifier를 호출하지 않으며, terminal verifier verdict를 disposition에 반영하려면 --verify-artifacts를 명시합니다.
Schema와 조회 기준은 소스 스캔 결과 NoSQL Schema에 정리되어 있습니다.
품질 평가는 실제 비공개 repository가 아니라 synthetic corpus로 먼저 확인합니다.
uv run security-scanner scan \
--manifest eval/synthetic-corpus/targets.local.example.yaml \
--output private/eval-findings.jsonl
uv run security-scanner evaluate \
--expected eval/synthetic-corpus/expected-findings.example.json \
--findings private/eval-findings.jsonlVerifier 적용 전후도 같은 방식으로 비교합니다.
Ollama가 scanner를 실행하는 Ubuntu host에 설치되어 있으면 host는 localhost로 둡니다.
export SECURITY_SCANNER_OLLAMA_HOST=http://127.0.0.1:11434
export SECURITY_SCANNER_OLLAMA_MODEL=lfm2.5-thinking
uv run security-scanner verify \
--findings private/eval-findings.jsonl \
--output private/eval-verified-findings.jsonl
uv run security-scanner evaluate \
--expected eval/synthetic-corpus/expected-findings.example.json \
--findings private/eval-findings.jsonl \
--after-findings private/eval-verified-findings.jsonl오탐 감소 흐름은 detector-visible documentation candidate를 포함한 별도 corpus로 확인합니다.
uv run security-scanner scan \
--manifest eval/verifier-corpus/targets.local.example.yaml \
--output private/verifier-findings.jsonl
uv run security-scanner verify \
--findings private/verifier-findings.jsonl \
--output private/verifier-verified-findings.jsonl
uv run security-scanner evaluate \
--expected eval/verifier-corpus/expected-findings.example.json \
--findings private/verifier-findings.jsonl \
--after-findings private/verifier-verified-findings.jsonl \
--precision-min 0.5Verifier는 detector가 아닙니다. Finding을 삭제하지 않고, 사람이 검토할 때 참고할 triage 상태만 붙입니다.
응답 실패, timeout, 낮은 confidence는 모두 “검토 필요” 상태로 남깁니다.
의존 방향은 단순합니다.
core <- scanners/storage/llm/adapters <- cli/runtime
core/는Finding, policy, report, evaluation을 담당합니다.scanners/gitleaks/는 Gitleaks 실행과 결과 parsing을 담당합니다.storage/는 JSONL과 DynamoDB-compatible 저장소를 담당합니다.llm/ollama/는 redacted metadata 기반 verifier 호출을 담당합니다.adapters/aws_future/는 현재 실행 경로가 아닙니다.
더 자세한 설명은 시스템 구조와 실행 환경을 보세요.
문서의 시작점은 docs/README.md입니다.
- 프로젝트 개요와 추진 전략
- 시스템 구조와 실행 환경
- 소스 스캔 결과 NoSQL Schema
- 탐지 결과와 지표
- Local Scan Orchestration 목표 구조
- 확장 경로와 운영 기준
- 리서치 요약과 기술 결정
- 공개 저장소 안전 정책
docs/views/, docs/assets/, docs/dashboards/는 publish 후보입니다.
docs/workbench/와 docs/reference/는 기본 publish 대상이 아닙니다.
커밋 전 확인할 것:
git status로 staged file을 확인합니다.- Diff에서 secret-like value, private name, host, path, raw finding을 찾습니다.
- 파일명을 지정해서 stage합니다.
git add -A와git add .는 피합니다. - 실제 증거 자료는
private/또는 저장소 밖에 둡니다.
세부 기준은 공개 저장소 안전 정책에 있습니다.
- 로컬 저장소와 workspace 흐름을 먼저 안정화합니다.
- 확장 adapter는 core pipeline을 재사용하는 방식으로만 추가합니다.