CI/CD 파이프라인을 구축했지만, 보안 검증 없이 빌드와 배포만 자동화하고 있다면 — 공격자에게 자동으로 문을 열어주는 파이프라인을 운영하는 셈입니다. DevSecOps는 보안을 파이프라인의 마지막 관문이 아니라 모든 단계에 내장하는 접근 방식입니다.
핵심 요약
- DevSecOps는 DevOps 워크플로우에 보안을 자동화하여 통합하는 문화이자 실천 방법입니다. 도구 하나를 추가하는 것이 아니라 개발-보안-운영의 협업 구조를 바꾸는 것입니다.
- Shift Left 원칙: 보안 검증을 배포 직전이 아니라 코드 작성 시점부터 적용합니다. 늦게 발견할수록 수정 비용이 급격히 증가합니다.
- 파이프라인 보안 자동화의 핵심 단계는 SAST(정적 분석), SCA(의존성 검사), 컨테이너 이미지 스캔, Secret 탐지, DAST(동적 분석)입니다.
- 도구 선택보다 "어떤 단계에서 무엇을 차단할 것인가"를 먼저 정의하는 것이 중요합니다. 모든 검사를 한꺼번에 blocking으로 설정하면 개발 속도가 급격히 저하됩니다.
- 점진적 도입이 핵심: 먼저 데이터를 수집하고(non-blocking), critical 항목부터 차단하고, 팀이 적응하면 범위를 확장합니다.
1. 왜 DevSecOps가 필요한가
스타트업에서 GitHub Actions로 CI/CD 파이프라인을 운영한다고 가정합니다. 개발자가 PR을 올리면 빌드, 단위 테스트, Docker 이미지 빌드, ECR 푸시, ECS 배포가 자동으로 실행됩니다.
이 파이프라인에 보안 검증이 없다면 어떤 일이 벌어질까요?
- 개발자가 실수로 하드코딩한 AWS Access Key가 Docker 이미지에 포함된 채 배포됩니다.
- npm 의존성에 포함된 취약한 라이브러리가 프로덕션까지 그대로 올라갑니다.
- 베이스 이미지에 알려진 CVE가 있지만 아무도 확인하지 않습니다.
- SQL Injection이 가능한 코드가 코드 리뷰에서 걸러지지 않고 배포됩니다.
전통적인 보안 검토 방식은 배포 직전에 보안팀이 수동으로 검토하는 구조입니다. 이 방식에는 두 가지 문제가 있습니다.
| 문제 | 결과 |
|---|---|
| 발견 시점이 늦음 | 코드가 이미 완성된 후 수정하면 비용이 10~100배 증가 |
| 속도와 보안이 충돌 | "보안 검토 대기 중" 상태가 릴리스를 막아 보안을 우회하려는 압력 발생 |
DevSecOps는 이 구조적 문제를 해결합니다. 보안 검증을 자동화하고 파이프라인에 내장하면, 빠르게 배포하면서도 보안 기준선을 유지할 수 있습니다.
2. DevSecOps의 핵심 원칙
2.1 Shift Left: 보안을 왼쪽으로 이동
소프트웨어 개발 생명주기(SDLC)를 왼쪽(설계/개발)에서 오른쪽(배포/운영)으로 읽을 때, Shift Left는 보안 활동을 가능한 한 왼쪽으로 당기는 것을 의미합니다.
| 단계 | 전통 방식 | DevSecOps 방식 |
|---|---|---|
| 설계 | 보안 고려 없음 | Threat Modeling 수행 |
| 코딩 | 보안 검증 없음 | IDE에서 실시간 SAST 피드백 |
| 빌드 | 보안 검증 없음 | 자동 SAST + SCA + Secret 탐지 |
| 테스트 | 기능 테스트만 | DAST + 컨테이너 스캔 추가 |
| 배포 직전 | 수동 보안 검토 | 이미 자동 검증 완료 |
| 운영 | 사후 대응 | 런타임 모니터링 + 자동 대응 |
2.2 보안을 코드로(Security as Code)
보안 정책도 인프라처럼 코드로 정의하고 버전 관리합니다.
- 파이프라인 보안 게이트: YAML로 정의된 검사 조건
- 정책 검증: OPA/Rego, Checkov 같은 도구로 IaC 검증
- 컴플라이언스: CIS Benchmark 기반 자동 점검
2.3 공동 책임(Shared Responsibility)
DevSecOps에서 보안은 보안팀만의 업무가 아닙니다.
| 역할 | 책임 |
|---|---|
| 개발자 | 안전한 코드 작성, 취약점 수정, Secret 관리 규칙 준수 |
| 보안 엔지니어 | 정책 정의, 도구 설정, 오탐 관리, 위협 모델링 지원 |
| DevOps/플랫폼 | 파이프라인에 보안 도구 통합, 자동화 유지 |
3. CI/CD 파이프라인에 보안을 통합하는 단계
3.1 Pre-Commit: 코드 작성 단계
코드가 저장소에 올라가기 전에 첫 번째 방어선을 설정합니다.
Secret 탐지 (pre-commit hook)
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.2
hooks:
- id: gitleaks
개발자의 로컬 환경에서 커밋 시점에 API Key, 비밀번호, 토큰 등이 포함되었는지 검사합니다. 저장소에 한번 올라간 Secret은 git history에 남기 때문에, 이 단계에서 차단하는 것이 가장 효과적입니다.
IDE 통합 SAST
SonarQube, Snyk 등의 IDE 플러그인을 사용하면 코드 작성 중 실시간으로 보안 취약점 피드백을 받을 수 있습니다. CI에서 실패하기 전에 개발자가 직접 수정할 수 있어 피드백 루프가 짧아집니다.
3.2 CI 단계: 빌드 시 자동 검증
PR이 올라오거나 main 브랜치에 머지될 때 자동으로 실행되는 보안 검사입니다.
SAST (Static Application Security Testing)
소스 코드를 실행하지 않고 정적으로 분석하여 보안 취약점을 탐지합니다.
- 탐지 대상: SQL Injection, XSS, Path Traversal, 안전하지 않은 암호화 등
- 주요 도구: SonarQube (Server 2026.3 기준 MCP 서버 내장), Snyk Code, Checkmarx, Semgrep
- 특징: 빠른 피드백, 오탐(false positive)이 많을 수 있음
# GitHub Actions에서 Semgrep SAST 실행 예시
- name: Run Semgrep SAST
uses: semgrep/semgrep-action@v1
with:
config: >-
p/security-audit
p/secrets
SCA (Software Composition Analysis)
오픈소스 의존성의 알려진 취약점(CVE)과 라이선스 위반을 검사합니다.
- 탐지 대상: 취약한 npm 패키지, 라이선스 비호환, 더 이상 유지보수되지 않는 라이브러리
- 주요 도구: Snyk Open Source, Dependabot, Trivy (filesystem 모드), OWASP Dependency-Check
- 특징: 프로젝트 코드의 70~90%가 오픈소스 의존성이므로 SCA는 필수
# Trivy를 사용한 의존성 취약점 스캔
- name: Run Trivy SCA scan
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
severity: 'CRITICAL,HIGH'
exit-code: '1'
주의: Trivy는 2026년 3월 공급망 공격(CVE-2026-33634)을 경험했습니다. v0.69.4~v0.69.6은 악성 코드가 포함된 버전입니다. 사용 시 반드시 안전한 버전(v0.70.0 이상 또는 v0.69.3)을 지정해야 합니다. 이 사건 자체가 Supply Chain Security의 중요성을 보여주는 사례입니다.
Secret 탐지 (CI 레벨)
pre-commit을 우회하거나 설정하지 않은 개발자의 코드도 CI에서 한 번 더 검사합니다.
- 주요 도구: Gitleaks, TruffleHog, GitHub Secret Scanning
- 정책: Secret이 탐지되면 빌드를 무조건 실패시킵니다 (non-negotiable)
3.3 컨테이너 이미지 스캔
Docker 이미지를 빌드한 후, Registry에 푸시하기 전에 이미지 내부의 취약점을 검사합니다.
- 탐지 대상: 베이스 이미지 OS 패키지 CVE, 애플리케이션 라이브러리 CVE, 잘못된 설정(root 실행 등)
- 주요 도구: Trivy (image 모드), Snyk Container, Amazon ECR Image Scanning, Aqua Security
- 정책 예시: Critical CVE가 1개 이상이면 빌드 실패, High는 경고만
# Trivy 컨테이너 이미지 스캔
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Scan container image
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
severity: 'CRITICAL'
exit-code: '1'
3.4 IaC 보안 검증
Terraform, CloudFormation, Kubernetes 매니페스트 등 인프라 코드의 보안 설정을 검사합니다.
- 탐지 대상: S3 퍼블릭 접근 허용, Security Group에서 0.0.0.0/0 허용, 암호화 미설정 등
- 주요 도구: Checkov, tfsec, KICS, Snyk IaC
- 특징: 인프라가 배포되기 전에 잘못된 설정을 차단할 수 있음
# Checkov으로 Terraform 검증
- name: Run Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: ./terraform
framework: terraform
soft_fail: false
3.5 CD 단계: 배포 전/후 검증
DAST (Dynamic Application Security Testing)
배포된 애플리케이션을 실제로 실행하면서 외부 공격자 관점에서 취약점을 탐지합니다.
- 탐지 대상: 인증 우회, CORS 설정 오류, 헤더 누락, 런타임 Injection
- 주요 도구: OWASP ZAP, Nuclei, Burp Suite (Enterprise)
- 실행 시점: staging 환경 배포 후, production 배포 전
- 특징: 실제 동작 기반이라 오탐이 적지만, 실행 시간이 길고 전체 커버리지 확보가 어려움
# OWASP ZAP을 staging에서 실행
- name: DAST Scan
uses: zaproxy/action-full-scan@v0.12.0
with:
target: 'https://staging.myapp.com'
rules_file_name: '.zap/rules.tsv'
배포 승인 게이트
모든 자동화된 보안 검사를 통과한 후에도, 운영 환경 배포 전에 승인 게이트를 설정할 수 있습니다. 보안 정책 위반이 없는지 최종 확인하는 단계입니다.
3.6 런타임 보안 모니터링
배포 후에도 보안 모니터링은 계속됩니다. DevSecOps는 "배포하면 끝"이 아닙니다.
- 런타임 취약점 모니터링: 새로운 CVE가 공개되면 운영 중인 이미지에 영향이 있는지 알림
- 이상 행위 탐지: 비정상적인 API 호출 패턴, 권한 상승 시도 탐지
- 도구: AWS GuardDuty, Falco (Kubernetes 런타임), Snyk Container Monitor
4. 실무 설계: 점진적 도입 전략
모든 보안 검사를 한꺼번에 blocking으로 설정하면 개발 속도가 급격히 저하됩니다. 실무에서는 단계적으로 도입하는 것이 현실적입니다.
Phase 1: 가시성 확보 (1~2주)
- 모든 검사를 non-blocking(경고만)으로 설정
- 현재 코드베이스의 취약점 현황 파악
- 오탐(false positive) 비율 측정
- 팀에 보안 스캔 결과 공유 시작
Phase 2: Critical 항목 차단 (2~4주)
- Secret 탐지 → 무조건 빌드 실패 (타협 없음)
- Critical CVE → 빌드 실패
- IaC에서 퍼블릭 접근 허용 → 빌드 실패
- 나머지는 여전히 경고만
Phase 3: 범위 확장 (1~3개월)
- High CVE → 빌드 실패 추가
- SAST 규칙 중 오탐이 적은 항목 → blocking 전환
- DAST를 staging 환경에 추가
- SLA 설정: "Critical은 24시간 내 수정, High는 1주 내 수정"
Phase 4: 성숙 단계
- 보안 메트릭 대시보드 운영 (MTTR, 취약점 추세, 차단율)
- Security Champion 제도 도입 (팀별 보안 담당 개발자)
- 정기적 Threat Modeling
- 공급망 보안(SBOM, 서명 검증) 추가
5. 도구 선택 기준과 비교
| 검사 유형 | 오픈소스 | 상용 | 선택 기준 |
|---|---|---|---|
| SAST | Semgrep, SonarQube CE | Snyk Code, Checkmarx | 언어 지원 범위, 오탐률, IDE 통합 |
| SCA | Trivy, OWASP Dep-Check | Snyk Open Source, Mend | 취약점 DB 업데이트 속도, 수정 가이드 품질 |
| Container | Trivy, Grype | Snyk Container, Aqua | 스캔 속도, OS/언어 패키지 커버리지 |
| Secret | Gitleaks, TruffleHog | GitHub Advanced Security | 패턴 커스터마이징, 사후 대응 워크플로우 |
| IaC | Checkov, tfsec | Snyk IaC, Prisma Cloud | 지원 프레임워크 범위, 정책 커스터마이징 |
| DAST | OWASP ZAP, Nuclei | Burp Suite Enterprise | API 지원, 인증 처리, 스캔 속도 |
도구 선택 시 고려사항
- 팀 규모 10명 이하: Trivy + Semgrep + Gitleaks 조합으로 시작. 무료이면서 커버리지가 넓습니다.
- 팀 규모 10~50명: Snyk 같은 통합 플랫폼 검토. 도구 파편화를 줄이고 대시보드를 통합할 수 있습니다.
- 엔터프라이즈: Checkmarx, Veracode 같은 풀 플랫폼. 컴플라이언스 보고서, RBAC, 감사 추적이 필요한 경우 적합합니다.
6. GitHub Actions 기반 DevSecOps 파이프라인 예시
name: DevSecOps Pipeline
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# 1. Secret 탐지
- name: Detect secrets
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# 2. SAST - 정적 분석
- name: SAST scan
uses: semgrep/semgrep-action@v1
with:
config: p/security-audit
# 3. SCA - 의존성 취약점
- name: SCA scan
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
severity: 'CRITICAL,HIGH'
exit-code: '1'
# 4. Docker 빌드
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
# 5. 컨테이너 이미지 스캔
- name: Container scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
severity: 'CRITICAL'
exit-code: '1'
# 6. IaC 검증
- name: IaC security check
uses: bridgecrewio/checkov-action@master
with:
directory: ./terraform
soft_fail: false
dast-scan:
needs: [security-scan]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to staging
run: echo "Deploy to staging environment"
- name: DAST scan
uses: zaproxy/action-full-scan@v0.12.0
with:
target: 'https://staging.myapp.com'
이 예시에서 보안 검사 순서는 의도적으로 설계되었습니다: 1. Secret 탐지가 가장 먼저 — Secret 유출은 즉시 차단해야 합니다. 2. SAST → SCA → Container 순으로 범위를 확장합니다. 3. DAST는 staging 배포 후 별도 job으로 실행합니다.
7. 흔한 실수와 대응 방법
| 실수 | 문제점 | 대응 |
|---|---|---|
| 모든 검사를 즉시 blocking | 빌드 실패 폭주로 개발자 반발 | Phase별 점진 도입 |
| 오탐 관리 미흡 | 개발자가 보안 알림을 무시하기 시작 | 정기적 오탐 리뷰, 예외 규칙 관리 |
| 도구만 도입하고 프로세스 없음 | 취약점이 발견되어도 누가 수정할지 불명확 | SLA 정의, 담당자 지정, 추적 시스템 |
| CI에서만 검사 | 런타임에 새로 공개된 CVE 대응 불가 | 주기적 이미지 재스캔, 런타임 모니터링 |
| Secret 유출 후 rotate 미수행 | 유출된 키가 여전히 유효 | Secret 유출 시 즉시 rotate + 사용 이력 감사 |
8. DevSecOps와 Supply Chain Security
2026년 3월 Trivy 공급망 공격 사건은 DevSecOps 도구 자체도 공격 대상이 될 수 있음을 보여줍니다. 파이프라인 보안은 코드만의 문제가 아닙니다.
공급망 보안 체크리스트:
- GitHub Actions에서 외부 Action 사용 시 커밋 SHA로 버전을 고정합니다 (태그 대신)
- SBOM(Software Bill of Materials)을 생성하고 관리합니다
- 컨테이너 이미지 서명(Cosign, Notation)으로 무결성을 검증합니다
- 의존성 업데이트는 자동화하되 검토 후 머지합니다 (Dependabot, Renovate)
# 태그 대신 SHA로 Action 고정 (공급망 보안)
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
9. 비용과 Trade-off
| 관점 | DevSecOps 도입 전 | DevSecOps 도입 후 |
|---|---|---|
| 보안 검증 시간 | 릴리스 직전 수일~수주 | 파이프라인 실행 시 수분 추가 |
| 취약점 발견 시점 | 배포 후 또는 침해 후 | 코드 작성 시점 |
| 수정 비용 | 높음 (설계 변경 필요할 수 있음) | 낮음 (코드 수준 패치) |
| CI 실행 시간 | 빌드+테스트만 | 보안 스캔으로 2~5분 추가 |
| 도구 비용 | 없음 또는 수동 도구 | 오픈소스 무료 / 상용 팀당 월 수십~수백 달러 |
| 개발자 학습 비용 | 없음 | 초기 적응 기간 1~2주 |
trade-off 판단 기준: - CI 시간이 2~5분 늘어나는 대신, 프로덕션 보안 사고 리스크를 크게 줄일 수 있습니다. - 오픈소스 도구 조합으로 시작하면 도구 비용 없이 기본적인 보안 자동화를 구축할 수 있습니다. - 팀 규모가 커지면 통합 플랫폼의 대시보드와 정책 관리 기능이 운영 효율에 기여합니다.
10. 정리: DevSecOps 도입 체크리스트
| 단계 | 항목 | 우선순위 |
|---|---|---|
| Pre-Commit | Secret 탐지 (Gitleaks) | 즉시 |
| Pre-Commit | IDE 보안 플러그인 설정 | 높음 |
| CI | Secret 스캔 (blocking) | 즉시 |
| CI | SCA 의존성 스캔 | 높음 |
| CI | SAST 정적 분석 | 높음 |
| CI | 컨테이너 이미지 스캔 | 높음 |
| CI | IaC 보안 검증 | 중간 |
| CD | DAST 동적 분석 (staging) | 중간 |
| 운영 | 런타임 모니터링 | 중간 |
| 프로세스 | 취약점 SLA 정의 | 높음 |
| 프로세스 | Security Champion 지정 | 중간 |
| 공급망 | Action SHA 고정 | 높음 |
| 공급망 | SBOM 생성 | 중간 |
DevSecOps는 하루 아침에 완성되는 것이 아닙니다. 점진적으로 도입하고, 팀의 성숙도에 맞춰 범위를 확장하는 것이 현실적인 접근입니다. 중요한 것은 "어떤 도구를 쓰느냐"보다 "팀이 보안을 일상적인 개발 프로세스의 일부로 받아들이는가"입니다.
관련 글: - CI/CD 파이프라인 기본 구조: 코드 커밋부터 프로덕션 배포까지 - 클라우드 보안 기본 원칙: 최소 권한, 네트워크 격리, 감사 로그 - GitHub Actions에서 Secret을 안전하게 관리하는 방법
'Security' 카테고리의 다른 글
| IAM과 RBAC 차이: AWS, Azure, GCP 기준으로 이해하기 (0) | 2026.06.08 |
|---|---|
| OIDC 기반 인증 설계: GitHub Actions, EKS, Cloud Provider 연동 (0) | 2026.06.08 |
| GitHub Actions에서 Secret을 안전하게 관리하는 방법 (0) | 2026.06.06 |
| AWS IAM Role과 Policy 차이: 권한을 설계하는 두 가지 축 (0) | 2026.05.29 |
| 클라우드 보안 기본 원칙: 최소 권한, 네트워크 격리, 감사 로그 (0) | 2026.05.28 |