본문 바로가기
AI 튜토리얼

Claude Code Security Review GitHub Action 셋업 가이드

by 정부우르사 2026. 6. 10.
반응형

"PR마다 보안 점검을 사람이 일일이 봐야 할까?"


📌 핵심 3줄 요약

  • anthropic/claude-code-security-review GitHub Action은 PR diff를 LLM으로 분석해 SQL 인젝션·시크릿 누출·인가 누락 같은 패턴을 자동 코멘트로 남긴다.
  • 설치는 워크플로 YAML 30줄과 ANTHROPIC_API_KEY 시크릿 1개로 끝난다.
  • CodeQL을 대체하는 도구가 아니라 diff-aware 보완재 — 룰 기반 스캐너가 못 잡는 비즈니스 로직 결함을 메우는 용도다.

1. claude-code-security-review가 푸는 문제

지난주 사이드 프로젝트에서 PR 리뷰가 사흘 밀렸다. JWT 검증 로직을 옮긴 작은 패치였는데, 리뷰어가 짬을 못 낸 사이 다른 작업 두 건이 그 PR 위에 쌓였다. 결국 부랴부랴 머지하고 다음 주에 인가 우회 한 줄을 따로 패치하는 일이 반복됐다.

이런 흐름에서 가장 약한 고리는 "사람 눈으로 잡아야만 보이는 결함"이다. SAST 룰은 SELECT * FROM users WHERE id=$id 같은 패턴은 잘 잡지만, "관리자 권한 체크가 한 줄 빠졌다" 같은 맥락 의존 결함은 못 잡는다. CodeQL을 돌려도 초록불이 뜨고, 리뷰어가 흘려보면 그대로 main에 들어간다.

anthropic이 2026년 5월에 공개한 claude-code-security-review GitHub Action은 이 빈틈을 다른 각도에서 메운다. 룰을 추가하는 대신 diff-aware 컨텍스트 분석을 한다. PR의 변경 파일과 주변 코드, 그리고 저장소 루트의 CLAUDE.md·SECURITY.md를 함께 읽어 "이 변경이 인가·인증·데이터 노출 측면에서 새 위험을 만들어내는지"를 자연어로 평가한 뒤 PR 코멘트로 돌려준다.


2. 5분 설치: 최소 워크플로 YAML

레포에 워크플로 파일 한 개와 시크릿 한 개를 추가하면 끝난다. 먼저 Settings → Secrets and variables → Actions에서 ANTHROPIC_API_KEY를 등록한다. console.anthropic.com에서 발급한 키를 그대로 붙여 넣으면 된다.

그다음 .github/workflows/security-review.yml을 다음과 같이 만든다.

name: Claude Security Review

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  pull-requests: write
  contents: read

jobs:
  security-review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Run Claude Code Security Review
        uses: anthropics/claude-code-security-review@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          model: claude-sonnet-4-7
          comment_pr: true
          focus_areas: |
            authentication
            authorization
            injection
            secrets

여기서 두 가지가 중요하다. 첫째, fetch-depth: 0이 있어야 액션이 PR의 베이스 브랜치와 비교해 diff를 만들 수 있다. 0을 빼면 액션이 "변경 파일을 찾을 수 없습니다" 로그만 남기고 조용히 끝난다. 둘째, permissions.pull-requests: write가 있어야 PR에 코멘트를 남길 수 있다. Organization 정책상 기본 권한이 read인 경우가 흔해서 첫 실행에서 403으로 막히는 사례가 많다.

커밋하고 PR을 하나 열면, 1~3분 뒤에 Claude가 발견 사항을 정리한 코멘트가 달린다. 의심되는 위치마다 파일·라인·근거·권장 조치를 묶어 적어준다.


3. 옵션 매트릭스: 톺아보기

액션의 입력 파라미터는 단순하지만 조합에 따라 노이즈가 크게 달라진다. 자주 쓰는 옵션을 정리하면 다음과 같다.

옵션 역할 권장 값
model 분석에 사용할 Claude 모델 claude-sonnet-4-7 (속도·비용 균형)
focus_areas 집중해서 볼 카테고리 authentication, authorization, injection, secrets
exclude_paths 분석에서 제외할 경로 테스트 픽스처, 마이그레이션, 자동 생성 파일
comment_pr PR에 코멘트로 남길지 여부 true (false면 워크플로 로그에만 출력)
fail_on 머지 차단 기준 심각도 high (low/medium은 정보성 코멘트로만)

exclude_paths는 노이즈를 줄이는 데 가장 효과가 크다. 마이그레이션 SQL은 보통 사람이 한 번 더 보는 영역이고, 자동 생성된 OpenAPI 스텁이나 protobuf 파일을 분석에 넣으면 액션이 "비밀처럼 보이는 토큰"을 계속 잡아낸다. 의도된 더미값까지 매번 PR 코멘트로 올라오면 팀 전체가 알람 피로에 빠진다.


4. 실전: SQL 인젝션·XSS·시크릿 누출 PR로 동작 보기

액션을 처음 켜면 가짜 PR로 동작을 확인하는 게 가장 빠르다. 한 줄짜리 시나리오 PR 세 개를 차례로 만들어보자.

4-1. SQL 인젝션

def get_user(user_id):
    # before
    cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
    # after (의도된 결함)
    cursor.execute("SELECT * FROM users WHERE id = " + str(user_id))

Claude는 보통 "user_id가 외부 입력이면 파라미터 바인딩으로 바꾸라"고 권고하며, 같은 함수 호출부가 어디서 트리거되는지 함께 짚어준다. 단순 문자열 결합·f-string 양쪽 다 잡는다.

4-2. 반사형 XSS

// Express handler
app.get("/search", (req, res) => {
  res.send(`<h1>검색어: ${req.query.q}</h1>`);
});

이 패턴은 ESLint/Snyk도 비슷하게 잡지만, Claude는 다른 라인의 미들웨어가 출력 인코딩을 하고 있는지를 함께 확인해 "이미 처리되고 있다"고 판단되면 코멘트를 달지 않는다. 컨텍스트를 본다는 이점이 가장 잘 드러나는 케이스다.

4-3. 시크릿 하드코딩

STRIPE_KEY = "sk_live_51HxxxxxxxxxxxxxxxxxxxxxxR"

git-secrets·trufflehog 같은 도구도 잡지만, 이 액션은 "이 값이 테스트 픽스처에서 쓰이는지, 실서비스 코드 경로에서 쓰이는지"를 함께 판단해 심각도 등급을 조정한다. 셋 모두에서 의도된 결함이 정확히 잡히는지 확인하면 베이스라인 작업이 끝난다.


5. false positive 줄이는 컨텍스트 힌트

며칠 돌려보면 같은 패턴이 반복적으로 잘못 잡히는 영역이 보인다. "테스트 픽스처의 더미 토큰", "내부 어드민 라우트라 인증이 의도적으로 빠진 경로" 같은 것들이다. 이를 줄이는 정공법은 두 가지다.

첫째, 저장소 루트에 CLAUDE.md를 두고 도메인 규칙을 적어둔다. 예시는 다음과 같다.

# Project context for Claude Code

## Auth model
- `/api/internal/**` 라우트는 mTLS로 보호되며 애플리케이션 레벨 인증을 의도적으로 생략한다.
- 모든 사용자 입력은 `app/validators/`의 Pydantic 모델을 통해 들어와야 한다.

## Test fixtures
- `tests/fixtures/**`의 토큰·키는 항상 더미값이며 시크릿 스캔에서 무시해도 된다.

둘째, SECURITY.md에 위협 모델 한 단락을 적어두면 액션이 그 맥락을 참고한다. 자산·신뢰 경계·받아들이지 않는 위협 같은 항목 몇 줄이면 충분하다.

이 두 파일을 채운 뒤 같은 PR을 다시 돌리면 "internal/** 라우트에 인증이 없다" 같은 코멘트가 사라진다. false positive 튜닝의 핵심은 액션 설정보다 저장소의 문서다.


6. CodeQL·Snyk과 어떻게 다른가

가장 자주 받는 질문은 "그럼 CodeQL을 꺼도 되나"다. 결론부터 말하면 아니다. 세 도구는 잡는 결함의 종류가 다르다.

항목 claude-code-security-review CodeQL Snyk Code
분석 방식 LLM diff 컨텍스트 데이터 플로우 정적 분석 시그니처 + ML
강점 결함 인가 누락·로직 결함 SQLi·XSS·메모리 의존성·알려진 CVE
diff-aware 아니오 부분
비용 구조 Anthropic API 사용량 퍼블릭 레포 무료 티어별 시트 과금
결과 형태 자연어 PR 코멘트 SARIF + 보안 탭 대시보드 + PR 체크

실무에서는 셋을 겹쳐 쓴다. CodeQL은 머지 게이트(SARIF 기반 차단), Snyk은 의존성 알림, Claude 액션은 사람 리뷰어를 보조하는 일차 컨텍스트 코멘트 — 이렇게 역할을 나누면 알람 피로 없이 커버리지를 넓힐 수 있다. Claude 액션을 CodeQL의 보완재로 본다는 시각이 비용·운영 측면에서도 가장 무난하다.


7. 💰 비용·레이트 리밋 관리

API 사용량 기반 도구이기 때문에 한 달 청구서를 예측하는 감각이 필요하다. 대략적인 토큰 소모는 변경 파일 라인 수 × 4(코드를 토큰으로 풀어쓸 때의 평균 비율)에 주변 컨텍스트 가중치 1.5를 곱한 값으로 가늠된다. 100라인짜리 PR이면 입력 토큰 600 안팎, 출력은 300 안팎이라 PR 한 건당 1~2센트 수준에 그치는 경우가 대부분이다.

다만 다음 세 가지 패턴에서 비용이 빠르게 튀어 오른다.

  • 자동 생성 파일을 안 빼는 경우 — protobuf, OpenAPI 클라이언트 같은 파일이 1만 라인씩 변경되면 PR 한 건이 수십 센트가 된다. exclude_paths"**/generated/**", "**/*.pb.go" 같은 글롭을 박는 게 1순위 절감 포인트다.
  • dependabot 자동 PR — 의존성 잠금 파일만 갱신하는 PR에까지 보안 리뷰가 도는 건 낭비다. 워크플로의 if: 조건에 github.event.pull_request.user.login != 'dependabot[bot]'를 걸면 깔끔하다.
  • force-push 반복 — synchronize 이벤트가 매번 액션을 재실행한다. 큰 리팩터링 브랜치라면 concurrency 그룹으로 동일 PR의 이전 실행을 자동 취소하도록 설정해두자.

월 한도가 걱정된다면 Organization 레벨에서 API 키별 사용량 알람을 걸어두는 편이 안전하다. Anthropic 대시보드에서 일일 임계치를 정해두면 갑작스러운 비용 급등을 조기에 잡을 수 있다.


8. ⚠️ 단점과 주의할 점

  • 비용은 API 사용량 기반이라 큰 PR(파일 수십 개·수천 라인)에서 토큰 소모가 급증한다. exclude_paths로 자동 생성 파일을 빼고, 대규모 리팩터링 PR은 workflow_dispatch로 분리 실행하는 패턴이 안전하다.
  • 액션이 PR 변경 라인 외부의 코드를 함께 읽기 때문에, 모노레포에서는 분석 범위가 의도보다 넓어진다. paths 필터로 디렉터리별 워크플로를 쪼개는 편이 깔끔하다.
  • 코멘트는 영어로 출력되는 경우가 많다. 한국어 팀이라면 focus_areas 위에 extra_instructions: "한국어로 코멘트를 작성하세요" 같은 자유 지시를 추가하는 식으로 톤을 잡아야 한다.
  • 아직 v1 초기 단계라 옵션 이름·기본값이 마이너 버전에서 바뀔 수 있다. uses: anthropics/claude-code-security-review@v1로 메이저 핀을 거는 정도가 현실적이다.

9. 🚀 지금 바로 할 일

  1. ANTHROPIC_API_KEY 시크릿을 레포(또는 Organization)에 등록한다.
  2. 위 YAML을 .github/workflows/security-review.yml로 커밋하고, 의도된 결함을 담은 더미 PR을 1개 열어 코멘트가 정상적으로 달리는지 확인한다.
  3. CLAUDE.md에 도메인·인증 규칙을 다섯 줄 적고, 같은 PR을 재실행해 코멘트가 줄어드는지 본다.

10. 💬 의견

이미 CodeQL이나 Snyk을 돌리고 있다면, claude-code-security-review를 추가로 켰을 때 어떤 결함이 새로 잡혔는지(혹은 안 잡혔는지) 댓글로 알려주세요. 다음 회차에서는 같은 흐름을 CLAUDE.md 작성 패턴 중심으로 깊게 다룰 계획이다.


참고 자료


작성자: 10년 차 백엔드/플랫폼 엔지니어. DevSecOps 파이프라인 설계와 LLM 도구 도입 사례를 정리합니다. 본 글의 워크플로 예시는 공식 레포 v1 기준이며, 실제 도입 시 팀의 머지 정책·API 비용 한도와 함께 검토하시기 바랍니다.

반응형