DevSecOps 실현을 위한 Secret Protection 활용 방안
이 문서는 이전에 포스팅한 GitHub Advanced Security의 Code Security로 구현하는 DevSecOps에서 이어지는 시리즈로, GHAS의 Secret Protection 기능을 다룹니다.
Code Security가 코드 내 취약점을 탐지·수정하는 데 중점을 둔다면, Secret Protection은 비밀 키나 자격증명이 원격 저장소에 도달하기 전에 차단하는 역할을 합니다. 두 기능은 서로 보완적으로 작동하며, 함께 사용할 때 개발 프로세스 전반에 걸쳐 강력한 방어선을 구축할 수 있습니다.
이 문서는 실제 고객 질문을 바탕으로 기능과 활용 방법을 설명합니다. 고객사 신원 보호를 위해 질문은 일부 수정·일반화되었습니다.
❓ 고객 질문 리스트
| # | 질문 |
|---|---|
| Q | Secret Scanning과 Push Protection은 어떻게 다른가요? 각각 언제 동작하나요? |
| Q | Push Protection은 정확히 어떤 시점에 코드를 차단하나요? CI 파이프라인과의 관계가 궁금합니다. |
| Q | Secret Scanning은 어떤 종류의 시크릿을 탐지할 수 있나요? AWS 키나 Slack 토큰도 탐지되나요? |
| Q | 사내에서만 사용하는 자체 API 토큰 형식도 탐지할 수 있나요? |
| Q | AI 기반 비밀 탐지는 기존 패턴 탐지와 어떤 점이 다른가요? 오탐(False Positive)은 어떻게 줄이나요? |
| Q | 개발자가 Push Protection 경고를 무시하고 bypass할 경우 추적이 가능한가요? |
| Q | 이미 과거 커밋 히스토리에 시크릿이 올라간 경우 어떻게 처리해야 하나요? |
| Q | GitHub Actions 워크플로우에서 시크릿을 안전하게 참조하는 방법이 있나요? |
| Q | Secret Scanning 알림을 Slack, Teams 또는 SIEM(Sentinel/Splunk)에 연동할 수 있나요? |
| Q | 배포(CD) 단계에서도 시크릿 이슈가 있는 경우 배포를 자동으로 차단할 수 있나요? |
| Q | 조직 전체 저장소에 Push Protection을 강제로 적용할 수 있나요? 개별 저장소 단위로 끄는 것을 막을 수 있나요? |
📑 목차
- Secret Protection 개요 — GHAS 내 역할과 핵심 기능
- CI/CD 파이프라인에서의 동작 방식
- 탐지 방식 심층 비교 — 패턴 기반 vs AI 기반
- 조직 설정 가이드 — Push Protection·Custom Patterns·알림 연동
- 시크릿 유출 사고 대응 절차
- 피해야 할 흔한 실수
- 요약
1. Secret Protection 개요 — GHAS 내 역할과 핵심 기능
GHAS는 두 가지 보안 제품으로 구성됩니다.
| 제품명 | 포함 기능 | 목적 |
|---|---|---|
| GitHub Code Security | Code Scanning (CodeQL), Copilot Autofix, Security Campaigns, Premium Dependabot, Dependency Review | 취약점 탐지·수정 중심 (SAST + SCA) |
| GitHub Secret Protection | Secret Scanning, Push Protection, AI 기반 비밀 탐지, Custom Patterns 등 | 코드 내 비밀(토큰/키) 누출 탐지·방지 중심 |
이 문서에서는 GitHub Secret Protection 영역을 집중적으로 다룹니다. Code Security 관련 내용은 이전 포스팅 GitHub Advanced Security의 Code Security로 구현하는 DevSecOps를 참고하세요.
Secret Protection 핵심 기능 5가지
| 기능 | 설명 |
|---|---|
| Secret Scanning | 저장소 전체(커밋 히스토리 포함)에서 API 키·토큰·자격증명 패턴 탐지 |
| Push Protection | git push 시점에 시크릿 포함 여부를 차단 (코드가 원격에 도달하기 전) |
| AI 기반 비밀 탐지 | 정규식 패턴 외 문맥(context)을 분석해 오탐 감소, 신규 패턴 자동 감지 |
| Custom Patterns | 조직 내부 토큰·키 형식을 정규식으로 직접 정의하여 탐지 |
| Partner Validation | 탐지된 시크릿을 서비스 제공사(AWS, Slack 등)에 실시간 전달 → 즉시 무효화 |
업계 주요 활용 패턴
| 활용 패턴 | 설명 |
|---|---|
| Partner Validation 자동 무효화 | AWS·GCP·Slack 등 200+ 파트너와 연동, 유출 즉시 키 무효화 (대부분의 기업 기본 설정) |
| Custom Patterns으로 내부 토큰 탐지 | JWT 포맷·사내 서비스 API 키 등 퍼블릭 패턴에 없는 토큰을 조직 단위로 등록 |
| Non-provider 패턴 AI 탐지 | 정형화되지 않은 비밀번호·연결 문자열을 AI로 탐지 |
| Webhook → SIEM 연동 | Secret Scanning Alert를 Webhook으로 받아 Sentinel/Splunk에서 실시간 모니터링 |
| Org-level 정책 강제 | Enterprise 설정에서 모든 저장소에 Push Protection 강제 활성화 |
2. CI/CD 파이프라인에서의 동작 방식
CI 단계 — Push 시점 차단 (가장 중요)
flowchart TD
DEV["👨💻 개발자 git push"]
PP["🔐 Push Protection
CI 시작 전에 동작
(네트워크 레벨 차단)"]
DEC{"Secret 감지?"}
BLOCK["🚫 push 차단
개발자 수정 후 재시도"]
REPO["✅ 원격 저장소 반영"]
CI["⚙️ CI 파이프라인 진행"]
DEV --> PP
PP --> DEC
DEC -->|"YES"| BLOCK
BLOCK -.->|"수정 후 재시도"| DEV
DEC -->|"NO"| REPO
REPO --> CI
style DEV fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f
style PP fill:#fef3c7,stroke:#f59e0b,color:#78350f
style DEC fill:#fff7ed,stroke:#f97316,color:#7c2d12
style BLOCK fill:#fee2e2,stroke:#ef4444,color:#7f1d1d
style REPO fill:#dcfce7,stroke:#22c55e,color:#14532d
style CI fill:#ede9fe,stroke:#7c3aed,color:#3b0764
- Pull Request가 생성되기도 전에 차단하므로, 시크릿이 히스토리에 남지 않음
- 기존 커밋 히스토리 전체를 대상으로 Secret Scanning이 백그라운드 실행
CD 단계 — 배포 환경 보호
flowchart TD
MERGE["✅ PR Merge"]
TRIGGER["🚀 배포 트리거"]
DEC{"Secret Scanning <br/>Alert - 미해결?"}
BLOCK["🚫 배포 차단
GitHub Environment +
Protection Rules 연동"]
DEPLOY["🎉 배포 진행"]
MERGE --> TRIGGER
TRIGGER --> DEC
DEC -->|"YES"| BLOCK
DEC -->|"NO"| DEPLOY
style MERGE fill:#dcfce7,stroke:#22c55e,color:#14532d
style TRIGGER fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f
style DEC fill:#fff7ed,stroke:#f97316,color:#7c2d12
style BLOCK fill:#fee2e2,stroke:#ef4444,color:#7f1d1d
style DEPLOY fill:#dcfce7,stroke:#16a34a,color:#14532d
- 배포 환경(Environments)의 Required Reviewers 및 Deployment Protection Rules와 조합 활용
- Actions 워크플로우 내 시크릿은
$형태로만 참조, 평문 노출 방지- Azure KeyVault 연동으로 보안성 강화 가능
3. 탐지 방식 심층 비교 — 패턴 기반 vs AI 기반
패턴(정규식) 기반 탐지
기존 Secret Scanning은 GitHub이 관리하는 200+ 개의 정규식 패턴을 기반으로 동작합니다. AWS Access Key(AKIA[0-9A-Z]{16}), Slack Token(xox[baprs]-...), GitHub PAT(ghp_[A-Za-z0-9]{36}) 등 형식이 명확히 정의된 서비스 토큰은 이 방식으로 높은 정밀도로 탐지됩니다.
그러나 형식이 정해지지 않은 비밀번호, DB 연결 문자열, 사내 인증 토큰 등 비정형 시크릿(Generic Secret) 은 정규식만으로 탐지하기 어렵습니다.
AI 기반 탐지
| 구분 | 패턴(정규식) 기반 | AI 기반 |
|---|---|---|
| 탐지 대상 | 형식이 정해진 서비스 토큰 (AWS, Slack 등) | 비정형 Generic Secret (비밀번호, DB 연결 문자열 등) |
| 탐지 방식 | 문자열 패턴 매칭 | 변수명·값·주변 문맥 종합 분석 |
| 신규 패턴 대응 | GitHub이 패턴 추가할 때까지 탐지 불가 | 문맥 기반이므로 패턴 미등록 시크릿도 탐지 가능 |
| 오탐 가능성 | 낮음 (형식이 명확) | 상대적으로 높음 (플레이스홀더·테스트 값과 혼동) |
AI 탐지가 작동하는 대표적인 경우
1
2
3
4
# 변수명 + 고엔트로피 값 조합 → AI가 시크릿으로 판단
password = "xK9#mP2$vL8nQ4@wZ"
db_connection = "Server=prod.db;Password=R7!kN3@mX5"
api_secret = "a8f3d2c1e9b4f7a2d5c8e1b4f7a2d5c8"
오탐(False Positive) 처리 방법
오탐이 발생하는 전형적인 패턴
| 오탐 원인 | 예시 |
|---|---|
| 테스트 코드의 더미 값 | password = "test1234", api_key = "dummy-key-for-test" |
| 문서·예시 코드의 플레이스홀더 | YOUR_API_KEY_HERE, <INSERT_SECRET> |
| 무작위처럼 보이는 해시값 | Git 커밋 SHA, UUID 등 |
| 인코딩된 데이터 | Base64 인코딩 문자열 |
개별 Alert 단위 처리
1
2
3
4
5
Repository → Security → Secret scanning alerts
→ 해당 Alert 클릭 → "Close as" 선택
- "False positive" : 실제 시크릿이 아닌 경우
- "Used in tests" : 테스트 코드에서 의도적으로 사용한 경우
→ 코멘트에 사유 기록 (감사 추적용)
저장소·조직 단위 예외 처리 (반복 오탐 방지)
1
2
3
4
5
# .github/secret_scanning.yml — 특정 경로를 스캔에서 제외
excluded_paths:
- "tests/**"
- "docs/examples/**"
- "**/*.example"
⚠️
excluded_paths는 해당 경로 전체를 스캔에서 제외하므로 실제 시크릿이 섞이지 않는 경로에만 적용해야 합니다. 테스트 파일이라도 실제 운영 키를 사용하는 경우가 있으므로 주의가 필요합니다.
AI 탐지의 한계
- 완전히 새로운 형식의 사내 토큰은 AI도 놓칠 수 있음 → Custom Patterns 병행 등록 필수
- 오탐률이 패턴 기반보다 높으므로, Alert 알림 채널과 트리아지(분류) 프로세스를 사전에 정의해두는 것이 중요
4. 조직 설정 가이드 — Push Protection·Custom Patterns·알림 연동
Push Protection 활성화 (조직 전체 강제)
① 조직 전체에 Push Protection 적용 및 강제(Enforce)
1
2
3
4
5
6
조직 Settings
→ 사이드바 Security 섹션 → Advanced Security → Configurations
→ New configuration (또는 기존 설정 편집)
→ Secret scanning 섹션: Push protection → Enabled
→ Policy 섹션: Enforce configuration → Enforce
→ Save configuration → 전체 저장소에 Apply
Enforce configuration을 선택하면 개별 저장소 관리자가 해당 설정을 임의로 변경할 수 없음- 신규 저장소에 자동 적용하려면
Use as default for newly created repositories → All repositories설정
② Bypass 제어 — Delegated Bypass 설정
Push Protection의 Bypass를 완전 차단하거나 승인 프로세스로 관리하는 것이 Delegated Bypass 기능입니다.
1
2
3
4
5
위 Security Configuration 편집 화면에서:
→ Secret scanning → Push protection: Enabled 확인
→ Bypass privileges → "Specific actors" 선택
→ Select actors: 보안팀/Security Manager 등 지정된 역할만 추가
→ Save configuration
- Bypass 권한이 없는 일반 개발자가 push를 시도하면 bypass 요청(Request) 이 자동 생성됨
- 요청 시 반드시 사유(reason)를 입력해야 하며, 7일 내에 지정된 검토자가 승인/거절
- 모든 bypass 요청과 처리 내역은 Audit Log에 자동 기록
1
2
Audit Log 확인:
조직 Settings → Audit log → 이벤트 필터: push_protection_bypass
⚠️
Exempt옵션은 특정 액터를 Push Protection에서 완전히 제외합니다. CI/CD 자동화 봇 등 신뢰할 수 있는 서비스 계정에만 부여하고 남용하지 않아야 합니다.
Custom Patterns 등록
1
2
3
# 사내 API 토큰 패턴 예시 (Settings → Secret scanning → Custom patterns)
Pattern name: Internal API Token
Secret format: COMP-[A-Z0-9]{32}
- 퍼블릭 패턴(200+개)에 잡히지 않는 내부 시크릿 탐지 (Q4 대응)
- AI 탐지와 병행하여 사각지대 최소화
Alert 알림 채널 연결
1
2
3
# Webhook → Slack/Teams 연동 (Q9 대응)
Repository Settings → Webhooks
Event: Secret scanning alert
- 탐지 즉시 담당자에게 알림, 대응 지연 방지
- Sentinel/Splunk 등 SIEM과 연동하여 실시간 모니터링 가능
Actions 워크플로우에서 시크릿 참조 규칙
1
2
3
4
5
6
7
# ✅ 올바른 방식 (Q8 대응)
env:
API_KEY: $
# ❌ 절대 금지
env:
API_KEY: "sk-abc123..." # 평문 하드코딩
- Azure Key Vault 연동으로 보안성 추가 강화 가능
기존 히스토리 스캔 후 키 로테이션
- 저장소 활성화 직후 전체 히스토리 스캔 결과 확인
- 탐지된 시크릿은 코드 수정 전에 먼저 키 로테이션 (삭제만으로는 부족)
5. 시크릿 유출 사고 대응 절차
왜 git rm만으로는 부족한가?
Git은 모든 커밋을 불변(immutable) 객체로 저장합니다. 파일을 삭제하는 새 커밋을 만들어도, 과거 커밋 객체는 히스토리에 그대로 남아 있습니다. 즉, git log나 git show <commit> 명령으로 누구든 과거 시크릿을 조회할 수 있습니다.
또한, 저장소를 GitHub에 push한 순간 GitHub의 Secret Scanning이 이미 해당 시크릿을 감지하고 Alert를 생성합니다. 코드에서 지웠다고 해서 Alert가 자동으로 해소되지 않습니다.
단계별 대응 순서
| 단계 | 작업 | 이유 |
|---|---|---|
| 1단계 | 해당 키/토큰 즉시 무효화·로테이션 | 히스토리 정리 전에 먼저 해야 노출 피해 최소화 |
| 2단계 | GitHub Secret Scanning Alert 확인 | 탐지 여부 및 Partner Validation 자동 무효화 확인 |
| 3단계 | git filter-repo로 히스토리에서 완전 제거 |
git rm은 새 커밋만 추가, 히스토리는 그대로 남음 |
| 4단계 | git push --force 후 팀 전파 |
모든 팀원이 기존 로컬 clone을 버리고 재취득 필요 |
| 5단계 | Secret Scanning Alert 닫기 | 해결 완료 처리 및 감사 추적 기록 |
git filter-repo 실제 사용 예시
1
2
3
4
5
6
7
8
9
10
11
12
# 설치 (pip 사용)
pip install git-filter-repo
# 특정 문자열(실제 시크릿 값)을 히스토리 전체에서 제거
git filter-repo --replace-text <(echo 'ACTUAL_SECRET_VALUE==>***REMOVED***')
# 특정 파일 자체를 히스토리 전체에서 제거 (예: .env 파일)
git filter-repo --path .env --invert-paths
# 히스토리 정리 후 강제 push
git push origin --force --all
git push origin --force --tags
⚠️
git filter-repo는 커밋 해시를 재작성합니다. 실행 후 모든 팀원은 기존 로컬 clone을 삭제하고 재clone해야 합니다. fork한 저장소가 있다면 해당 fork도 별도 처리가 필요합니다.
Secret Scanning Alert 처리
1
2
3
Repository → Security → Secret scanning alerts
→ 해당 Alert 클릭 → "Close as" → "Revoked" 선택
→ 코멘트에 대응 내역 기록 (키 로테이션 완료, 히스토리 정리 완료 등)
Revoked로 닫아야 감사 추적(Audit Log)에 ‘대응 완료’로 기록됨False positive나Used in tests로 닫으면 실제 유출 사고임에도 잘못 분류됨
6. 피해야 할 흔한 실수
| 실수 | 올바른 대응 |
|---|---|
Push Protection 알림을 bypass로 무시 |
Bypass 사유를 필수 입력하도록 설정, Audit Log로 추적 |
시크릿 커밋 후 git rm으로만 삭제 |
git filter-repo로 히스토리 정리 + 즉시 키 로테이션 |
| 개인 저장소는 예외 처리 | Enterprise 정책으로 private 저장소 포함 전체 강제 |
| Custom Pattern 없이 운영 | 내부 토큰 형식 반드시 등록 |
요약
| 기능 | 설명 | CI/CD 단계 |
|---|---|---|
| Push Protection | 코드 유입 자체를 원천 차단 | CI 전단계 |
| Secret Scanning | 히스토리 전체 + 실시간 탐지 | CI 단계 |
| Custom Patterns | 내부 토큰까지 커버, 탐지 범위 확장 | CI 단계 |
| Partner Validation | 유출된 키 자동 무효화 | 사고 대응 |
| Webhook/SIEM 연동 | 실시간 모니터링 및 대응 | 운영 단계 |
핵심: Secret Protection은 배포 이후 대응이 아닌, 코드가 저장소에 도달하기 전 차단이 목표입니다.
Push Protection + Custom Patterns + 키 로테이션 프로세스를 조합하면 시크릿 유출 사고의 90% 이상을 예방할 수 있습니다.