hermetoproject/hermeto

GitHub: hermetoproject/hermeto

Hermeto 是一个用于封闭式容器构建的依赖预获取工具,通过提前下载所有项目依赖并生成 SBOM 来实现可复现、可审计且网络隔离的安全构建流程。

Stars: 37 | Forks: 81

# Hermeto [![coverage badge]][hermeto coverage status] [![container badge]][hermeto container status] Hermeto 是一个 CLI 工具,它可以预获取项目的依赖项,以帮助 使您的构建过程实现 [hermetic][]。 要查看我们是否支持您的包管理器,请查看 [包管理器](#package-managers) 章节。 Hermeto 输出的主要预期用途是用于网络隔离的容器 构建。 ## 目录 - [目标](#goals) - [安装](#installation) - [基本用法](#basic-usage) - [配置](#configuration) - [包管理器](#package-managers) - [项目状态](#project-status) ## 目标 请注意,Hermeto 相当挑剔,旨在 - 鼓励或强制执行最佳实践 - 从不执行任意代码 [^pip-download-example] - 保持实现简单 为了与 Hermeto 很好地配合,您项目的构建过程必须是 - **Defined(已定义)** - Hermeto 仅获取明确声明的依赖项 - 通常位于您的包管理器生成的 lockfile 中。 - **Reproducible(可复现)** - 如果依赖项未 固定到确切版本,Hermeto 将拒绝获取。这同样适用于传递依赖项(并且 与“已定义”点相关联)。大多数包管理器 会在 lockfile 中自动固定所有依赖项。 - **Secure(安全)** - 即使有 lockfile,您的构建也并非真正免受供应链 攻击,除非您验证所有依赖项的校验和。如果您的 包管理器支持指定预期的校验和,我们强烈 鼓励您使用它们。 ⚠ Hermeto 将验证校验和(如果存在),但默认不要求它们。这可能会在未来发生变化。 作为回报,Hermeto 将帮助使您的构建 - **Auditable(可审计)** - 通过生成包含所有进入 您构建的依赖项的清单。 实现目标的能力取决于构建过程是 *hermetic(封闭式)* 的。 理想情况下,您应该尝试将构建与互联网和 底层主机系统隔离,以避免隐式依赖项、不可复现的行为 以及各种其他问题。Hermeto 本身不是一个封闭式构建系统。 我们建议您利用现有技术(例如容器)来 实现网络隔离。 ## 安装 ### 独立版 我们目前不分发 Hermeto 作为独立包。 要在本地开发中安装 Hermeto,请参阅 CONTRIBUTING.md。 ### 容器镜像 [![container badge]][hermeto container status] ``` ghcr.io/hermetoproject/hermeto ``` 您可能希望设置一个别名以便本地使用更方便 ``` alias hermeto='podman run --rm -ti -v "$PWD:$PWD:z" -w "$PWD" ghcr.io/hermetoproject/hermeto:latest' ``` 请注意,该别名挂载了当前工作目录 —— 容器将 有权访问该目录中的文件,但不能访问其他任何地方。 ## 基本用法 ``` hermeto fetch-deps \ --source ./my-repo \ --output ./hermeto-output \ --sbom-output-type cyclonedx \ gomod ``` `fetch-deps` 命令获取您项目的依赖项并将它们存储在 您的磁盘上。Hermeto 还会生成一个详细的 SBOM,其中包含关于 所有项目组件和包的信息。您可以在输出 目录中找到 SBOM。 有关 Hermeto 用法的更详细、实用的示例,请参阅 `docs/usage.md`。 您可能还想查看 `hermeto --help` 以及 可用子命令的 `--help` 文本。 ## 配置 ### 模式 Hermeto 可以使用全局 CLI 选项 `--mode` 在两种模式下运行。 - strict - permissive 默认模式是 `strict`。在此模式下,*部分* 未满足的输入要求会被 视为错误。另一方面,`permissive` 模式将 它们视为警告。这意味着 Hermeto 将继续并生成 SBOM,但 它可能不完整或不准确。 permissive 模式当前可以抑制以下情况: - go `vendor` 目录不一致(有关 vendoring 信息,请参阅 `docs/gomod.md`) - cargo manifest 文件 `Cargo.toml` 与 `Cargo.lock` 不同步 ### 设置 可以通过以下来源提供设置(优先级从高到低): 1. **环境变量**:带有 `HERMETO_` 前缀,使用 `__` 表示嵌套 设置(例如 `HERMETO_GOMOD__DOWNLOAD_MAX_TRIES=10`) 2. **CLI 选项**:`--config-file path/to/config.yaml` 3. **配置文件**(如果存在则自动加载):`~/.config/hermeto/config.yaml`, `hermeto.yaml`, `.hermeto.yaml` 指定的任何设置都将覆盖 [config.py][] 模块中存在的默认值。 配置文件唯一支持的格式是 YAML。 - `gomod.download_max_tries` go 命令的最大重试次数。 - `gomod.environment_variables` gomod 的默认环境变量。 - `gomod.proxy_url` 设置 Hermeto 在 下载 Go 模块时内部使用的 GOPROXY 变量。请参阅 [Go 环境变量][]。 - `http.connect_timeout` HTTP 请求的连接超时(秒) (默认值:30)。 - `http.read_timeout` HTTP 请求的读取超时(秒)(默认值:300)。 只要字节持续流动,长时间运行的下载可以花费任意长的时间。 - `http.timeout`(已弃用)自动迁移到 `http.read_timeout`。 - `runtime.concurrency_limit` 最大并发操作数。 - `runtime.subprocess_timeout` 子进程命令的超时(秒)。 ## 包管理器 | 包管理器 | 生态系统 | |-----------------------------|------------| | [bundler](#bundler) | Ruby | | [cargo](#cargo) | Rust | | [generic](#generic-fetcher) | N/A | | [gomod](#gomod) | Go | | [npm](#npm) | JavaScript | | [pip](#pip) | Python | | [rpm](#rpm) | RPM | | [yarn](#yarn) | JavaScript | ### [bundler][] Hermeto 通过解析源代码仓库中存在的 [Gemfile.lock][] 文件并下载声明的依赖项来支持 bundler。 要生成 lockfile 或确保文件是最新的,例如您可以使用 `bundle lock` 命令,该命令根据 [Gemfile][] 中指定的依赖项生成 `Gemfile.lock` 文件。 两个文件都必须存在于源代码仓库中,因此您应该将它们检入您的 git 仓库。 有关更多详细信息,请参阅 docs/bundler.md。 ### [cargo][] Hermeto 通过调用 Cargo CLI 来支持 Cargo,以获取项目中声明的 Rust 依赖项,从而通过显式定义的版本确保可复现的构建。 请确保您的项目中存在最新的 [Cargo.lock][]。 有关更多详细信息,请参阅 docs/cargo.md。 ### 通用 fetcher generic fetcher 是 Hermeto 支持预获取不适合其他包管理器的任意文件的一种方式。使用 generic fetcher,您可以轻松地使用 Hermeto 获取这些文件以及您其他特定语言的依赖项,满足封闭式构建条件,并将它们记录在 SBOM 中。 Hermeto 使用一个名为 `artifacts.lock.yaml` 的简单自定义 lockfile,该文件 预期存在于仓库中,或以 JSON 输入提供。 lockfile 描述了下载文件的 URL、校验和和输出文件名。 当前支持的工件类型 - 任意文件 - Maven artifacts 有关更多详细信息,请参阅 docs/generic.md。 ### [gomod][] 当前版本:1.25 [^2] [^3] gomod 包管理器通过解析源代码仓库中存在的 [go.mod][] 文件来工作,以确定要下载哪些依赖项。Hermeto 不会 自己解析此文件 —— 相反,我们依赖 `go` 命令来下载并列出所需的依赖项。 从 Go 1.17 开始,go.mod 文件包含应用程序所有传递所需的依赖项 —— 请参阅 [Go 1.17 更新日志][] 中关于 *Pruned module graphs* 的章节。 在以前的 Go 版本中,go.mod 文件仅 包含直接依赖项。得益于 Go 的向后兼容性 [^3],Hermeto 确实支持为早期版本下载并列出所有传递依赖项。请注意,在您的项目中使用 Go >= 1.17 具有 下载更少依赖项的额外好处(如更新日志中所述),在某些 情况下效果显著。 有关更多详细信息,请参阅 docs/gomod.md。 ### [npm][] Hermeto 通过解析源代码仓库中存在的 [package-lock.json][] 文件并下载声明的依赖项来支持 npm。 要生成 lockfile 或确保文件是最新的,您可以使用 [npm install][]。 请确保 lockfile 版本高于 v1(Node.js 15 或更高版本)。 有关更多详细信息,请参阅 docs/npm.md。 ### [pip][] Hermeto 通过解析源代码仓库中存在的 [requirements.txt][] 文件并下载声明的依赖项来支持 pip。 这些文件必须是 lockfile,即声明所有传递依赖项并将它们固定到特定版本。生成此类 lockfile 最好使用像 [pip-compile][] 这样的工具。 我们支持源分发包格式 ([sdist][]) 以及二进制 分发包格式 ([wheel][])。 有关更多详细信息,请参阅 docs/pip.md。 ### [rpm][] Hermeto 通过解析源代码仓库中存在的 `rpms.lock.yaml` 文件并下载声明的依赖项来支持 rpm。要生成此 YAML “lockfile”,目前只能使用 [rpm-lockfile-prototype][] 来完成这项工作。 有关更多详细信息,请参阅 docs/rpm.md。 ### [yarn][] 当前版本:v4 与 NPM 不同,hermeto 仅仅驱动底层的 `yarn` CLI 命令操作, 也就是说,hermeto 将大部分繁重工作留给 Yarn 本身,它主要 专注于后处理验证。请注意,将 Yarn lockfile (`yarn.lock`) 检入仓库对于 hermeto 成功处理 项目至关重要。如果缺失,您可以通过运行 [yarn install][] 轻松生成一个,然后再将 hermeto 指向您的项目。 有关更多详细信息,请参阅 docs/yarn.md。 ## 项目状态 Hermeto 源自(但不是直接分叉)[Cachito][]。 [^pip-download-example]: 例如,请参阅此 [python.org 讨论][] [^2]: Hermeto 期望在下载依赖项时使用特定版本的 `go` 命令。这是安装在 [hermeto container](#container-image) 中的版本。如果您在本地(容器外)使用不同的 Go 版本 运行 Hermeto,我们不保证正确性。 您*可以*自由使用不同的版本来构建您的项目。 [^3]: `go` 命令承诺与以前的 版本向后兼容。如果您的 go.mod 文件指定了预期的 go 版本,Hermeto 应该适当地处理它。如果您的 go 版本比 Hermeto 使用的版本*高*,只要 两个版本之间的依赖项解析没有改变,无论 如何它很有可能是兼容的。 例如,依赖项解析在 [Go 1.18][] 中确实发生了变化,但在 [Go 1.19][] 中没有。情况在 [Go 1.21][] 中稍微复杂一些,如果您正在或 一直遇到与 Go 1.21+ 相关的 hermeto 问题,请参阅 我们的 gomod 文档以获取更多详细信息。
标签:Bundler, DevSecOps, DNS 反向解析, Go, npm, Python, Ruby工具, SBOM, SOC Prime, Yarn, 上游代理, 依赖管理, 包管理器, 可重现构建, 审计, 容器构建, 封闭构建, 开发工具, 提示词模板, 文档安全, 无后门, 无网络构建, 构建隔离, 校验和验证, 硬件无关, 统一API, 网络信息收集, 网络安全, 请求拦截, 跌倒检测, 软件物料清单, 逆向工具, 隐私保护, 预获取