GilsStudio/mhelm

GitHub: GilsStudio/mhelm

一款面向供应链安全的 Helm chart 全链路镜像工具,能自动发现并同步 chart 引用的所有容器镜像,同时提供签名验证、SLSA 来源证明、SBOM 生成和漂移检测等完整可审计能力。

Stars: 0 | Forks: 0

# mhelm **mhelm = Mirror HELM。** 一个供应链安全的镜像工具,用于镜像单个 Helm chart 及其引用的所有容器镜像。CLI 负责脚手架搭建和准备工作;GitHub Action 执行实际的镜像操作,对每个构件进行签名,并附加 SLSA + MirrorProvenance,以及为镜像生成 SBOM 和漏洞扫描报告。 ## 为什么 镜像一个 chart 不仅仅是复制一个 `.tgz` 文件。一个真正的平台镜像需要: - 通过摘要保留 chart 字节, - 发现并镜像 chart 引用的每一个容器镜像, - 提供指向镜像地址的 `helm install` 覆盖值, - 在复制前验证上游签名, - 使用你的 CI 身份对下游构件重新签名, - 为每个构件提供 SLSA 构建来源 + 自定义的 MirrorProvenance 证明,以及为每个镜像提供 SBOM + 漏洞扫描, - 针对上游轮换和下游篡改进行持续的漂移检测。 mhelm 将这一切交由 git 中的锁文件(`chart-lock.json`)作为事实来源来完成管理——每一次更改都是一个可审查的 PR。 ## 架构 两个信任区域: | 区域 | 位置 | 功能 | 凭据 | |---|---|---|---| | **CLI** (`mhelm`) | 开发者笔记本电脑 | 脚手架规范,发现镜像,验证上游签名,检查漂移。**仅网络只读。** | 无 | | **Action** | GitHub Actions 运行器 | 镜像 chart + 镜像,cosign 签名,证明,提交锁文件更新。 | 仅限 GHA 环境 OIDC | 签名密钥永远不会接触到开发者的笔记本电脑。每一个镜像操作都是一个针对 `chart-lock.json` 的可审查差异。 ## 快速入门 — 添加你的第一个 chart 你在笔记本电脑上进行准备(仅限网络只读,无凭据);CI 执行镜像和签名(环境 OIDC,你的机器上没有密钥)。一个 chart = 一个目录。 ``` LAPTOP — read-only, no credentials CI — writes + signs (OIDC) ───────────────────────────────── ────────────────────────────── 1 mhelm init scaffold 6 merge to main → mirror.yml: 2 edit chart.json + helm/values.yml discover→verify→mirror→wrap 3 mhelm discover → lock + values →provenance→slsa→sign+attest 4 mhelm discover --check (exit 0) auto-commits lockfile back 5 commit + PR ──dry-run gate──▶ 7 drift.yml nightly → PR on drift 8 release print-install | bash ``` 1. **搭建脚手架**:使用初始的 `chart.json` + `helm/values.yml` 创建 chart 目录: mhelm init platform/cilium \ --upstream-type oci \ --upstream-url oci://quay.io/cilium/charts/cilium \ --upstream-version 1.19.3 \ --downstream-url oci://ghcr.io/myorg/mirror 对于经典的 HTTP Helm 仓库,请使用带 `--upstream-name ` 的 `--upstream-type repo` 以及 `https://` 的 `--upstream-url`。 2. **配置** `platform/cilium/chart.json`:添加 `mirror.discoveryValues`,任何发现过程无法自动找到的 `mirror.extraImages`,`mirror.verify` / `mirror.vulnPolicy`,以及可选的 `wrap` / `release` 部分。将用于部署塑形的 Helm values 放在 `platform/cilium/helm/values.yml` 中。逐字段参考:[`chart.json` schema](#chartjson-schema)。完整示例:[`examples/cilium/`](examples/cilium/) ([`chart.json`](examples/cilium/chart.json))。 3. **发现** — 渲染 chart 并锁定每一个镜像(只读): mhelm discover platform/cilium 生成 `chart-lock.json`(事实来源)和 `image-values.yaml`(`helm install --values` 的覆盖文件)。这两个文件都需要提交。 4. **健全性检查** — `mhelm discover --check platform/cilium` 必须以状态码 `0` 退出。这是 CI 强制执行的准确关卡;状态码为 `2` 表示锁文件已过期 — 需重新执行步骤 3。可选执行 `mhelm verify platform/cilium`,以便在推送前检查上游签名状况。 5. **提交并开启 PR** — 提交 `chart.json`、`chart-lock.json`、`image-values.yaml`。使用 **`dry-run`** 模式的 Action(`command: dry-run` → `discover --check` + `verify`,无写入/签名/提交操作)为 PR 设置关卡:过期的锁文件将无法通过检查,从而强制要求在合并前生成新的发现输出。这是步骤 4 在 CI 中的对应操作,由 [`dry-run.yml`](examples/workflows/dry-run.yml) 接入。 6. **合并 → CI 执行镜像。** 当 `chart.json` 的修改变更进入你的默认分支时,[`mirror.yml`](examples/workflows/mirror.yml)(一个 `platform/**/chart.json` 矩阵)将运行完整的流水线 — discover → verify → mirror → wrap → provenance → slsa → cosign sign + attest (SBOM / 漏洞扫描 / SLSA / MirrorProvenance) — 将 chart 及其所有镜像推送到你的下游 registry,然后开启一个包含更新后的 `chart-lock.json` / `image-values.yaml` / `mirror-provenance.json` 的 PR(审查摘要差异,合并以在 git 中记录镜像操作)。详情:[规范的 CI 流程](#canonical-ci-sequence),[GitHub Action](#github-action)。 7. **持续漂移检测。** [`drift.yml`](examples/workflows/drift.yml) 每晚运行,并在发生上游轮换、下游篡改或出现新的上游版本时,为每个 chart 开启一个 PR。审查它,提升 `mirror.upstream.version`,循环将返回到步骤 3。 8. **部署** — 为已锁定的构件生成一个可运行的安装命令(当设置了 `wrap` 时为 wrapper chart,否则为裸镜像 chart + `image-values.yaml`): mhelm release print-install platform/cilium | bash **接入 CI:** 将 [`dry-run.yml`](examples/workflows/dry-run.yml)(步骤 5 的 PR 关卡)、[`mirror.yml`](examples/workflows/mirror.yml) 和 [`drift.yml`](examples/workflows/drift.yml) 从 [`examples/workflows/`](examples/workflows/) 复制到 `.github/workflows/`,然后调整 chart 矩阵和 `downstream.url`。步骤 1–5 是唯一需要人工介入的循环;变更合并之后的所有操作都是自动化的,并且可通过 git diffs 进行审计。 ## 文件 | 文件 | 生成者 | 是否提交 | 作用 | |---|---|---|---| | `chart.json` | 用户 | 是 | 输入规范 (`apiVersion: mhelm.io/v1alpha1`):`mirror`(upstream/downstream/discoveryValues/extraImages/verify/vulnPolicy),可选 `wrap`,可选 `release` | | `chart-lock.json` | CLI + Action | 是 | 事实来源:chart 摘要,镜像列表 + 每个镜像的 source/digest/values-paths/signature/downstream,漂移记录 | | `image-values.yaml` | `mhelm discover` | 是 | 稀疏的 `helm install --values` 覆盖,将每个匹配的 values 路径指向镜像(配置了 `wrap` 部分时跳过) | | `mirror-provenance.json` | `mhelm provenance` | (CI 构件) | 提供给 `cosign attest` 的自定义 `mhelm.dev/MirrorProvenance/v1` 断言 | | `slsa-provenance.json` | `mhelm slsa` | (CI 构件) | 提供给 `cosign attest --type slsaprovenance1` 的 SLSA v1 构建来源断言 | Cargo.toml ↔ Cargo.lock 模式。每个 `chart.json` / `chart-lock.json` 对应一个 chart。多 chart 编排是用户的责任(在 CI 中使用一个 `**/**/chart.json` 矩阵)。 ### 推荐布局 将所有 Helm values 文件保存在 `chart.json` 旁边的 `helm/` 子目录中, 以便 `mirror.discoveryValues`、`wrap.valuesFiles` 和 `release.valuesFiles` 都引用 `helm/…` —— 这是唯一可以 grep “我们正在应用什么覆盖” 的地方,且在 `chart.json` 中具有统一的路径: ``` platform/cilium/ ├── chart.json ├── chart-lock.json ├── image-values.yaml # generated by `mhelm discover` └── helm/ ├── values.yml # discoveryValues + wrap/release valuesFiles └── install-overrides.yml # optional opt-in overlay ``` `mhelm init` 会搭建 `helm/values.yml` 并预先填充 `mirror.discoveryValues: ["helm/values.yml"]`,以便使用者默认遵循此约定。 ## `chart.json` schema `apiVersion: mhelm.io/v1alpha1`。扁平的 v0.1.0 结构(没有 `apiVersion`, 顶层的 `upstream`/`downstream`/`valuesFiles`/`trustedIdentities`)仍 会在内存中自动迁移并附带 stderr 警告,但编写新文件时 请使用嵌套形式: ``` { "apiVersion": "mhelm.io/v1alpha1", "mirror": { "upstream": { "type": "repo", "url": "https://charts.jetstack.io", "name": "cert-manager", "version": "v1.17.0" }, "downstream": { "type": "oci", "url": "oci://ghcr.io/myorg/mirror" }, "discoveryValues": ["helm/values.yml"], "extraImages": [ { "ref": "quay.io/cephcsi/cephcsi:v3.12.2", "valuesPath": "csi.cephcsi.image" } ], "verify": { "trustedIdentities": [ { "subjectRegex": "https://github.com/cert-manager/.*", "issuer": "https://token.actions.githubusercontent.com" } ], "allowUnsigned": ["cilium/hubble-ui"] }, "vulnPolicy": { "failOn": "critical", "allowlist": [ { "cve": "CVE-2024-1234", "expires": "2026-12-31", "reason": "tracked upstream; no patch yet" } ] } }, "wrap": { "version": "v1.17.0-myorg.1", "valuesFiles": ["helm/values.yml"], "extraManifests": [] }, "release": { "name": "cert-manager", "namespace": "cert-manager", "valuesFiles": ["helm/install-overrides.yml"] } } ``` | 字段 | 是否必填 | 描述 | |---|---|---| | `apiVersion` | 是 | `mhelm.io/v1alpha1`(空 = 遗留的 v0.1.0 自动迁移)。 | | `mirror.upstream.type` | 是 | `repo`(经典 HTTP Helm 仓库)或 `oci`。 | | `mirror.upstream.url` | 是 | 仓库基础 URL,或 **完整的** `oci://registry/path/chart` 引用。 | | `mirror.upstream.name` | 仅限 `type=repo` | Chart 名称。对于 `oci` 会被拒绝 — 请将完整的 chart 路径放在 `url` 中。 | | `mirror.upstream.version` | 是 | Semver(repo)或 tag(oci)。 | | `mirror.downstream.type` | 是 | `oci`(仅支持 OCI 目标)。 | | `mirror.downstream.url` | 是 | **不带** chart 名称的目标 registry 路径。mhelm 会在其下命名空间化构件:`charts/`(原样复制),`platform/`(wrapper),`images/`(每个镜像)。 | | `mirror.discoveryValues` | 否 | 在 `discover` 期间按顺序合并的 YAML 文件,以便渲染后的清单与你部署的内容相匹配。 | | `mirror.extraImages` | 否 | 手动指定的列表 `[{ref, valuesPath?, overridePath?, reason?}]`,用于发现过程无法自动找到的镜像。`overridePath` 会将整个锁定的引用作为单个字符串输出(例如 cilium 的 `image.override`)。 | | `mirror.verify.trustedIdentities` | 否 | `mhelm verify` 的允许列表。设置后,仅接受匹配的 cosign 签名。 | | `mirror.verify.allowUnsigned` | 否 | 豁免验证的仓库路径(记录为 `type=allowlisted`)。 | | `mirror.vulnPolicy` | 否 | 用于 `mhelm vuln-gate` 的 `failOn`(`critical`/`high`/`medium`/`never`)+ `allowlist[{cve,expires,reason}]`。 | | `wrap` | 否 | 创作一个依赖于镜像的 wrapper chart(`version`,`valuesFiles`,`extraManifests`)。wrapper 在 `platform/` 命名空间下复用被镜像 chart 的名称;`version` 是可选的(默认为被镜像 chart 的版本 — 设置它可以独立地重新发布)。镜像重写将从锁文件中自动推导。 | | `release` | 否 | 用于 `mhelm release print-install` 的部署时便利设置(`name`,`namespace`,`valuesFiles`)。 | ## 命令 ``` mhelm init [dir] scaffold chart.json + helm/values.yml stub mhelm discover [dir] pull chart, render, extract images, resolve digests, write chart-lock.json + image-values.yaml mhelm discover --check [dir] compute artifacts but don't write; exit 2 if they would change (PR gate) mhelm verify [dir] cosign-verify every upstream image; record signature data in chart-lock.json (--strict to fail) mhelm mirror [dir] push chart + every image to downstream OCI; record downstream refs/digests mhelm wrap [dir] author + push a wrapper chart depending on the mirror (no-op without a wrap section) mhelm release init [dir] scaffold the chart.json release section mhelm release print-install [dir] emit a runnable `helm upgrade --install` against the locked artifact mhelm provenance [dir] write mirror-provenance.json (custom MirrorProvenance predicate) mhelm slsa [dir] write slsa-provenance.json (SLSA v1 build provenance predicate) mhelm vuln-gate [dir] apply chart.json#mirror.vulnPolicy to a grype cosign-vuln report mhelm refs [dir] print downstream ref@digest lines (--with-upstream pairs, --json, --chart-only, --images-only) mhelm drift [dir] detect upstream rotation, downstream tampering, new upstream versions mhelm version print the mhelm version (git-tag derived) ``` 所有命令都接受一个可选的 `[dir]` 位置参数(默认为 `.`)— 即包含 `chart.json` 的目录。如果目录不存在,`init` 会创建该目录。 ### 规范的 CI 流程 ``` mhelm discover → images, digests, values paths, source labels mhelm verify → upstream signatures mhelm mirror → push chart + images; downstream digests mhelm wrap → author + push wrapper chart (when a wrap section is set) mhelm provenance → MirrorProvenance predicate mhelm slsa → SLSA v1 predicate mhelm refs → ref@digest lines feeding cosign sign + attest cosign sign + attest (SBOM via syft, vuln via grype, SLSA, MirrorProvenance) [GHA only] mhelm drift (scheduled) → drift records committed via PR ``` `discover`、`verify`、`provenance`、`slsa`、`refs`、`drift` 都是网络只读的。`mirror` 执行 registry 写入操作。`cosign sign + attest` 仅在带有环境 OIDC 的 CI 中运行。 ## 镜像发现来源 每个 `chart-lock.json` 的镜像条目都带有一个 `source` 标签,以便审查人员可以审计其来源: | 来源 | 模式 | |---|---| | `manifest` | 来自渲染后 K8s 清单中的 `containers[].image` / `initContainers[].image` | | `annotation` | `Chart.yaml` 中的 `artifacthub.io/images` | | `env` | `containers[].env[].value`(正则表达式匹配,registry 已验证) | | `configmap` | 任何 ConfigMap `data` 的值(正则表达式匹配,registry 已验证) | | `crd-spec` | 任何非内置 Kind 中的字符串(正则表达式匹配,registry 已验证) | | `manual` | `chart.json#extraImages` | 通过正则表达式发现的候选对象只有在 `crane.Digest` 确认它们可被拉取时,才会进入锁文件。随机生成的碰巧看起来像引用的字符串将被过滤掉。受信任的来源(`manifest`、`annotation`、`manual`)无论 registry 解析结果如何都会被保留;不受信任的来源(`env`、`configmap`、`crd-spec`)在失败时将被丢弃。 已针对 cert-manager、cilium、rook-ceph(8 个镜像 — 1 个 manifest + 7 个 ConfigMap)、rook-ceph-cluster(1 个镜像 — CRD spec)、argocd、cnpg 进行了冒烟验证。 ## GitHub Action 仓库根目录中的 `action.yml` 发布了一个复合 Action,可在单个步骤中运行完整流水线。 最小化的使用者工作流: ``` permissions: contents: write # commit lockfile updates back packages: write # push to ghcr.io id-token: write # cosign keyless OIDC jobs: mirror: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: gilsstudio/mhelm@v0.6.0 with: dir: platform/cert-manager ``` ### 输入 | 输入 | 默认值 | 描述 | |---|---|---| | `dir` | (必填) | 包含 `chart.json` 的目录,相对于 checkout 根目录。 | | `command` | `mirror` | `mirror`(完整流水线),`dry-run`(仅限 `discover --check` + `verify` — 不执行 mirror/sign/commit;如果锁文件过期则失败),或 `drift`(只读的差异检查)。 | | `cosign-version` | `v2.6.3` | 要安装的 cosign 版本。 | | `sign` | `true` | 镜像模式:对所有下游构件进行签名 + 证明。 | | `verify` | `true` | 镜像/dry-run 模式:在 discover 和 mirror 之间运行 `mhelm verify`。 | | `strict-verify` | `false` | 当上游镜像未被验证时失败 — 包括 `unreachable`(信任根 / registry 被阻止)。离线运行器必须提供离线信任根或将此设置为 `false`。 | | `copy-upstream-attestations` | `true` | 镜像模式:将上游的 cosign 签名 + 证明转发到下游 registry。尽力而为。 | | `drift-exit-zero` | `true` | 漂移模式:发现问题时以代码 0 退出(对 PR 友好)。设为 `false` 可使作业失败。 | 输出:`lockfile`、`mirror-values`(生成的 `image-values.yaml` 的路径;保留此输出 id 以实现向后兼容)、`provenance` — 生成文件的绝对路径。在 `dry-run` 模式下为空(未写入任何构件)。 ### 每构件证明链 当 `sign=true` 时,**每一个**下游构件(被镜像的 chart、可选的 wrapper chart,以及每一个镜像)都会获得: 1. **cosign 签名** — 通过 Fulcio + Rekor 的无密钥签名(环境 GHA OIDC)。 2. **转发的上游证明** — 通过 `cosign copy --force` 从上游 registry 复制,尽力而为。 3. **SLSA v1 构建来源** — 来自 `slsa-provenance.json` → `cosign attest --type slsaprovenance1`。 4. **MirrorProvenance** — 来自 `mirror-provenance.json` → `cosign attest --type https://mhelm.dev/MirrorProvenance/v1`。 **镜像额外**会获得: 5. **CycloneDX SBOM** — `syft ` → `cosign attest --type cyclonedx`。 6. **漏洞报告** — `grype -o cosign-vuln` → `cosign attest --type vuln`(cosign vuln/v1 schema),在证明前由 `chart.json#mirror.vulnPolicy` 进行关卡检查。 chart 和 wrapper 是 Helm OCI 构件(`application/vnd.cncf.helm.*` 媒体类型),syft/grype 无法对其进行编目,因此它们仅接收签名 + SLSA + MirrorProvenance — chart 的模板化 YAML 没有对应的包 SBOM。 所有证明都作为以构件清单摘要为键的 OCI referrers 存储,并记录到 Rekor。 ### 示例工作流 - [`examples/workflows/mirror.yml`](examples/workflows/mirror.yml) — 带有自动提交的多 chart 矩阵镜像。 - [`examples/workflows/drift.yml`](examples/workflows/drift.yml) — 每晚漂移检查,为每个发现的 chart 开启一个 PR。 ## SLSA 立场 **镜像操作可以达到 SLSA L3 级别**(通过 Action 运行时): - 来源由构建平台(GHA)生成,而非用户代码。 - 不可伪造的签名者密钥(通过 OIDC 获取的 Fulcio 短期证书)。 - 隔离的短暂构建器(GHA 运行器)。 - 来源被签名并记录到 Rekor。 **上游构件的构建来源**由发布者决定。mhelm 会保留它(`cosign copy` 会转发 referrers)但无法提升它。端到端声明的消费者可以验证: 对于不发布证明的上游,mhelm 的 MirrorProvenance 是唯一的证明 — 链条只能追溯至“mhelm 在运行 Z 时从 URL Y 逐字节复制了 X。” ## 信任模型摘要 1. 上游发布者签名 → `mhelm verify` 在镜像前进行检查。 2. mhelm(GHA OIDC 身份)对每个下游构件进行签名。 3. 下游消费者在部署时验证 mhelm 的签名(准入策略 — 超出 mhelm 范围)。 4. git 中的 `chart-lock.json` = 可重现、可审查、可审计。 5. Rekor = 每个镜像操作的透明度日志。 6. `mhelm drift` = 持续检测上游轮换和 registry 篡改。 每个环节均可独立验证。任何单一环节的受损都是可被检测到的。 ## 平台引导(集群侧,供参考) “仅从我的私有 registry 进行部署”需要三个环节 — mhelm 涵盖了前两个: 1. **镜像 + 覆盖** (mhelm) — 找到每个镜像,进行镜像,生成 `image-values.yaml`。 2. **`helm install --values image-values.yaml`** (用户) — 应用覆盖。 3. **准入时的强制执行**(集群侧,**在 mhelm 范围之外**)— 拒绝任何镜像不以你的镜像前缀开头的 Pod。 环节 3 存在一个鸡生蛋还是蛋生鸡的问题:Kyverno 和 OPA Gatekeeper 都需要一个正常工作的 CNI 才能接收准入 webhook 调用,但 CNI 本身又是你希望强制执行策略的 chart 之一。有三种选择: - **节点级别的 Containerd registry 镜像**(推荐)。将重定向烘焙到节点镜像中;每次拉取(包括 CNI 的)都在运行时层通过镜像进行。 - **ValidatingAdmissionPolicy**(K8s 1.30+)。API 服务器中的原生 CEL 策略 — 不需要 Pods,不依赖 CNI。 - **在节点构建时**通过 `ctr -n=k8s.io images import` **预加载 CNI 镜像**。 编写强制执行层是一个针对 `chart.json#downstream.url` 的一次性步骤 — 故意将其设计在 mhelm 的范围之外。 ## 技术栈 | 关注点 | 库 / 工具 | 原因 | |---|---|---| | Chart 拉取 (HTTP repo) | `helm.sh/helm/v3/pkg/{repo,getter}` | 标准的 Helm SDK | | Chart 拉取/推送 (OCI) | `helm.sh/helm/v3/pkg/registry` | 使用 Helm 媒体类型封装 oras-go | | 模板渲染 | `helm.sh/helm/v3/pkg/engine` | 捕获模板化的镜像引用 | | 镜像流式镜像 | `github.com/google/go-containerregistry/pkg/crane` | Blob 级别的复制,无需完整的 pull/push | | 镜像引用解析 | `github.com/google/go-containerregistry/pkg/name` | 规范的 repo 标准化 | | 上游签名验证 (CLI) | `github.com/sigstore/cosign/v2/pkg/...` | 内嵌因此 `mhelm verify` 无需强制安装运行时 cosign 即可工作 | | 下游签名 + 证明 (Action) | `sigstore/cosign-installer` CLI | 从 CI 调用 Cosign CLI — 官方,可固定版本,无 Go-API 变动 | | SBOM (Action) | `anchore/sbom-action` (syft CLI) | CycloneDX/SPDX,官方 Action | | 漏洞扫描 (Action) | `anchore/scan-action` (grype CLI) | 与 syft 原生配合 | | 自定义断言 | 纯 `encoding/json` | Cosign 将断言体封装在其自有的 DSSE 信封中 | **工具边界。** CLI 负责脚手架搭建、发现、验证、镜像和断言生成。Action 将 CLI 与 cosign / syft / grype 安装器组合在一起。mhelm 故意 **不** 将 cosign/syft/grype 作为 Go 库嵌入用于签名 — 它们久经沙场的 CLI,在工作流中可固定版本,且不受 Go-API 变动的影响。 ## 认证 `mhelm mirror` 复用 `~/.config/helm/registry/config.json` 和 `~/.docker/config.json`(后者是 crane 用于镜像复制的配置)。在向私有 registry 进行镜像之前,请运行 `helm registry login` 和/或 `docker login`。 ## 本地 registry 测试 设置 `MHELM_INSECURE=1` 以允许纯 HTTP + 跳过 TLS 验证。当目标为本地 OCI registry(如 `localhost` 上的 `registry:2`)时需要此设置。对于生产环境的 registry,请保持不设置。 ## 已知限制 - **硬编码的 operator 二进制默认值** — 镜像引用被烘焙到 operator 的 Go 二进制文件本身中(没有 env,没有 ConfigMap)。一旦生产环境安装揭示了它们,请将其添加到 `chart.json#extraImages` 中。 - **子 chart 依赖项** 需要先运行 `helm dependency update`;用户需在 `mhelm discover` 之前运行此命令。 - **多 chart 捆绑包** — 每个 repo/目录一个 chart。在 CI 中使用多个 Action 运行或一个 `**/**/chart.json` 矩阵。 - **漏洞修复** — mhelm 负责扫描和证明;它不会修补或阻止发现的问题。部署时的策略(Kyverno、sigstore-policy-controller)负责执行阻止操作。 - **Values 路径匹配是一种启发式方法** — 准确性包括 `heuristic`(精确的规范 repo 匹配)、`suffix-heuristic`(类似 cilium 的 `operator` → `operator-generic` 的连字符后缀扩展)或 `manual`(`extraImages.valuesPath`)。未来的双渲染差异模式会将明确的案例升级为 `verified`。对于仍然不匹配的镜像,请设置 `extraImages.valuesPath`(对于带有 `image.override` 逃生舱口的 chart 设置 `overridePath`),或手动填充 `image-values.yaml`。 - **`mhelm verify` 在应对出站流量时是尽力而为的** — 由于 Fulcio/Rekor 或 registry 不可达而无法检查其签名的镜像会被记录为 `type=unreachable`(与 `none` = 真正未签名 有区别)。两者都会在 `--strict` 模式下失败。
标签:Cosign, DevSecOps, EVTX分析, GitHub Actions, Helm, LLM防护, OIDC, SBOM, SLSA证明, 上游代理, 代码签名, 容器镜像, 日志审计, 漂移检测, 硬件无关, 自动笔记, 镜像仓库, 镜像同步, 防篡改