
AI 기반 Docker 보안 스캐너로, 취약점을 쉬운 영어로 설명합니다. OWASP 랩 프로젝트입니다.

AI 기반 Docker 보안 스캐너로 취약점을 평이한 영어로 설명합니다
DockSec은 복잡한 보안 스캔 결과와 개발자가 실행할 수 있는 수정 사항 사이의 격차를 해소하는 OWASP Lab 프로젝트입니다. 업계 표준 스캐너(Trivy, Hadolint, Docker Scout)를 AI와 통합하여 상황에 맞는 보안 분석을 제공합니다.
200개 이상의 CVE 목록으로 사용자를 압도하는 대신, DockSec은:
모든 스캔은 로컬에서 수행됩니다. 사용자의 머신을 떠나는 것은 선택한 AI 제공자에게 전송되는 (비밀 정보가 삭제된) 파일 콘텐츠뿐이며, 로컬 모델이나 스캔 전용 모드를 사용하면 아무것도 외부로 나가지 않습니다. 데이터 흐름 및 개인정보 보호를 참조하세요.
DockSec 워크플로우: 스캔에서 실행 가능한 인사이트까지
DockSec은 4단계 파이프라인을 따릅니다:
DockSec은 로컬 스캐너를 오케스트레이션하므로 다음이 필요합니다:
| 요구 사항 | 필요한 용도 | 설치 |
|---|---|---|
| Python 3.12+ | DockSec 자체 | python.org |
| Trivy | 모든 스캔 (필수) | brew install trivy 또는 Trivy 문서 |
| Hadolint | Dockerfile 린팅 | brew install hadolint 또는 Hadolint 문서 |
| Docker | 이미지 스캔 (-i) | Docker 문서 |
또는 DockSec이 Trivy와 Hadolint를 대신 설치하게 할 수도 있습니다:```bash python -m docksec.setup_external_tools
### 2. DockSec 설치```bash
# Full install with AI analysis support (recommended)
pip install "docksec[ai]"
# Or the slim, scan-only core (no LLM dependencies, no API key needed)
pip install docksec
로컬 스캔에는 API 키가 필요하지 않습니다:```bash docksec Dockerfile --scan-only
모든 스캔은 결과 요약으로 끝납니다: 심각도 표, 등급이 포함된 0-100 보안 점수,
"Quick take" 작업 블록, 생성된 보고서(기본적으로 `~/.docksec/results/`에 저장),
및 제안된 다음 명령.
### 4. AI 분석 활성화
AI 분석은 발견 사항을 설명하고 수정 사항을 제안합니다. 제공업체를 선택하고 API 키를 설정한 후 실행하세요:```bash
# OpenAI (default provider)
export OPENAI_API_KEY="sk-..."
docksec Dockerfile
# Anthropic Claude
export ANTHROPIC_API_KEY="sk-ant-..."
docksec Dockerfile --ai-only --provider anthropic --model claude-sonnet-5
# Google Gemini
export GOOGLE_API_KEY="..."
docksec Dockerfile --ai-only --provider google
# Ollama (fully local, no API key, data never leaves your machine)
docksec Dockerfile --ai-only --provider ollama --model llama3.1
각 제공업체에는 합리적인 기본 모델이 있습니다 (OpenAI: gpt-4o, Anthropic:
claude-haiku-4-5, Google: gemini-1.5-pro, Ollama: llama3.1), 따라서 --model은
선택 사항입니다. 플래그를 반복하지 않으려면 환경 변수를 설정하세요 (또는 실행 디렉토리의 .env
파일에 넣으세요 - DockSec이 자동으로 로드합니다):```bash
export LLM_PROVIDER=anthropic
export LLM_MODEL=claude-sonnet-5
docksec Dockerfile
AI 제공자에게 콘텐츠를 보내기 전에, 비밀처럼 보이는 값(비밀번호, 토큰,
API 키, 개인 키 블록)은 자동으로 마스킹됩니다. 자세한 내용은
[데이터 흐름 및 개인정보 보호](#data-flow-and-privacy)를 참조하세요.
### 5. 또는 GitHub Action 사용```yaml
- name: Run DockSec AI Scanner
uses: OWASP/[email protected]
with:
dockerfile: 'Dockerfile'
openai_api_key: ${{ secrets.OPENAI_API_KEY }}
docksec Dockerfile -i myapp:latest
docksec --compose docker-compose.yml
docksec --image-only -i myapp:latest
docksec Dockerfile --scan-only
docksec -i myapp:latest --image-only --severity CRITICAL,HIGH,MEDIUM
docksec -i myapp:latest --image-only --fail-on high
docksec Dockerfile --scan-only --format json,html --output-dir ./reports
docksec -i myapp:latest --image-only --json
docksec Dockerfile --scan-only --sarif
docksec --image-only -i myapp:latest --sbom
docksec --image-only -i myapp:latest --offline
docksec -i myapp:latest --image-only --baseline .docksec-baseline.json --update-baseline docksec -i myapp:latest --image-only --baseline .docksec-baseline.json --fail-on high
docksec -i myapp:latest --image-only --ignore-file .docksec-ignore.yml
docksec -i myapp:latest --image-only --no-cache
docksec install-skill
docksec Dockerfile --scan-only --quiet # warnings, errors, summary only docksec Dockerfile --scan-only --verbose # INFO-level diagnostics on stderr docksec Dockerfile --scan-only --verbose --log-file logs/docksec.log docksec Dockerfile --no-color # also honors NO_COLOR
---
## 구성 파일
저장소 루트에 `.docksec.yml`을 커밋하고 팀 전체 - 그리고
모든 CI 작업 - 이 각 개발자가 자신의 플래그를 전달하는 대신
동일한 정책 하에 스캔합니다.```yaml
# yaml-language-server: $schema=https://owasp.org/DockSec/docksec-config-schema.json
severity: CRITICAL,HIGH
fail_on: HIGH
formats: [json, html]
output_dir: ./security-reports
rules:
disabled:
- compose-missing-healthcheck
모든 설정은 선택 사항이며, 생략한 항목은 환경 변수로 대체되고, 그다음에는 내장 기본값으로 대체됩니다. 주석이 포함된 전체 예제는 examples/.docksec.yml에 있습니다.
높은 우선순위부터:``` CLI flag > environment variable > .docksec.yml > built-in default
그래서 커밋된 `severity: LOW`는 명령줄의 `--severity CRITICAL`에 의해,
그리고 환경의 `DOCKSEC_DEFAULT_SEVERITY`에 의해 여전히 재정의됩니다.
### 검색
DockSec은 작업 디렉터리에서 `.docksec.yml`(또는 `.docksec.yaml`)을 찾은 다음
리포지토리 루트까지 위로 이동하므로, 모노레포 하위 디렉터리의 서비스는
최상위에 커밋된 정책을 상속합니다. 검색은 `.git`이 포함된
디렉터리에서 멈추므로 리포지토리 밖의 파일은 절대 가져오지
않습니다.
- `--config FILE`은 검색 대신 특정 파일을 사용합니다.
- `--no-config`는 재현 가능한 CI 실행을 위해 설정 파일을 무시합니다.
적용 중인 설정 파일은 스캔 배너에 표시되므로, 항상
어떤 정책이 적용되었는지 명확합니다.
### 설정
| 설정 | 해당 플래그 | 참고 |
| --- | --- | --- |
| `severity` | `--severity` | 이미지 스캔의 심각도 수준 |
| `fail_on` | `--fail-on` | CI 게이트 임계값 |
| `formats` | `--format` | 목록 형식: `[json, html]` |
| `output_dir` | `--output-dir` | 보고서 저장 위치 |
| `provider` | `--provider` | `openai`, `anthropic`, `google`, `ollama` |
| `model` | `--model` | 공급자의 모델 이름 |
| `offline` | `--offline` | 네트워크 없음; AI 및 Docker Scout 건너뜀 |
| `skip_ai_scoring` | `--skip-ai-scoring` | 로컬 점수화만 수행 |
| `no_redact` | `--no-redact` | AI 호출 전에 비밀 값을 마스킹하지 않음 |
| `no_cache` | `--no-cache` | 스캔 캐시 우회 |
| `ignore_file` | `--ignore-file` | 면제 파일 경로 |
| `baseline` | `--baseline` | 기준 파일 경로 |
| `rules.disabled` | - | 완전히 비활성화할 규칙 ID |
잘못된 설정 파일(알 수 없는 키, 잘못된 심각도)은 경고가 아니라
`2`로 종료되는 하드 오류입니다. 따라서 깨진 정책 파일로 인해
팀이 커밋하지 않은 규칙으로 스캔이 실행되는 일은 절대 없습니다.
### 편집기 자동 완성
첫 번째 줄의 `# yaml-language-server:` 주석은 자동 완성과
VS Code 및 JetBrains 편집기에서 인라인 검증을 제공합니다. 스키마는
[`docs/docksec-config-schema.json`](https://github.com/owasp/docksec/blob/main/docs/docksec-config-schema.json)에 게시되어 있으며
`docksec --print-config-schema`로 다시 생성할 수 있습니다.
### 규칙 비활성화
`rules.disabled`는 체크를 완전히 모든 곳에서 끕니다. 점수화, 보고서,
`--json` 및 `--fail-on` 게이트 전에 제거됩니다. 환경에 적용되지 않는 체크에
사용하세요. 팀이 분류하고 수용한 개별 발견 사항의 경우
[면제 파일](#ignoring-findings-waivers)을 선호하세요. 해당 항목에는
사유와 만료 날짜가 포함되어 감사 가능하게 유지됩니다.
---
## CI/CD 통합
### 종료 코드
DockSec은 빌드와 셸이 결과에 반응할 수 있도록 CI 친화적인 종료 코드를 사용합니다:
| 코드 | 의미 |
|---|---|
| `0` | 성공, `--fail-on` 이상의 발견 사항 없음 |
| `1` | `--fail-on` 임계값 이상의 발견 사항 있음 |
| `2` | 사용법 또는 인자 오류 |
| `3` | 도구 또는 런타임 오류(스캔 실패, 이미지를 찾을 수 없음, 도구 누락) |
`--fail-on`은 구조화된 발견 사항(이미지 취약점 및 컴포즈 오설정)을
기준으로 게이트합니다. `--fail-on`이 요청된 `--severity`보다 낮으면 스캔
심각도가 자동으로 넓어져 게이트가 해당 발견 사항을 관찰할 수 있습니다.
### 기계 판독 가능 출력
`--json`은 사람이 읽을 수 있는 요약 대신 단일 JSON 객체를 stdout으로 출력합니다
(스캔 정보, 취약점, 심각도 수, AI 발견 사항). 따라서 다른 도구로
바로 파이프할 수 있습니다:```bash
docksec -i myapp:latest --image-only --json | jq '.severity_counts'
--json만 사용하면 보고서 파일이 작성되지 않습니다. --format과 함께 사용하면
파일을 작성하는 동시에 JSON을 출력할 수 있습니다. 사람이 읽을 수 있는 모든 메시지는
--json 모드에서는 stderr로 이동하므로 stdout에는 항상 JSON 페이로드만 포함됩니다.
--sarif는 다른 보고서 형식과 함께 SARIF 2.1.0 보고서를 작성합니다. 표준
github/codeql-action/upload-sarif 액션으로 업로드하면 풀 리퀘스트와 보안 탭에서
결과가 직접 주석으로 표시됩니다:```yaml
name: Run DockSec uses: OWASP/[email protected] with: dockerfile: 'Dockerfile' sarif: 'true'
name: Upload SARIF to GitHub Code Scanning uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: ~/.docksec/results
> `if: always()`는 중요합니다. 이것이 없으면 `--fail-on`으로 인해 DockSec이 0이 아닌 종료 코드로 종료될 때마다 업로드 단계가 건너뛰어져서, 가장 중요한 순간에 결과가 유실됩니다.
### 기준선 / 래칫 모드
`--baseline FILE`을 사용하면 기존 프로젝트에서 `--fail-on`을 도입할 수 있으며,
기존에 발견된 수많은 문제가 모든 빌드를 막는 상황을 피할 수 있습니다. `--update-baseline`으로 한 번 실행하여
오늘의 발견 사항을 스냅샷으로 저장한 다음 기준선 파일을 커밋하세요. 이후부터는 `--fail-on`이
기준선에 아직 없는 발견 사항에 대해서만 게이트로 작동합니다:```bash
# Snapshot current findings (does not gate)
docksec -i myapp:latest --image-only --baseline .docksec-baseline.json --update-baseline
# Later runs only fail on NEW findings above the threshold
docksec -i myapp:latest --image-only --baseline .docksec-baseline.json --fail-on high
검출 결과는 취약점 ID, 대상, 패키지 이름으로 매칭되므로, 관련 없는 결과가 생기고 사라져도
기준선은 유효하게 유지됩니다. 현재 상태를 새 기준선으로 수용하려면 언제든
--update-baseline 옵션으로 다시 실행하세요.
--ignore-file FILE는 팀이 분류하고 수용한 개별 검출 결과를 억제합니다.
기준선(특정 시점의 스냅샷)과 달리, 무시 파일은 명시적이고 검토 가능한 목록으로,
모든 항목에는 사유와 선택적 만료 날짜가 포함됩니다.
현재 디렉터리에 .docksec-ignore.yml 파일이 있으면 자동으로
인식됩니다.```yaml
ignores:
억제된 발견 항목은 점수 산정, 보고서, `--json` 출력, 그리고
`--fail-on` 게이트 이전에 제거됩니다. 만료된 항목은 (경고와 함께) 자동으로 적용이 중지되며,
사유가 없는 항목은 플래그가 지정되어 면제(waiver) 항목이 감사 가능한 상태로 유지됩니다. 파일을
버전 관리에 커밋하여 억제 사항이 다른 변경 사항과 동일하게 검토되도록 하세요.
---
## 보고서
### 보고서 형식
기본적으로 모든 스캔은 4개의 보고서 파일을 작성합니다. `--format`을 사용하여 하위 집합을 선택하세요:
- **html**: 대화형이며 시각적으로 깔끔한 웹 보고서: 심각도 카드, 점수 등급, 수정 버전이 포함된 전체 취약점 테이블, 그리고 AI 발견 항목 전체.
- **pdf**: 휴대 가능하며 프레젠테이션에 바로 사용할 수 있는 문서.
- **json**: 기계가 읽을 수 있는 전체 스캔 데이터(`--json` stdout 출력과 동일한 형태).
- **csv**: 개별 취약점에 대한 스프레드시트 준비 테이블.
> CSV 동작 참고: 취약점이 0건이어도 DockSec은 헤더만 있는
> CSV(열 이름, 행 없음)를 계속 작성하므로 다운스트림 자동화가 누락된 파일이나
> 빈 파일로 인해 중단되지 않습니다. 이는 의도된 동작입니다.
### CycloneDX SBOM
`--sbom`은 스캔된 이미지의 CycloneDX 소프트웨어 자재 명세서(`<image>.cdx.json`)를
작성하며, 모든 패키지 구성 요소와 알려진 취약점을 나열합니다. BOM은
Trivy의 네이티브 익스포터에 의해 생성되므로(사양 준수) DockSec은 도구 메타데이터에 자신을
기록합니다. 이를 Dependency-Track, GitHub의 의존성 그래프, 또는 다른
SBOM 소비자에게 전달하세요:```bash
docksec --image-only -i myapp:latest --sbom
--sbom needs a single image (-i), so it is skipped for compose runs. Like --sarif,
it is independent of --format.
DockSec은 여러분의 시스템에서 무엇이 나가는지 항상 알 수 있도록 설계되었습니다:
--no-redact를 사용하세요.--provider ollama를 사용하여 AI 분석을 자체
하드웨어에서 유지하거나, --scan-only / --offline을 사용해 AI를 완전히 건너뛸 수 있습니다.--offline은 네트워크 접근 없이 스캔을 실행합니다. 이미 디스크에 있는 Trivy 취약점 데이터베이스를
사용하며(DB 업데이트 없음), 네트워크가 모두 필요한 AI 분석과 Docker Scout 고급 스캔을 건너t락니다.
이는 차단된(air-gapped) 또는 잠긴 환경에서 스캔하는 가장 간단한 방법입니다:```bash
docksec --image-only -i myapp:latest --offline
`--offline`에 의존하기 전에 Trivy DB가 최소 한 번은 다운로드되었는지 확인하세요(이전의 온라인 스캔이면
충족됩니다).
### 스캔 결과 캐시
이미지 스캔 결과는 기본적으로 24시간 동안 캐시되며(`DOCKSEC_CACHE_TTL_HOURS`로 재정의 가능),
이미지 콘텐츠 다이제스트를 키로 사용하므로 재사용된 `:latest` 같은 태그가 다시 빌드되어도
항상 새로 스캔됩니다. `--no-cache`(또는 `DOCKSEC_USE_CACHE=false`)를 사용하면
특정 실행에서 캐시를 우회할 수 있습니다.
---
## AI 어시스턴트 스킬 (`install-skill`)
`docksec install-skill`은 널리 사용되는 AI 코딩 어시스턴트의 잘 알려진 컨텍스트 파일에
DockSec 사용 지침을 작성하므로, 저장소에서 작업하는 어시스턴트가 DockSec을
호출하는 방법을 알 수 있습니다:```bash
docksec install-skill
다음을 생성하거나 업데이트합니다:
.claude/commands/docksec.md (Claude Code 슬래시 명령어 /docksec).cursor/rules/docksec.mdc (Cursor)AGENTS.md (Codex CLI), GEMINI.md (Gemini CLI).github/copilot-instructions.md (GitHub Copilot)이 파일들은 검토하고 커밋할 수 있는 일반 텍스트이며, 아무것도 실행되지 않습니다. 명령을 다시 실행하면 DockSec 섹션이 중복되지 않고 제자리에서 업데이트됩니다.
--fail-on 종료 코드, 베이스라인/래칫 모드, 감사 가능한 면제, JSON-to-stdout 및 Marketplace의 GitHub Action을 지원합니다.--offline).docksec install-skill은 Claude Code, Cursor, Copilot 등에 저장소에서 DockSec을 실행하는 방법을 알려줍니다.| 기능 | DockSec | Trivy (단독) | Snyk Container | Aikido |
|---|---|---|---|---|
| 라이선스 및 비용 | 무료, 오픈소스 (MIT) | 무료, 오픈소스 (Apache 2.0) | 상용 (제한된 무료 티어) | 상용 (제한된 무료 티어) |
| 거버넌스 | OWASP Lab 프로젝트, 벤더 중립적 | Aqua가 유지 관리하는 오픈소스 | 단일 벤더 | 단일 벤더 |
| CVE 및 Dockerfile 잘못된 구성 탐지 | 예 | 예 | 예 | 예 |
| 발견 사항을 알기 쉬운 언어로 설명 | 예 (AI가 작성한 맥락 및 영향) | 아니오 (원시 CVE 데이터) | 부분적 (심각도 및 수정 힌트) | 부분적 (플랫폼 내 AI 요약) |
| 상황에 맞는 Dockerfile 수정 | 예 (설명과 함께 구체적인 재작성) | 아니오 (탐지만 수행) | 예 (베이스 이미지 업그레이드 조언, 수정 PR) | 예 (AI AutoFix PR) |
| Docker Compose (다중 서비스) 스캐닝 | 예 (오케스트레이션 검사 및 서비스별 스캔) | 부분적 (구성 스캔, 서비스별 확장 없음) | 부분적 | 부분적 |
| 베이스라인 / 래칫 모드 (새로운 발견 사항에 대해서만 실패) | 예 | 아니오 | 부분적 (플랫폼 정책) | 부분적 (플랫폼 정책) |
| 이유 및 만료일이 있는 감사 가능한 발견 사항별 면제 | 예 | 부분적 (.trivyignore, 이유 강제되지 않음) | 부분적 (플랫폼 정책) | 부분적 (플랫폼 정책) |
| CI 네이티브 출력 (GitHub Code Scanning용 SARIF) | 예 | 예 | 예 | 예 |
| SBOM 내보내기 (CycloneDX) | 예 (--sbom) | 예 | 예 | 예 |
| AI 어시스턴트 스킬 설치 (Claude Code, Cursor, Copilot) | 예 (install-skill) | 아니오 | 아니오 | 아니오 |
| 완전 오프라인 / 분리 환경 실행 | 예 (Ollama를 통한 로컬 LLM, 스캔 전용 모드, API 키 불필요) | 스캔만 가능 (수정 계층 없음) | 아니오 (클라우드 플랫폼) | 아니오 (호스팅 플랫폼) |
| 이미지 데이터가 네트워크 내에 유지됨 | 예 | 예 | 아니오 | 아니오 |
| 자체 LLM / 모델 선택 | 예 (OpenAI, Anthropic, Gemini 또는 로컬 Ollama) | 해당 없음 | 아니오 (독점 AI) | 아니오 (독점 AI) |
| 자체 호스팅 가능, 플랫폼 배포 불필요 | 예 | 예 | 아니오 | 아니오 |
| 벤더 종속 | 없음 | 없음 | 예 | 예 |
| 보안 점수 (0-100) 및 다중 형식 보고서 | 예 | 부분적 (머신 형식, 수정 보고서 없음) | 부분적 (대시보드 보고서) | 부분적 (대시보드 보고서) |
DockSec은 이들 중 상황에 맞는 Dockerfile 수정 기능과 완전한 오픈소스, OWASP 관리, 로컬 실행 가능한 설계를 결합한 유일한 도구입니다. Snyk와 Aikido는 강력한 AI 수정 기능을 제공하지만, 데이터를 자사 서비스로 전송하는 상용 클라우드 플랫폼으로만 제공됩니다. Trivy는 오픈소스이고 로컬에서 실행되지만 탐지에서 멈추며 수정을 돕지 않습니다. DockSec은 수정 가이드와 데이터에 대한 완전한 통제권을 모두 비용 없이 필요로 하는 개발자와 규제 대상 또는 분리된 환경의 팀에게 그 공백을 메워줍니다.
DockSec의 향후 방향은 ROADMAP.md에서 확인할 수 있습니다: 로컬 Docker 데몬 없이 레지스트리 스캔, 저장소 수준 정책 구성 파일, Jenkins/GitLab/Azure DevOps 템플릿, 공식 컨테이너 이미지, Kubernetes 및 Helm 스캔 등입니다. 우선순위에 대한 피드백과 투표는 issues와 OWASP Slack에서 환영합니다.
DockSec은 커뮤니티 기여로 성장합니다. 개발자, 디자이너, 보안 애호가 등 누구든 참여할 수 있는 많은 방법이 있습니다:
DockSec은 컨테이너 보안을 누구나 접근할 수 있게 만드는 데 전념하는 전담 팀이 이끌고 있습니다:
여기에서 찾을 수 있습니다: