DockSec 是一个 OWASP 实验室项目,旨在弥合复杂安全扫描结果与可操作的开发者修复方案之间的鸿沟。它将行业标准扫描器(Trivy、Hadolint、Docker Scout)与 AI 相结合,提供具有上下文感知能力的安全分析。
DockSec 不会用 200 多个 CVE 的列表让你不知所措,而是:
所有扫描均在本地进行;唯一会离开你机器的内容,是发送给你所选 AI 提供商的(已脱敏处理秘密信息的)文件内容——而如果使用本地模型或仅扫描模式,则任何内容都不会离开你的机器。请参阅数据流与隐私。
DockSec 工作流程:从扫描到可操作的洞察
DockSec 遵循四阶段流水线:
DockSec 负责编排本地扫描器,因此需要:
或者让 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 安全评分、一个“快速要点”操作块、生成的报告(默认保存到 `~/.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`),然后向上遍历至仓库根目录,因此 monorepo 子目录中的服务会继承顶层提交的策略。搜索会在包含 `.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 编辑器中提供补全及内联校验。该 schema 发布在 [`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 友好的退出码,以便构建和 Shell 能对结果作出响应:
| 代码 | 含义 |
|---|---|
| `0` | 成功,没有达到或超过 `--fail-on` 的发现项 |
| `1` | 存在达到或超过 `--fail-on` 阈值的发现项 |
| `2` | 用法或参数错误 |
| `3` | 工具或运行时错误(扫描失败、镜像未找到、缺少工具) |
`--fail-on` 基于结构化发现项(镜像漏洞和 compose 配置错误)进行门禁。当 `--fail-on` 低于所请求的 `--severity` 时,扫描严重性会自动放宽,以便门禁能观察到这些发现项。
### 机器可读输出
`--json` 会将单个 JSON 对象打印到标准输出(扫描信息、漏洞、严重性计数以及任何 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 操作上传该报告,从而在拉取请求以及 Security 选项卡中直接看到带注释的发现结果:```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 以非零状态退出时,上传步骤会被跳过,而这恰恰是在最需要结果的时候丢失了发现。
### 基线 / 棘轮模式
`--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` 门控之前被移除。过期的条目会自动停止生效(并附带警告),而没有原因的条目会被标记出来,以确保豁免保持可审计性。将该文件提交到版本控制中,这样抑制操作就能像其他任何更改一样接受审查。
---
## 报告
### 报告格式
默认情况下,每次扫描都会生成四个报告文件;使用 `--format` 来选择子集:
- **html**:一份交互式、视觉简洁的网页报告:严重性卡片、评分评级、包含修复版本的完整漏洞表,以及完整的 AI 发现。
- **pdf**:一份便携、适合演示的文档。
- **json**:完整的、机器可读的扫描数据(与 `--json` 标准输出格式相同)。
- **csv**:一份适合电子表格处理的单个漏洞表。
> 关于 CSV 行为的说明:当漏洞为零时,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 需要单个镜像(-i),因此 compose 运行时会跳过它。与 --sarif 一样,它独立于 --format。
DockSec 的设计确保你始终清楚哪些数据会离开你的机器:
--no-redact 可选择退出。--provider ollama 可将 AI 分析保留在你自己的硬件上,或使用 --scan-only / --offline 完全跳过 AI。--offline 在无网络访问的情况下运行扫描。它使用磁盘上已有的 Trivy 漏洞数据库(不进行数据库更新),并跳过 AI 分析和 Docker Scout 高级扫描(这两者都需要网络)。这是在气隙或锁定环境中进行扫描的最简单方式:```bash
docksec --image-only -i myapp:latest --offline
确保 Trivy DB 至少已下载过一次(任何先前的在线扫描都会完成此操作),然后再依赖 `--offline`。
### 扫描结果缓存
镜像扫描结果会被缓存(默认:24 小时,可通过 `DOCKSEC_CACHE_TTL_HOURS` 覆盖),并以镜像的内容摘要为键,因此重新构建的标签(例如复用的 `:latest`)始终会获得全新的扫描。使用 `--no-cache`(或 `DOCKSEC_USE_CACHE=false`)可在单次运行中绕过缓存。
---
## AI 助手技能(`install-skill`)
`docksec install-skill` 会将 DockSec 的使用说明写入主流 AI 编程助手的知名上下文文件中,以便在您的仓库中工作的助手知道如何调用 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 输出到 stdout,以及 Marketplace 上的 GitHub Action。--offline)。docksec install-skill 可教会 Claude Code、Cursor、Copilot 等工具如何在你的仓库中运行 DockSec。DockSec 是这些工具中唯一将上下文相关的 Dockerfile 修复与完全开源、由 OWASP 治理、可本地运行的设计相结合的方案。Snyk 和 Aikido 提供强大的 AI 修复能力,但仅限于商业云平台,需要将你的数据发送到其服务。Trivy 是开源且本地的,但止步于检测,不会帮你修复任何问题。DockSec 填补了这一空白,为开发者以及受监管或隔离网络的团队提供修复指导和数据的完全控制权,且完全免费。
有关 DockSec 的未来方向,请参阅 ROADMAP.md:无需本地 Docker 守护进程的镜像仓库扫描、仓库级策略配置文件、Jenkins/GitLab/Azure DevOps 模板、官方容器镜像、Kubernetes 和 Helm 扫描等。欢迎在 issues 和 OWASP Slack 中提供反馈并投票确定优先级。
DockSec 的发展离不开社区贡献。无论你是开发者、设计师还是安全爱好者,都有很多参与方式:
DockSec 由一支致力于让容器安全更易用的专职团队领导:
在这里找到我们:
| 要求 | 用途 | 安装 |
|---|
| Python 3.12+ | DockSec 本身 | python.org |
| Trivy | 所有扫描(必需) | brew install trivy 或 Trivy 文档 |
| Hadolint | Dockerfile 代码检查 | brew install hadolint 或 Hadolint 文档 |
| Docker | 镜像扫描(-i) | Docker 文档 |
| 能力 | DockSec | Trivy(独立使用) | Snyk Container | Aikido |
|---|
| 许可证和成本 | 免费,开源(MIT) | 免费,开源(Apache 2.0) | 商业(有限免费层) | 商业(有限免费层) |
| 治理 | OWASP 实验室项目,厂商中立 | 开源,由 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)和多格式报告 | 是 | 部分(机器格式,无修复报告) | 部分(仪表板报告) | 部分(仪表板报告) |