DevSecOps 보안 테스트 파이프라인을 CI/CD에 통합하는 방법

DevSecOps 보안 테스트 파이프라인에 SAST, SCA, SBOM, DAST, 정책 게이팅을 연결하고 운영하는 실무 기준을 정리한다.

2026-08-14 · 최초 발행 2025-12-24

코드 변경부터 런타임까지 이어지는 보안 검사

DevSecOps 보안 테스트 파이프라인은 개발·빌드·배포의 전 구간에 보안 검사를 녹이고 자동화하는 방식이다. 애플리케이션, 인프라, 공급망에서 발생하는 취약점을 이른 시점에 찾아 차단하면서 배포 속도와 품질을 함께 관리한다.

검사 결과는 단순 리포트로 끝나지 않는다. 정책 기반 게이트로 평가하고, 티켓·대시보드·서명·감사 로그를 연결해 조치와 검증이 이어지는 폐쇄 루프를 만든다. 수동 스캔을 특정 시점에 수행하던 방식과 달리, 코드 변경 단위로 검사를 지속한다는 점이 핵심이다.

보안·개발·운영 조직은 Policy as Code와 SBOM·서명 같은 표준 아티팩트를 공유하며 품질 기준을 맞춘다.

PR/PushPre-commit/Pre-merge빌드SBOM 생성컨테이너 빌드스테이징 배포정책 평가통과차단프로덕션 배포소스 코드 저장소CI 트리거로컬/CI 빠른 검사('Secrets','Lint')SAST/SCA 실행아티팩트 저장소이미지 스캔('Container')DAST/IAST게이트 통과 여부?서명('Cosign')/릴리스이슈 생성('Jira')/'Slack' 알림런타임 모니터링('WAF/IDS','RASP')

빠른 피드백과 배포 후 검증을 함께 설계한다

Shift-left에서는 PR 단위로 SAST, SCA, Secrets, IaC 스캔을 빠르게 실행해 개발자 피드백 루프를 줄인다. 캐시와 증분 스캔은 빌드 시간을 통제하는 수단이다.

Shift-right는 스테이징과 프로덕션에서 DAST·IAST, 런타임 취약점·행위 탐지를 연계한다. 배포 뒤의 검증 결과를 다시 반영해 실제 리스크를 낮춘다.

정책은 심각도, CWE/CVE, 라이선스, 베이스라인, 허용 기간(예외 만료)을 코드로 다룬다. OPA/Conftest, SARIF 규격, 저장소 브랜치 보호 규칙을 결합하면 차단과 허용 판단을 일관되게 적용할 수 있다.

SBOM은 CycloneDX/SPDX 형식으로 생성·보관해 공급망을 추적하는 기반이 된다. CVE DB 업데이트와 동기화하면 재평가를 자동화할 수 있으며, 아티팩트와 이미지에 Cosign/Sigstore 서명을 적용하고 배포 시 검증하면 무결성을 보증할 수 있다.

대규모 실행 환경에서는 변경 파일·모듈 단위의 범위 제한, 병렬 실행, 증분 스캔으로 시간을 관리한다. 스테이지별 타임아웃과 리트라이를 두고, 스캐너 컨테이너화·SCA DB 및 언어 빌드 캐시·중앙 취약점 DB 미러링을 활용해 병렬 처리에 대응한다.

티켓 시스템(Jira)과 양방향으로 연동하고 SLO/SLI(예: 고위험 MTTR, 빌드 실패율)를 모니터링한다. 예외 승인 워크플로우도 표준화해야 한다. 정책 버전, 스캔 결과, 서명 정보를 모두 남기면 감사 시점에도 결정을 재현할 수 있다.

테스트 유형 성능(시간/자원) 확장성 일관성 안정성(오탐/과탐) 운영 편의
SAST 중간 높음 높음 오탐 중간 IDE/CI 연동 용이
SCA 빠름 높음 높음 안정적 SBOM 연계 용이
IaC Scan 빠름 높음 높음 낮음 규정 준수에 유리
Container Scan 중간 높음 높음 안정적 이미지 파이프라인 친화
DAST 느림 중간 중간 과탐 가능 스테이징 필요

파이프라인 입력과 산출물의 연결

입력은 코드 변경(PR/Push), 의존성 선언파일, IaC 템플릿, 컨테이너 Dockerfile, 대상 URL이다.

PR 단계에서는 Secrets, SAST, SCA, IaC 스캔을 병렬로 수행한다. 심각도 임계를 넘거나 금지된 라이선스를 사용하면 실패 조건이 된다. 빌드 단계에서는 SBOM을 만들고 이미지를 빌드·스캔하며, 베이스 이미지의 고위험 미해결 또는 서명 검증 실패를 차단 조건으로 둔다. 스테이징 단계에서는 DAST/IAST와 취약점·커버리지·가용성 정책 평가를 실행한다.

결과물은 SARIF/JSON 리포트, SBOM, 서명 메타데이터, 이슈 티켓, 대시보드 지표로 남긴다. 허용 요청에는 만료일과 대체통제를 명시하고 정책 저장소 PR에서 승인한다. 타임아웃이 발생하면 스캐너를 격리한 뒤 재시도 1회를 수행하며, 계속 실패하면 소음 억제 로깅과 차단으로 처리한다.

GitHub Actions로 구성한 보안 검사 예시

전제조건은 다음과 같다.

  • Runner: ubuntu-latest
  • 레지스트리 권한(OIDC 또는 PAT), 대상 URL 준비
  • 액션 버전은 예시, 최신 정보 확인 필요
name: security-pipeline
on:
  pull_request:
  push:
    branches: [ main ]

jobs:
  security:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
      id-token: write
    env:
      SEVERITY_THRESHOLD: HIGH
      TARGET_URL: https://staging.example.com
    steps:
      - uses: actions/checkout@v4

      # Secrets Scan
      - name: Gitleaks
        uses: gitleaks/gitleaks-action@v2
        with:
          args: detect --source . --no-git -v --redact --exit-code 1

      # SAST (Semgrep)
      - name: Semgrep SAST
        uses: returntocorp/semgrep-action@v1
        with:
          config: p/ci
          generateSarif: "1"
          publishToken: ${{ secrets.SEMGREP_APP_TOKEN }}
        continue-on-error: false

      # SCA + FS Scan (Trivy)
      - name: Trivy FS (SCA)
        uses: aquasecurity/trivy-action@0.20.0
        with:
          scan-type: fs
          format: sarif
          output: trivy-fs.sarif
          severity: CRITICAL,HIGH

      # IaC Scan (tfsec)
      - name: tfsec
        uses: aquasecurity/tfsec-action@v1.0.3
        with:
          additional_args: --soft-fail-severity=MEDIUM

      # Build image
      - name: Build image
        run: |
          docker build -t ghcr.io/org/app:${{ github.sha }} .

      # SBOM (Syft)
      - name: SBOM (CycloneDX)
        uses: anchore/sbom-action@v0
        with:
          image: ghcr.io/org/app:${{ github.sha }}
          format: cyclonedx-json
          output-file: sbom.cdx.json

      # Container Scan (Trivy Image)
      - name: Trivy Image
        uses: aquasecurity/trivy-action@0.20.0
        with:
          image-ref: ghcr.io/org/app:${{ github.sha }}
          format: sarif
          output: trivy-image.sarif
          severity: CRITICAL,HIGH

      # Upload SARIF to GitHub Security tab
      - name: Upload SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: |
            trivy-fs.sarif
            trivy-image.sarif
            semgrep.sarif

      # DAST (OWASP ZAP baseline)
      - name: ZAP Baseline
        uses: zaproxy/action-baseline@v0.12.0
        with:
          target: ${{ env.TARGET_URL }}
          cmd_options: "-a -m 5" # 5분 제한
        continue-on-error: true

      # Policy Gate (간단 샘플)
      - name: Gate - Fail on HIGH/CRITICAL
        run: |
          # 실패 기준을 확장하려면 SARIF 파서 사용 권장
          if grep -qi "CRITICAL\|HIGH" trivy-image.sarif; then
            echo "Gate: severity threshold exceeded"
            exit 1
          fi

      # Optional: Cosign sign (레지스트리 로그인 필요)
      - name: Cosign Sign
        if: ${{ github.ref == 'refs/heads/main' }}
        run: |
          cosign sign ghcr.io/org/app:${{ github.sha }} --yes

소음, 성능, 예외를 정책으로 다룬다

보안 검사는 탐지량만으로 운영할 수 없다. 베이스라인·허용 리스트·최대 신규 취약점 수 같은 상대 기준을 함께 적용해야 하며, 무조건 차단하는 정책은 개발 생산성을 떨어뜨릴 리스크가 있다.

PR에서는 증분·샘플링을 적용하고, main 병합과 릴리스 태그에서는 전체 스캔을 수행한다. DAST는 스테이징 배포 뒤 예약 실행하는 방식이 적합하다.

도구가 늘어날수록 결과는 SARIF로 통합하고, 정책은 OPA로 공통화하며, SLO를 공통 메트릭으로 사용해 이질적인 도구를 운영 표준 안에 묶는다.

취약점 조기 발견 비율은 4070%p 향상하고, 고위험 MTTR은 3060% 단축되며, 릴리스 차단 건수 대비 재작업 시간은 20~40% 감소할 수 있다. SBOM 보급률 90% 이상과 이미지 서명 적용률 95% 이상도 달성 가능하다. 수치는 조직 성숙도에 따라 변동, 최신 정보 확인 필요.

이 체계는 개발자의 자율 보안 문화를 정착시키고 보안팀의 감사·거버넌스 역량을 강화한다. 릴리스 신뢰도와 금융·의료 규제 같은 규정 준수 대응력도 함께 높일 수 있다.

DevSecOps보안 테스트CI/CD공급망 보안SBOM