Community연구 & 데이터 분석github.com

vitwit/deploy-security-gate

서비스를 출시하고 운영할 때 준비 상태를 점검하는 보안 게이트입니다. 소스 코드, Git 히스토리, 프론트엔드/모바일 번들, Dockerfile, CI 워크플로, 코딩 에이전트 설정 등에서 노출된 API 키와 시크릿을 찾아내고, AI 게이트웨이/LLM, 결제 및 분석 연동을 검토하며, 단일 장애점을 식별하고, 고정된 체크리스트에 기반한 Go/No-Go 보고서를 생성합니다.

deploy-security-gate란 무엇인가요?

이 스킬은 배포 전에 반드시 수행해야 할 보안 게이트 검사를 자동화하고 체계화합니다. 세 단계로 진행됩니다: (1) 빠르고 결정론적인 스크립트 기반 스캔으로 다양한 패턴의 시크릿을 감지하고, (2) 감지된 각 연동(LLM, 결제, 분석 등)에 대한 코드 리뷰를 안내하는 참조 문서를 제공하며, (3) 리포지토리만으로 확인할 수 없는 항목(공급자 대시보드 설정, 로테이션 일정, 백업 테스트 등)을 수동으로 확인하도록 요구합니다. 스캐너는 다양한 시크릿 패턴을 지원하며, SARIF 형식으로 GitHub 코드 스캐닝과 통합할 수 있습니다. 스캔 결과를 확인하고 오탐을 처리한 후, Go/No-Go 또는 예외 허용 보고서를 생성합니다. 주로 Claude Code, Cursor, Codex와 같은 AI 코딩 에이전트 환경에서 사용되며, CI/CD 파이프라인에 통합하여 모든 PR에 대해 게이트를 실행할 것을 권장합니다.

지원 대상✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/vitwit/claude-plugins/tree/HEAD/deploy-security-gate/skills/deploy-security-gate

Installed? Explore more 연구 & 데이터 분석 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

배포 보안 게이트

이 스킬은 하나의 체크리스트를 강제합니다: 어떤 키도 노출되지 않고, 어떤 단일 장애도 제품을 중단시키지 않는다. 세 단계로 진행됩니다:

  1. scripts/scan.py를 사용한 자동 스캔 - 빠르고 결정론적이며 읽기 전용입니다.
  2. 각 감지된 연동에 대한 코드 리뷰, references/integrations.md에 따라 진행합니다.
  3. 리포지토리에서 볼 수 없는 모든 항목(공급자 대시보드, 키 로테이션, 백업, 장애 조치 훈련 등)에 대한 수동 게이트입니다. 이러한 항목은 references/checklist.md에서 제공됩니다.

스캔만으로는 통과할 수 없습니다. 체크리스트의 약 1/3을 다룹니다. 이 스킬의 가치는 세 단계를 모두 수행하고, 무엇이 확인되었고 무엇이 여전히 인간의 확인을 필요로 하는지 솔직하게 보고하는 데 있습니다.

워크플로

1. 범위 설정

무엇이 출시되는지 파악합니다:

  • 리포지토리 루트
  • 프론트엔드 또는 모바일 빌드 출력물(있는 경우)
  • 배포 대상(컨테이너, 서버리스, Kubernetes 등)
  • 첫 출시, 새로운 연동 추가, 또는 정기 유지보수인지 여부

사용자가 "Stripe 추가"와 같은 특정 변경 사항을 언급한 경우, 해당 변경 사항에 초점을 맞춰 리뷰합니다. 그래도 전체 스캔은 실행해야 합니다. 다른 곳에서의 유출도 출시를 막기 때문입니다.

2. 스캐너 실행

python3 <skill-dir>/scripts/scan.py <repo> --history
  • 각 빌드 번들(dist, .next/static, 압축 해제된 APK/IPA)에 대해 --build-dir <dir>을 추가합니다. 출시된 번들은 "공개" 키가 실제로는 비밀 키로 판명나는 곳입니다. 일반적인 빌드 디렉토리는 자동으로 감지됩니다. 번들이 없으면 먼저 앱을 빌드하세요.
  • --entropy는 알려진 패턴에 맞지 않는 커스텀 시크릿을 잡는 높은 엔트로피 패스를 추가합니다(낮은 심각도; 각각 보고하기 전에 확인).
  • --format json 또는 --format sarif는 기계가 읽을 수 있는 출력을 제공합니다. SARIF는 GitHub 코드 스캐닝에 업로드됩니다. --fail-on high|medium|low|never는 종료 코드를 제어하며, CI에서 유용합니다.
  • 확인된 오탐은 인라인 # security-gate: allow 주석 또는 리포지토리 루트에 있는 .security-gate-ignore 파일(README 참조)로 억제할 수 있습니다. 특정 발견을 억제하는 것이 --fail-on을 낮추는 것보다 선호됩니다.
  • 스캐너는 시크릿 값을 마스킹합니다. 작성하는 모든 것에서 이 상태를 유지하세요. 전체 키를 채팅, 파일, 커밋, PR 텍스트에 절대 표시하지 마세요. 이는 두 번째 유출을 만들기 때문입니다.

스캐너는 다음을 확인합니다:

  • 작업 트리, 빌드 출력물 및 Git 히스토리에서의 시크릿 패턴 (AWS, Anthropic, OpenAI, OpenRouter, Groq, xAI, Perplexity, Replicate, fal, Google API 키 및 OAuth 시크릿, Stripe 라이브 키 및 웹훅 시크릿, Razorpay, GitHub, GitLab, Slack 토큰 및 앱 토큰, GCP 서비스 계정, npm, PyPI, SendGrid, Hugging Face, DigitalOcean, New Relic, Shopify, Square, Databricks, Doppler, PlanetScale, Linear, Azure Storage 키, Mailgun, Telegram, Discord 웹훅, JWT, 개인 키, 비밀번호가 포함된 DB URL, 하드코딩된 *_SECRET / *_TOKEN / *_SERVICE_ROLE 할당 — 인용(JSON/MCP 설정 포함) 또는 비인용)
  • --entropy 사용 시, 알려진 형식과 일치하지 않는 높은 엔트로피 문자열(커스텀 또는 새로운 시크릿)
  • 커밋된 .env 파일 및 누락된 .gitignore 항목
  • 클라이언트 노출 접두사(NEXT_PUBLIC_, VITE_, REACT_APP_, EXPO_PUBLIC_ 등) 뒤에 있는 시크릿처럼 보이는 변수, 그리고 클라이언트 코드에서의 직접적인 LLM 호출
  • 빌드 출력물의 소스 맵
  • GitHub Actions 워크플로: 태그로 고정된 액션, pull_request_target, 누락된 permissions: 블록, 에코된 시크릿, 파일이나 $GITHUB_ENV / $GITHUB_OUTPUT에 기록된 시크릿, OIDC 대신 정적 클라우드 키, 수명 주기 스크립트를 실행하는 설치
  • Dockerfile: ARG/ENV의 시크릿, 복사된 .env 파일, root로 실행
  • 서명 검증이 없는 결제 웹훅 핸들러
  • .env 파일에 대한 코딩 에이전트 읽기 접근
  • 사용 중인 연동, 그리고 AI 및 결제에 대한 단일 공급자(단일 장애점) 힌트

3. 발견 사항 분류

스캐너는 패턴 매칭으로 작동하므로, 보고하기 전에 코드를 읽어 각 발견 사항을 확인하세요.

  • 라이브 시크릿 발견됨 (트리, 히스토리 또는 번들 내): 리포지토리가 비공개여도 유출된 것으로 처리합니다. references/leaked-key-runbook.md를 따르세요. 여기서는 키 폐기가 먼저이고 정리는 나중입니다. 키를 폐기하거나 순환시키는 것은 프로덕션을 변경하므로, 사용자에게 정확히 어떤 키인지, 어디서 발견되었는지, 폐기 단계를 알려주세요. 사용자가 직접 수행하도록 하거나, 직접 수행하기 전에 확인을 받으세요.
  • 오탐 (테스트 픽스처, 문서화된 공개 키): 왜 안전한지 설명하고 넘어갑니다.
  • 휴리스틱 발견 사항 (웹훅 검증, 클라이언트 측 LLM 호출): 파일을 열고 실제 제어 흐름을 확인하세요. 검증이 다른 곳의 미들웨어에 있을 수 있습니다.

4. 각 감지된 연동 검토

스캐너가 나열했거나 코드에서 찾은 모든 연동에 대해 references/integrations.md의 해당 섹션을 읽고 코드를 확인하세요. 이 단계는 패턴이 잡을 수 없는 다음을 잡습니다:

  • 오픈 릴레이인 백엔드 프록시
  • 요청 본문에서 가져온 모델 이름
  • 클라이언트에서 계산된 금액
  • 관리자 자격 증명으로 실행되는 도구 호출
  • 분석으로 전송된 PII
  • 테넌트 필터가 없는 RAG 쿼리
  • 간접 프롬프트 인젝션: 모델이 읽는 문서, 웹 페이지, 트랜스크립트, 도구 결과가 지침으로 처리되는 경우 (체크리스트 3.17)
  • 유형/크기/아카이브 검사나 샌드박스 없이 파싱된 파일 업로드 (3.18)
  • SSRF: 모델이나 도구가 개인 또는 메타데이터 주소를 차단하지 않고 가져오는 *_url (3.19)

웹훅, 클라이언트-LLM 및 시크릿 검사는 휴리스틱입니다. 스캐너는 후보를 플래그하지만 수동으로 작성된 제어나 비표준 레이아웃을 놓칠 수 있습니다. createHmac + timingSafeEqual로 검증된 웹훅이나 우연히 src/ 아래에 있는 백엔드는 도구가 플래그하거나 놓치더라도 괜찮습니다. 항상 코드를 읽어 확인하세요.

5. 단일 장애점 확인

체크리스트 섹션 10을 사용하고 코드와 IaC에서 다음을 찾습니다:

  • 폴백이 없는 하나의 LLM 공급자
  • 타임아웃이나 재시도가 없는 벤더에 대한 HTTP 클라이언트
  • 분석이 다운되었을 때 요청 경로를 차단하는 벤더 호출
  • 단일 리전 또는 단일 영역 데이터베이스
  • 캐시가 없는 시크릿 가져오기
  • 사용자가 알려준 대로 루트 또는 소유자 접근 권한을 단독으로 가진 한 사람

6. 수동 게이트

많은 체크리스트 항목은 리포지토리에서 확인할 수 없습니다. 예를 들어:

  • 공급자 대시보드의 지출 한도
  • 키 순환 일정
  • 벤더 계정의 SSO 및 MFA
  • 백업 복원 테스트
  • 장애 조치 훈련
  • DPA (데이터 처리 계약)
  • 결제 페이지의 PCI 스크립트 인벤토리

이러한 항목을 확인 필요로 나열하고, 각각에 대해 소유자를 위한 한 줄 질문을 작성하세요. 가정에 기반하여 통과된 것으로 표시하지 마세요. 확인되지 않은 항목을 조용히 통과시키는 게이트는 게이트가 없는 것보다 나쁩니다.

7. 보고서

이 구조를 사용하여 결과를 릴리스 간에 비교 가능하게 만드세요:

# 보안 게이트: <제품 / 변경 사항> — <GO | NO-GO | GO WITH EXCEPTIONS>

## 차단 항목 (배포 전 수정 필수)
- [체크리스트 ID] 파일:줄 — 문제 — 수정 방법

## 수정 권장 (이번 스프린트 내)
- ...

## 검토된 연동
| 연동 | 서버 측 전용 | 범위 키 + 지출 한도 | 웹훅/출력 검증됨 | 폴백 | 참고 |

## 확인 필요 (수동)
- [ ] <소유자를 위한 질문> (체크리스트 §n)

## 통과됨 (확인됨)
- <항목> — 확인 방법

판정 규칙:

  • NO-GO: 확인된 HIGH 심각도 발견 사항이 하나라도 있는 경우. 여기에는 라이브 시크릿, 클라이언트에 노출된 시크릿 키, 검증되지 않은 결제 웹훅, CI 로그의 시크릿이 포함됩니다.
  • GO WITH EXCEPTIONS: MEDIUM 또는 LOW 발견 사항만 남아 있고, 사용자가 소유자와 날짜를 지정하여 이를 수락한 경우.
  • GO: 열린 항목이 없고, 모든 수동 항목이 확인된 경우.

문제 수정

사용자가 발견 사항을 수정하도록 요청할 때, 증상이 아닌 근본 원인을 해결하는 다음 방법을 선호하세요:

  • 코드 내 키: 시크릿 관리자가 주입한 환경 변수 또는 공급자 SDK를 통한 런타임 조회로 교체합니다. .env.example에 플레이스홀더를 추가합니다. 실제 값을 어디에도 작성하지 마세요. 키가 여전히 폐기되어야 한다고 사용자에게 알립니다. 코드에서 제거한다고 유출이 해제되는 것은 아닙니다.
  • 클라이언트에 도달하는 시크릿: 사용자를 인증하고, 사용자 및 테넌트별로 속도를 제한하며, 모델 및 작업을 허용 목록에 추가하고, 키를 보유하는 백엔드 경로 또는 AI 게이트웨이 뒤로 호출을 이동합니다. 클라이언트에는 게시 가능한 키만 유지합니다.
  • 검증되지 않은 웹훅: 공급자 SDK를 사용하여 원시 본문의 서명을 확인합니다. 오래된 타임스탬프를 거부하고, 이벤트 ID로 중복 제거한 후 상태를 변경하기 전에 공급자로부터 객체를 다시 가져옵니다.
  • CI 문제: 액션을 커밋 SHA로 고정합니다(git ls-remote로 SHA 확인, 태그는 주석에 유지). permissions: contents: read를 추가합니다. 정적 클라우드 키를 OIDC로 교체합니다. npm ci --ignore-scripts를 사용합니다.
  • Docker 문제: 빌드 타임 시크릿에 BuildKit RUN --mount=type=secret을 사용하고, non-root USER를 사용합니다.
  • 에이전트 접근: .claude/settings.json에 permissions.deny 항목 Read(./.env) 및 Read(./.env.*)를 추가합니다. 평문 파일이 전혀 존재하지 않도록 런타임 주입(doppler run, infisical run, op run)을 권장합니다.

지속적 사용

게이트가 출시 시에만이 아니라 모든 PR에서 실행되도록 스캐너를 CI에 연결할 것을 제안하세요:

- run: python3 tools/deploy-security-gate/scripts/scan.py . --fail-on high

또한 체크리스트 섹션 12의 주기로 정기적인 리뷰를 제안하세요.

참조 파일

  • references/checklist.md: 전체 체크리스트(섹션 1–14). 각 항목은 [auto](스캐너), [code](코드 리뷰) 또는 [manual](소유자 확인)로 태그됩니다. 5-6단계 및 정확한 제어가 필요할 때 읽으세요.
  • references/integrations.md: AI 게이트웨이 및 LLM 공급자, MCP 서버, 결제, 분석 및 인증에 대한 양호한 상태의 예시와 찾아야 할 패턴. 범위 내 연동의 섹션을 읽으세요.
  • references/leaked-key-runbook.md: 라이브 키가 발견되었을 때의 단계별 대응 방법으로, 공급자별 키 폐기 지침을 포함합니다.

관련 스킬