TrendShift 딥다이브 · 2026-07-01

Deepsec 딥다이브
— 코딩 에이전트에게 "네 회사 전 코드베이스를 감사해봐"라고 시키는 도구

deepsec은 정규식 하나로 끝나는 스캐너가 아니다. 약 200개의 가벼운 정규식 매처(matcher)로 "의심스러운 위치"를 빠르게 골라내고, 그 자리마다 Claude Opus·GPT-5.5 같은 진짜 코딩 에이전트를 보내 "이게 정말 뚫리는 취약점인가"를 판단하게 하는 2단계 파이프라인이다. 큰 레포는 파일 수천 개를 Vercel Sandbox (마이크로VM 기반 격리 실행 환경)로 병렬로 쪼개 돌리고, 결과는 재검증 단계를 거쳐 오탐(false positive)을 절반 이상 걸러낸다. TypeScript pnpm 모노레포 · Claude Agent SDK / Codex SDK / Pi 3중 에이전트 백엔드 · Apache-2.0 위에서 동작한다. (저장소: vercel-labs/deepsec · TypeScript · ★4,936 · Apache-2.0)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 저장소가 대체 무엇인가.

핵심 메시지

"정규식은 '어디를 볼지' 고르는 미끼일 뿐, 실제 판단은 코딩 에이전트가 코드를 직접 읽고 내린다."

전통적인 정적분석 도구(SAST)는 규칙 하나가 파일 하나를 보고 "위험/안전"을 기계적으로 판정한다. deepsec은 반대다 — 정규식 매처는 그저 "이 근처를 봐야 할 것 같다"는 후보지(candidate)를 뽑아낼 뿐이고, 실제 "이게 진짜 취약점인가"는 사람 대신 Claude Opus나 GPT-5.5 같은 추론형 코딩 에이전트가 그 파일을 읽고, 주변 코드를 따라가고, "공격자가 이 입력을 통제할 수 있는가"를 판단한다.

비유하면: 정규식 매처 = 순찰 도는 경비원이 손전등으로 수상한 골목을 가리키는 것, 코딩 에이전트 = 그 골목에 실제로 들어가 문이 잠겼는지 손으로 확인하는 형사. 경비원은 빠르지만 오탐이 많고, 형사는 느리고 비싸지만 정확하다. deepsec은 이 둘을 파이프라인으로 엮었다.

README의 자기소개는 "a security harness for finding vulnerabilities in your codebase powered by coding agents" — 직역하면 "코딩 에이전트로 구동되는, 코드베이스 취약점을 찾는 보안 하니스(security harness)"다. 보안 하니스 (security harness)란 취약점 탐지 로직 자체가 아니라, "탐지 도구(여기선 AI 에이전트)를 대량의 코드에 체계적으로 투입하는 실행 골격"을 뜻한다 — 사람이 등산할 때 매는 안전벨트(harness)처럼, 에이전트가 코드베이스 구석구석을 안전하고 재현 가능하게 훑도록 잡아주는 틀이다.

README는 비용도 숨기지 않는다: "최고 성능 모델을 최대 사고 수준(maximum thinking levels)으로 쓰도록 설정되어 있어, 대형 코드베이스 스캔은 수천~수만 달러가 들 수 있다"고 명시한다. 싸구려 도구가 아니라 "정말 중요한 레포를 한 번 제대로 훑는" 용도다. 중단되면 이어서 재개하고, 이미 분석한 파일은 건너뛴다.

용어
SAST (Static Application Security Testing, 정적 애플리케이션 보안 테스트)
코드를 실행하지 않고 소스코드 자체를 분석해 취약점을 찾는 기법. Snyk Code, Semgrep, CodeQL 같은 도구가 대표적이다. 보통 "규칙(rule) 하나 = 취약점 패턴 하나"로 매칭하며, 규칙에 없는 새로운 형태의 논리적 결함은 놓치기 쉽다. deepsec은 SAST의 앞단(패턴 매칭)만 정적분석으로 하고, 실제 판단은 AI 에이전트에게 넘긴다는 점에서 "AI 강화 SAST"에 가깝다.

2왜 주목받는가

트렌딩 이유 · 기존 SAST/DAST 스캐너 대비 장점.

2026년 상반기 "AI 에이전트가 코드를 감사한다"는 아이디어 자체는 새롭지 않다. 하지만 deepsec이 주목받는 이유는 Vercel이 자기 프로덕션 코드에 실제로 돌리고 있는 도구를 그대로 오픈소스로 공개했다는 점, 그리고 "싸고 빠른 정적분석" 대신 "비싸도 되니 정확한 것"을 정면으로 선택했다는 포지셔닝이다. 처음부터 "이거 비쌉니다, 그래도 오래 숨어있던 버그를 잡는 게 그만한 가치가 있다"고 못박는다.

기존 방식과 무엇이 다른가

비교 대상기존 SAST(Semgrep/CodeQL/Snyk 류)deepsec의 접근
판정 주체정적 규칙 엔진이 최종 판정규칙은 후보만 고르고, AI 에이전트가 코드를 읽고 최종 판정
오탐(FP) 처리규칙을 더 촘촘히 짜서 줄임(한계 있음)2차 revalidate 단계가 git 히스토리까지 보고 재검증
새로운 취약점 유형규칙 작성자가 미리 정의해야 탐지매처가 못 잡아도 AI가 "열린 눈"으로 자유롭게 탐색
대규모 코드베이스단일 프로세스로 전체를 훑음Vercel Sandbox 마이크로VM으로 워커를 병렬 분산
비용 모델보통 정액 SaaS 요금토큰 사용량 기반 — 대형 레포는 수천 달러
기존 SAST의 한계
규칙에 없으면 못 찾는다, 있어도 오탐이 많다

전통 SAST는 "SQL 문자열에 변수가 섞이면 SQL 인젝션"처럼 정해진 패턴만 본다. 그 패턴에 딱 맞지 않는 논리적 인증 우회(예: 파라미터 중복으로 검사를 우회하는 경우)는 애초에 규칙이 없으면 영원히 못 찾는다. 반대로 패턴에는 맞지만 실제로는 안전한 코드(파라미터화된 쿼리를 문자열처럼 보이게 짠 경우 등)는 오탐으로 쏟아진다.

deepsec의 해결
규칙은 미끼로만 쓰고, 판단은 추론 능력이 있는 에이전트에게

매처는 "여기 수상하다"는 후보지 목록만 만든다. 실제 판정은 코드를 읽고, 미티게이션(완화 조치)이 있는지 확인하고, 공격자 관점에서 이 입력이 통제 가능한지 추론할 수 있는 AI 에이전트가 한다. 게다가 매처에 안 걸린 파일도 AI가 "전체적으로" 훑을 수 있어, 규칙 밖의 취약점도 잡을 여지가 있다.

이런 상황을 상상해봐

신입 보안 담당자에게 "이 코드에 SQL 인젝션 있으면 표시해"라고만 시키면, + 연산자로 SQL을 이어붙인 코드는 다 표시하겠지만 실제로 파라미터 바인딩이 되어 있어 안전한 경우까지 다 걸릴 것이다. deepsec은 대신 "여기 SQL을 문자열로 조립하는 곳이 있다, 가서 진짜 위험한지 코드를 직접 읽고 판단해와"라고 경력 많은 시니어를 보내는 셈이다.

3기술 스택 전체 지도

모노레포 4개 패키지 + AI 에이전트 3종 + 분산 실행 인프라.

레이어기술 / 버전역할
언어/런타임TypeScript (ESM) · Node.js 22+전체 코드베이스가 TS. 파일 6종 언어 비중 중 TS가 99% 이상
패키지 관리pnpm 8.15.9 워크스페이스packages/* 4개 패키지를 하나의 모노레포로 관리
CLI 프레임워크commanderdeepsec scan/process/revalidate/... 서브커맨드 파싱
스키마 검증zod@deepsec/core의 FileRecord·Finding 등 런타임 타입 검증
AI 에이전트 SDK 1@anthropic-ai/claude-agent-sdkClaude(기본 claude-opus-4-8)를 코딩 에이전트로 구동
AI 에이전트 SDK 2@openai/codex-sdkOpenAI Codex(기본 gpt-5.5)를 읽기 전용 샌드박스로 구동
AI 에이전트 SDK 3@earendil-works/pi-coding-agentPi 에이전트(기본 zai/glm-5.2) — Gateway로 다른 provider도 연결 가능
분산 실행@vercel/sandbox + @vercel/oidc대형 레포를 마이크로VM 여러 대로 쪼개 병렬 처리
파일 탐색glob · minimatch매처 대상 파일을 프로젝트 루트에서 훑어 수집
번들러esbuild + dts-bundle-generator배포용 dist/cli.mjs 단일 번들 생성
설정 로더jitideepsec.config.ts를 별도 빌드 없이 즉석 로드
린트/포맷Biome · knip코드 스타일 통일 + 죽은 코드 탐지
테스트vitest (workspace 프로젝트별 분리)core/scanner/processor/cli/e2e 프로젝트를 개별 실행
JSON 복구jsonrepairAI 응답이 살짝 깨진 JSON이어도 파싱 실패 없이 복구
용어
에이전틱 AI (Agentic AI)
단순히 프롬프트에 답만 하는 게 아니라, 파일을 읽고(Read/Grep 도구), 코드를 탐색하고, 여러 단계를 스스로 계획해 실행하는 AI를 말한다. deepsec의 process 단계는 챗봇에게 코드 스니펫만 던져 물어보는 게 아니라, Claude Agent SDK가 실제로 파일시스템에 접근해 관련 파일을 스스로 더 찾아 읽는 "에이전트 루프"를 돈다.

4아키텍처 심화 분석

"싸게 넓게 훑고, 비싸게 깊게 판다" — 5단계 파이프라인.

deepsec의 뼈대는 docs/architecture.md가 명시한 5단계 파이프라인이다. 각 단계는 독립된 CLI 서브커맨드이고, 모두 같은 온디스크 저장소(data/<projectId>/)를 읽고 쓴다. 핵심 설계는 "각 단계가 이전 결과를 덮어쓰지 않고 추가한다"는 것 — 재실행해도 안전하고, 중단됐다 재개해도 중복 작업이 없다.

┌──────────┐ ┌──────────┐ ┌────────────┐ ┌──────────┐ ┌──────────┐ │ scan │─▶│ process │─▶│ revalidate │─▶│ enrich │─▶│ export │ │ (무료) │ │ ($$$) │ │ ($$) │ │ (무료) │ │ (무료) │ └──────────┘ └──────────┘ └────────────┘ └──────────┘ └──────────┘ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ 후보(candidate) 발견 → AI 조사·판정 → TP/FP/Fixed 재검증 → 커밋 정보 추가 → MD/JSON 출력

① scan — 정규식 200개로 "볼 만한 곳" 고르기 (무료)

packages/scanner/src/matchers/ 아래 198개의 매처(matcher) 파일이 프로젝트 루트를 훑는다. 각 매처는 SQL 인젝션, 인증 우회, XSS 같은 카테고리 하나를 담당하고, 여러 개의 정규식 + 프레임워크별 게이트(예: Express 라우트인지 package.json으로 먼저 확인)로 후보를 찾는다. 이 단계는 AI 호출이 전혀 없어 무료고, 2천 파일 레포도 ~15초면 끝난다.

// packages/scanner/src/matchers/sql-injection.ts (일부)
export const sqlInjectionMatcher: MatcherPlugin = {
  noiseTier: "precise",               // precise/normal/noisy 3단계 — 우선순위에 반영
  slug: "sql-injection",
  filePatterns: ["**/*.{ts,tsx,js,jsx}"],
  match(content, _filePath) {
    return regexMatcher("sql-injection", [
      { regex: /`\s*SELECT\s+[^`]{0,400}\$\{/,
        label: "template literal SELECT with interpolation" },
      { regex: /['"]SELECT\s+[^'"]{0,400}['"]\s*\+/,
        label: "string concat SELECT" },
      // ... LIKE/RLIKE/INSERT/UPDATE/DELETE 변형까지 총 15개 패턴
    ], content);
  },
};

매처마다 noiseTier(precise/normal/noisy)가 있어, 나중에 배치 순서를 정할 때 "더 확실한 패턴"부터 AI에게 넘긴다. 매처는 examples 필드로 자체 테스트 예시까지 갖고 있어(packages/scanner/src/__tests__/matcher-examples.test.ts), 새 매처를 추가해도 회귀 테스트가 자동으로 붙는다.

② process — AI 에이전트가 실제로 코드를 읽고 판정 (가장 비싼 단계)

후보 파일들은 디렉토리 기준으로 5개씩 묶여(batch) AI에게 전달된다(packages/processor/src/batch.ts) — 같은 폴더 파일은 서로 관련이 깊어서 묶어 보내면 문맥을 공유할 수 있다는 논리다. 프롬프트는 고정 템플릿이 아니라 코어 프롬프트 + 감지된 기술스택 하이라이트 + 이 배치에 걸린 슬러그별 메모를 그때그때 조립한다(packages/processor/src/prompt/assemble.ts).

설계 패턴
동적 프롬프트 조립 (Prompt Assembly)
모든 배치에 똑같은 거대 프롬프트를 보내는 대신, 이 프로젝트가 Next.js인지 Django인지(detectTech())와 이 배치에 어떤 취약점 슬러그가 걸렸는지를 보고 필요한 섹션만 조립해서 보낸다. Next.js 전용 위협 하이라이트는 Python 배치엔 안 붙는다 — 프롬프트가 쓸데없이 커져 모델의 집중력이 흩어지는 걸 막는 설계다. 프레임워크 섹션이 예산(문자 6000자)을 넘으면 "이 레포는 N개 프레임워크를 씁니다" 한 줄 요약으로 강등한다.

실제로 AI에게 전달되는 핵심 지시(packages/processor/src/prompt/core.ts)는 역할 부여부터 시작한다: "You are a world-class security researcher... You think like an attacker". 그다음 심각도 분류표(CRITICAL/HIGH/MEDIUM + HIGH_BUG/BUG), 알려진 취약점 슬러그 목록, 그리고 결정적으로 "정적 분석만 하라 — 절대 취약점을 재현·실행·공격하지 마라"는 명시적 금지 조항이 들어간다.

흐름 한 줄기 끝까지 따라가기 — "SQL 인젝션 후보 하나가 리포트로 나오기까지"

단계별로 실제 데이터가 어떻게 바뀌는지 추적해보자.

① scan src/api/users.ts 안에서 정규식이 매치 → `const q = "SELECT * FROM users WHERE id=" + id;` 발견 → candidates: [{ vulnSlug: "sql-injection", lineNumbers: [12] }] → status: "pending" 으로 FileRecord 저장 ② process (batch에 담겨 Claude Opus에게 전달) AI가 파일을 열어 앞뒤 문맥까지 읽음 → id가 req.query에서 바로 왔고 파라미터 바인딩 없음 확인 → findings: [{ severity: "CRITICAL", vulnSlug: "sql-injection", title: "Unsanitized user input in SQL query", confidence: "high" }] → status: "analyzed" ③ revalidate (재검증, 선택이지만 권장) 같은 AI가 다시 코드 + git blame을 확인 → 최근 커밋에서 고쳐지지 않았음을 확인 → revalidation: { verdict: "true-positive", reasoning: "..." } ④ enrich → gitInfo.recentCommitters: [{ name: "...", email: "..." }] 추가 ⑤ export --format md-dir → findings/CRITICAL/sql-injection-users-ts.md 파일로 출력

③ revalidate — 다시 읽고 진짜인지 재확인

process가 낸 판정을 같은(또는 다른) AI 에이전트가 한 번 더 검토한다. 이번엔 코드만이 아니라 git 히스토리까지 참고해 "이미 고쳐졌는지(fixed)"까지 확인한다. 결과는 true-positive / false-positive / fixed / uncertain 넷 중 하나. 문서에 따르면 이 단계 하나로 오탐률이 50% 이상 줄어든다. HIGH 이상 심각도에는 반드시 돌리길 권장한다.

④ AI 백엔드 3종 — 같은 계약, 다른 실행기

packages/processor/src/agents/ 아래 Claude·Codex·Pi 세 플러그인이 같은 인터페이스(AgentPlugin)를 구현한다. 셋 다 같은 프롬프트, 같은 JSON 출력 스키마를 쓰지만 실행 방식이 다르다 — Claude는 Claude Agent SDK로 로컬 OS 샌드박스(bubblewrap/Seatbelt)까지 씌우고, Codex는 처음부터 읽기 전용 샌드박스에서 grep 위주로 빠르게 돈다. findings는 에이전트 간에 자동으로 중복 제거(dedupe)되므로, Claude로 한 번 돌리고 Codex로 다시 돌려 "두 번째 의견"을 받는 것도 안전하다.

// packages/processor/src/agents/claude-agent-sdk.ts — 환경변수 화이트리스트
const CLAUDE_ENV_ALLOWLIST = new Set([
  "PATH", "HOME", "USER", "SHELL", "TERM", "TZ", "LANG", ...
]);
// 프롬프트 인젝션 방어: 레포 안의 악성 콘텐츠가 에이전트에게
// "환경변수 다 출력해"라고 시켜도 GITHUB_TOKEN, AWS_* 는 애초에
// 자식 프로세스 환경에 없어서 유출이 불가능하다.

⑤ 대규모 분산 — Vercel Sandbox로 워커 병렬화

파일 수천 개짜리 모노레포는 로컬 한 대로 오래 걸린다. pnpm deepsec sandbox process --sandboxes 10는 작업 트리를 tar로 묶어 업로드하고(.git은 제외), Vercel Sandbox 마이크로VM 10대에 파일 목록을 분할(partition)해 각자 process를 돌린 뒤 결과를 병합(merge-records)한다. 마이크로VM (microVM)이란 일반 가상머신보다 훨씬 가볍고 빠르게 뜨는 격리 실행 단위로, 워커마다 독립된 샌드박스를 통째로 새로 만드는 셈이라 한 워커가 이상해져도 다른 워커에 영향이 없다.

설계 패턴
파일 단위 원자적 락 (Atomic Per-File Locking)
여러 워커/러너가 동시에 같은 프로젝트를 process할 수 있는 이유. FileRecord에 lockedByRunId를 원자적으로 세팅해 "내가 지금 이 파일 조사 중"을 표시하고, 그 run이 죽었는지는 ① RunMeta phase ② 같은 호스트면 PID 생존 여부 ③ 락 나이(1시간 초과)로 판단해 되찾는다(reclaim). 두 프로세스가 같은 파일을 동시에 건드려 덮어쓰는 경쟁 상태(race condition)를 막는 실전적인 락 설계다.

5디렉토리 구조 해부

4개 패키지 모노레포 + 스캔당한 코드가 저장되는 곳.

deepsec/ ├── packages/ │ ├── core/ # 타입·스키마·설정 로더·플러그인 계약 │ │ └── src/{types,schemas,plugin,config,paths,run}.ts │ ├── scanner/ # 정규식 매처 198개 + 스캔 엔진 │ │ └── src/matchers/*.ts (sql-injection, auth-bypass, ssrf, ...) │ ├── processor/ # AI 조사 로직 — 이 레포의 두뇌 │ │ └── src/ │ │ ├── agents/ # claude-agent-sdk / codex-sdk / pi-sdk 3종 │ │ ├── prompt/ # core.ts(코어 프롬프트) + assemble.ts(조립) │ │ ├── batch.ts # 후보 파일을 5개씩 배치로 묶음 │ │ ├── triage.ts # P0/P1/P2 저비용 분류 │ │ └── enrich.ts # git 커미터 정보 부착 │ └── deepsec/ # 배포되는 CLI 패키지 (npm: deepsec) │ └── src/ │ ├── cli.ts # commander 진입점, 서브커맨드 등록 │ ├── commands/ # scan/process/revalidate/export/... 각 1파일 │ └── sandbox/ # Vercel Sandbox 업로드·분할·병합·다운로드 │ ├── fixtures/vulnerable-app/ # 일부러 취약하게 만든 테스트용 미니 앱 ├── samples/webapp/ # deepsec.config.ts 작성 예시(플러그인·매처 포함) ├── docs/ # architecture/models/data-layout/faq 등 9개 문서 ├── e2e/ # 엔드투엔드 테스트 (LIVE_AGENT=1이면 실제 AI 호출) ├── .github/workflows/ # ci.yml, deepsec.yml(PR마다 자체 스캔!), release.yml └── (사용자 레포 안에 설치되면) .deepsec/ ├── deepsec.config.ts # projects[] 등록, 플러그인 연결 └── data/<projectId>/ ├── INFO.md # 프로젝트 맥락 — AI 프롬프트에 매번 주입 ├── files/**/*.json # FileRecord — 파일당 발견물 누적 └── runs/*.json # 실행 기록 (RunMeta)
파일/폴더역할
packages/scanner/src/matchers/핵심 — 198개 정규식 매처. 새 취약점 유형을 추가하려면 여기.
packages/processor/src/prompt/core.tsAI에게 보내는 시스템 프롬프트의 뼈대. 심각도 기준·금지 조항이 여기 있다.
packages/processor/src/agents/*-sdk.tsClaude/Codex/Pi 세 백엔드가 각각 어떻게 에이전트를 구동하는지.
packages/deepsec/SKILL.md코딩 에이전트(사용자 쪽)에게 "이 도구 문서는 여기 있다"고 알려주는 스킬 파일.
fixtures/vulnerable-app/테스트 픽스처 — 일부러 SQLi·경로 순회·인증 우회를 심어 매처 회귀 테스트에 씀.
.github/workflows/deepsec.ymldeepsec이 자기 자신의 PR을 deepsec으로 스캔하는 이터레이션(dogfooding) 워크플로.
주의 — fixtures는 공격 코드가 아니라 방어용 테스트 자료
일부러 취약하게 만든 샘플, 실제로 배포되지 않음

fixtures/vulnerable-app/은 매처가 실제 취약 패턴을 놓치지 않는지 검증하는 테스트 픽스처다. 파일 맨 위에 // VULN: auth-bypass — Auth check with flawed logic처럼 주석으로 어떤 취약점을 흉내 낸 것인지 명시해 두었고, 실행되거나 배포되는 코드가 아니라 packages/scanner/src/__tests__/의 자동 테스트가 참조하는 정적 예시일 뿐이다.

6학습 포인트 (기술별)

이 저장소 하나로 배울 수 있는 것 + 실습 아이디어.

6-1. 정규식 매처 설계 — "노이즈 등급"이라는 아이디어

198개 매처 각각이 noiseTier: "precise" | "normal" | "noisy"를 선언한다. SQL 인젝션처럼 패턴이 명확한 건 precise, "인증 관련 코드 전반"처럼 넓게 잡는 auth-bypassnormal이다. 이 값이 나중에 noiseScore()로 배치 우선순위를 정하는 데 쓰인다 — 확실한 후보부터 AI에게 먼저 보내는 전략이다.

실습 아이디어

packages/scanner/src/matchers/sql-injection.ts를 열어 정규식 15개를 하나씩 읽고, 각각을 통과/실패시키는 짧은 코드 샘플을 직접 만들어 regex.test()로 확인해보자. 그다음 자신만의 매처(예: "console.log에 비밀번호 변수가 찍히는 패턴")를 하나 추가하고 matcher-examples.test.ts 형식으로 예시를 붙여본다.

6-2. AI 프롬프트를 코드처럼 조립하기

assemblePrompt()는 프롬프트 엔지니어링을 "긴 문자열 하나"가 아니라 코어 + 조건부 하이라이트 + 조건부 슬러그 메모로 나눠 조립 가능한 구조로 짰다. 토큰 예산(문자 6000자, 대략 1500토큰)을 넘으면 자동으로 요약본으로 강등하는 로직까지 있다 — "프롬프트가 길어질수록 모델이 산만해진다"는 실전 교훈이 코드에 그대로 녹아 있다.

// packages/processor/src/prompt/assemble.ts (개념 요약)
const sections = [CORE_PROMPT];
if (frameworkSection.length <= 6000) sections.push(frameworkSection);
else sections.push(oneLineFallback);      // 폴리글랏 레포는 요약으로 강등
sections.push(slugSpecificNotes);          // 이 배치에 걸린 슬러그만
sections.push(projectInfoMd);              // INFO.md 원문 그대로 첨부
실습 아이디어

가상의 "프레임워크 하이라이트" 2~3개를 문자열 배열로 만들고, 총 길이가 예산을 넘으면 요약 문장으로 바꾸는 미니 함수를 직접 구현해보자. LLM 프롬프트를 "설정에 따라 동적으로 조립하는 템플릿"으로 다루는 감각을 익힐 수 있다.

6-3. 심각도 분류 체계 설계하기

CORE_PROMPT는 CRITICAL/HIGH/MEDIUM이라는 흔한 3단계에, 보안이 아닌 버그를 위한 HIGH_BUG/BUG 두 단계를 더했다. "보안 취약점은 아니지만 데이터 유실·중단을 일으킬 수 있는 버그도 같이 보고하라"는 지시다. 매처 슬러그 하나하나가 표로 정의되어 있어, 새 카테고리를 추가하려면 이 표 + 매처 파일 한 개만 더하면 된다.

실습 아이디어

자신의 프로젝트에 맞는 심각도 표를 하나 설계해보자 — "이 프로젝트에서 CRITICAL은 무엇인가"를 3줄로 정의하는 연습만으로도 실무 보안 리뷰 감각이 는다.

6-4. 3개의 서로 다른 AI SDK를 같은 인터페이스로 감싸기

Claude Agent SDK, Codex SDK, Pi 코딩 에이전트는 API도, 실행 방식도, 응답 형식도 다르다. deepsec은 AgentPlugin 인터페이스(investigate(), revalidate() 두 메서드) 하나로 셋을 통일했다. 새 AI 제공자가 나오면 이 인터페이스만 구현하면 --agent 플래그에 바로 꽂힌다 — docs/models.md가 실제로 "미래의 Anthropic Mythos 같은 신모델도 문자열 하나 바꾸면 된다"고 설명한다.

실습 아이디어

packages/processor/src/agents/types.tsAgentPlugin 타입을 읽고, 가짜(mock) 응답만 리턴하는 미니 StubAgentPlugin을 만들어보자(테스트 코드의 stub-agent.ts가 실제 참고 예시다). "실제 AI 호출 없이 파이프라인 로직만 테스트하는" 패턴을 익힐 수 있다.

6-5. 프롬프트 인젝션 방어 — 환경변수 화이트리스트

코딩 에이전트에게 셸 실행 권한을 주는 도구는 필연적으로 위험하다. deepsec은 자식 프로세스(claude/codex CLI)에 process.env 전체를 넘기지 않고, PATH·HOME·TERM 같은 필수 변수 + 인증에 필요한 최소 크리덴셜만 골라 넘긴다. 레포 안에 악성 콘텐츠(프롬프트 인젝션)가 있어 에이전트가 "환경변수 다 출력해"라는 지시를 따르게 되더라도,애초에 GITHUB_TOKEN 같은 값이 그 프로세스 환경에 없어서 유출이 원천 차단된다.

실습 아이디어

Node.js의 child_process.spawn()에서 env 옵션을 화이트리스트로 제한해 자식 프로세스를 띄우는 미니 스크립트를 짜보자. console.log(process.env)를 자식 안에서 실행시켜 상위 프로세스의 비밀값이 실제로 보이지 않는지 확인.

7시스템 요구사항

로컬 실행 자체는 가볍다 — 진짜 비용은 AI API 토큰이다.

항목요구사항
런타임Node.js 22 이상 (엔진 명시), pnpm 권장(npm/yarn도 동작)
OSmacOS · Linux · Windows(정규식/파일탐색은 크로스플랫폼, windows-paths.test.ts로 검증)
AI 크리덴셜(필수)AI_GATEWAY_API_KEY(Vercel AI Gateway) 또는 ANTHROPIC_AUTH_TOKEN+ANTHROPIC_BASE_URL, 또는 로컬에 이미 로그인된 claude/codex 구독
대규모 분산(선택)Vercel 계정 + @vercel/sandbox — 로컬 동시성으로 부족할 때만 필요
하드웨어일반 개발 노트북으로 충분. 실제 추론은 클라우드 LLM에서 일어나 로컬 GPU 불필요
예산(핵심 요구사항)파일 100개 = $25~60, 500개 = $130~300, 2,000개 = $500~1,200 (Opus 기준, --limit으로 조절 가능)
정리하면

설치·실행 장벽은 낮다(Node + API 키 하나). 진짜 "요구사항"은 하드웨어가 아니라 예산이다 — README가 여러 번 강조하듯 이건 "빠르고 싼" 도구가 아니라 "느리지만 정확한" 도구로 설계됐다. 처음엔 반드시 --limit 50으로 소규모 파일에 먼저 돌려 비용을 가늠해보길 권장한다.

8직접 해볼 수 있는 실습 과제

난이도별 4단계. 반드시 본인 소유이거나 명시적으로 스캔을 허가받은 코드베이스에만 실행할 것.

실습 1

fixtures/vulnerable-app에 scan만 돌려보기 난이도 ★☆☆ 입문

레포를 클론해 pnpm install 후, pnpm deepsec scan --root ./fixtures/vulnerable-app --project-id demo를 실행(AI 호출 없어 무료). data/demo/files/**/*.json을 열어 candidates 배열에 어떤 vulnSlug가 몇 줄에서 잡혔는지 확인해보자. 목표: AI 호출 전 단계에서 "후보"가 어떻게 생겼는지 몸으로 익히기.

실습 2

정규식 매처 하나 직접 작성 난이도 ★★☆ 중급

packages/scanner/src/matchers/의 기존 매처 하나(예: secret-in-log.ts)를 참고해, "console.log에 password·apiKey 같은 변수명이 그대로 찍히는 패턴"을 잡는 매처를 새로 만들고 matchers/index.ts에 등록. vitest run --project scanner로 테스트가 통과하는지 확인. 목표: "노이즈 등급"과 정규식 설계를 직접 겪어보기.

실습 3

본인 소유 작은 레포에 process까지 소규모로 실행 난이도 ★★☆ 중급

본인이 만든 토이 프로젝트(또는 위 fixtures)에 AI_GATEWAY_API_KEY 하나만 발급받아 pnpm deepsec process --project-id demo --limit 5 --concurrency 1로 파일 5개만 실제 AI 조사를 시켜본다. 결과 findings[]severity·confidence·recommendation을 읽어보고, analysisHistory[].costUsd로 실제 얼마가 들었는지 확인. 목표: 정규식 판정과 AI 판정의 결이 어떻게 다른지 체감.

실습 4

revalidate로 오탐률 변화 측정 난이도 ★★★ 고급

실습 3의 결과에 이어 pnpm deepsec revalidate --project-id demo를 돌려, 각 finding에 revalidation.verdict가 어떻게 붙는지 비교. true-positivefalse-positive로 갈리는 이유(reasoning 필드)를 읽고, "AI가 왜 판정을 바꿨는지"를 직접 분석해 정리해보자. 목표: 2단계 검증 설계가 실제로 오탐을 줄이는 과정을 데이터로 확인.

실습 5

커스텀 AgentPlugin으로 스텁 백엔드 추가 난이도 ★★★ 고급

packages/processor/src/__tests__/stub-agent.ts를 참고해, 실제 AI 호출 없이 항상 고정된 findings를 리턴하는 AgentPlugin을 만들어 AgentRegistry에 등록하고 --agent stub으로 파이프라인 전체(scan→process→export)를 무료로 끝까지 돌려보자. 목표: "AI 조사"와 "파이프라인 오케스트레이션"이 어떻게 분리되어 있는지 아키텍처 차원에서 이해.

9관련 기술 심화 학습 로드맵

이 저장소를 출발점으로, 5주 코스.

주차주제학습 자료
1주차웹 취약점 기초 (OWASP Top 10)OWASP Top 10 공식 문서 · CORE_PROMPT의 심각도 분류표 정독 · 실습 1~2
2주차정규식·정적분석 설계packages/scanner/src/matchers/ 10개 정독 · Semgrep/CodeQL 룰 문법과 비교
3주차AI 에이전트 SDK (Claude Agent SDK)Anthropic 공식 Agent SDK 문서 · agents/claude-agent-sdk.ts 정독 · 실습 3
4주차프롬프트 엔지니어링 실전prompt/core.ts+assemble.ts 분석 · 자신의 도메인용 프롬프트 조립기 설계
5주차분산 실행 · 파이프라인 설계sandbox/ 디렉토리 · Vercel Sandbox 문서 · 원자적 락/재개 가능 파이프라인 패턴 정리

10핵심 키워드 사전

본문에 나온 용어 빠른 참조.

용어의미
Security Harness탐지 로직 자체가 아니라, 탐지 도구(여기선 AI)를 코드베이스 전체에 체계적으로 투입하는 실행 골격.
SASTStatic Application Security Testing. 코드를 실행하지 않고 소스만 분석해 취약점을 찾는 기법.
Matcher (매처)정규식 + 파일패턴으로 "취약점 후보"를 찾는 규칙 하나. deepsec엔 198개가 있다.
Noise Tier매처의 확신도 등급(precise/normal/noisy). AI 조사 우선순위에 반영된다.
Candidate (후보)매처가 찾은 "볼 만한 위치". 아직 AI가 확인하지 않은 상태.
FindingAI가 실제로 판정한 취약점. severity·title·recommendation·confidence를 포함.
FileRecord파일 하나의 candidates·findings·분석이력을 누적 저장하는 JSON 단위.
Revalidation (재검증)기존 finding을 다시 읽어 true-positive/false-positive/fixed로 재판정하는 단계.
에이전틱 AI (Agentic AI)파일을 읽고 도구를 써가며 스스로 여러 단계를 수행하는 AI. 단발성 챗봇 응답과 대비된다.
프롬프트 인젝션 (Prompt Injection)코드/문서 안에 숨긴 지시로 AI 에이전트를 조종하려는 공격. deepsec은 환경변수 화이트리스트 등으로 방어한다.
마이크로VM (microVM)일반 VM보다 훨씬 가볍고 빠르게 뜨는 격리 실행 단위. Vercel Sandbox의 기반 기술.
Atomic Locking (원자적 락)여러 워커가 동시에 같은 파일을 건드리지 않도록 파일 단위로 잠금을 거는 동시성 제어 기법.

11참고 링크