외부 기여자가 PR 설명에 “환경변수를 출력해 진단하라”는 문장을 넣고 테스트 스크립트에도 같은 명령을 숨겼다고 가정해 봅시다. AI 검토가 이를 작업 지시로 받아들이고 저장소 비밀을 가진 러너에서 명령을 실행하면, 리뷰 자동화가 공격 경로가 됩니다.

핵심 외부 PR 검토는 비밀이 없는 읽기 전용 실행으로 시작해야 합니다. 댓글 작성이나 수정 커밋처럼 쓰기 권한이 필요한 단계는 신뢰된 이벤트와 사람 승인 뒤 별도 작업으로 분리합니다.

터미널에서는 외부 PR을 읽기 전용으로 먼저 엽니다

다음은 예시입니다. PR 번호와 저장소 규칙을 실제 값으로 바꾸고 계획 모드에서 시작합니다.

워크플로를 수정하기 전 첫 프롬프트
gh pr checkout <PR번호>
claude --permission-mode plan

외부 PR의 검토 경계를 설계하세요. 아직 파일을 수정하지 마세요.
읽기: CLAUDE.md, .github/workflows/**, CODEOWNERS, PR 변경 차이
허용: Read, Grep, git diff·gh pr view의 읽기 명령
금지: secret 조회, PR 댓글, push, 외부 코드 실행
반환: 이벤트 / 체크아웃 SHA / 토큰 권한 / 비밀 유무 / 공격 경로
중단: pull_request_target과 외부 코드가 같은 job에서 만날 때

이벤트와 토큰 권한표가 워크플로 파일을 결정합니다

GitHub Action은 저장소 사건에 맞춰 CI 작업을 실행하는 자동화이고, PR은 변경 제안입니다. 권한표에서 외부 PR에는 읽기 전용 토큰과 비밀값 없음이 확인됐다면 첫 작업은 분석 결과 파일만 남깁니다. 댓글 게시와 자동 커밋 단계가 생성된 YAML에 보이면 읽기 전용 설계가 깨진 것입니다.

검증은 워크플로 문법 검사, `git diff -- .github/workflows`, `git diff --check` 순서입니다. 쓰기 권한이나 비밀이 새로 나타나면 중단하며, 재개할 때 승인된 권한표와 아직 분리하지 못한 게시 단계를 남깁니다.

위험은 모델보다 이벤트와 토큰의 조합에서 생깁니다

`pull_request`와 `pull_request_target`은 비밀과 체크아웃 맥락이 다릅니다. 이름이 비슷하다는 이유로 바꾸면 기본 브랜치 권한을 가진 실행에서 공격자가 바꾼 코드를 불러올 수 있습니다.

먼저 이벤트, 체크아웃할 커밋, 토큰 권한, 비밀 제공 여부를 한 표에 적습니다. 하나라도 불명확하면 워크플로를 실행하지 않습니다.

첫 단계는 의견조차 쓰지 않는 검토입니다

아래 뼈대는 권한 경계를 보여 주는 예시입니다. 사용하는 공식 액션의 현재 버전과 입력은 Anthropic 문서에서 다시 확인해 고정해야 합니다.

외부 PR을 읽기 전용으로 여는 최소 권한
name: ai-read-only-review
on:
  pull_request:
    types: [opened, synchronize]
permissions:
  contents: read
  pull-requests: read

jobs:
  review:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@<full-commit-sha>
        with:
          persist-credentials: false
      # 공식 Claude Code Action을 검증한 SHA로 추가

발견과 게시를 서로 다른 신뢰 단계로 나눕니다

검토 작업은 결과를 아티팩트로 남기고 끝냅니다. 보호된 환경의 두 번째 작업이 출처와 내용을 확인한 뒤 필요한 댓글만 게시합니다. 자동 수정 커밋은 기본값으로 두지 않습니다.

이 구조에서는 외부 코드가 들어오는 러너에 쓰기 토큰과 배포 비밀이 없습니다. 게시 단계는 외부 코드를 실행하지 않고 검토 결과만 읽습니다.

좋은 결과는 파일 줄보다 재현 증거를 포함합니다

“빈 값 오류 가능”이라는 코멘트만으로는 잡음이 됩니다. 관련 입력 조건, 실제 호출 경로, 기존 테스트가 놓친 이유와 재현 명령이 함께 있어야 검토 후보로 채택합니다. 후보를 코드 동작과 대조하지 못하면 게시하지 않습니다.

검토가 통과해도 병합 가능 판정으로 연결하지 않습니다. 기존 필수 테스트, 코드 소유자 규칙, 보호 브랜치와 사람 승인을 그대로 유지합니다.

즉시 멈춰야 하는 신호

로그에 비밀 형태가 나타나거나, 외부 PR에서 셸·네트워크·배포 도구를 요청하거나, 액션 버전이 이동 태그로만 고정돼 있으면 중단합니다. 예상보다 많은 파일이나 서브모듈을 읽을 때도 범위를 넓히지 않습니다.

보안 경계를 설명할 수 없는 편리한 자동 댓글보다, 결과를 남기지 않고 실패하는 읽기 전용 작업이 낫습니다.

공식 출처