ckotzbauer/sbom-operator

GitHub: ckotzbauer/sbom-operator

基于 Syft 的 Kubernetes Operator,自动为集群内所有容器镜像生成并分发软件物料清单(SBOM)。

Stars: 221 | Forks: 33

# sbom-operator [![test](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/b007cb31e9065807.svg)](https://github.com/ckotzbauer/sbom-operator/actions/workflows/test.yml) ## 概述 该 Operator 维护一个中心位置,用于跟踪 Kubernetes 集群中所有镜像里使用的所有包和软件。为此,使用 Syft 从每个镜像生成软件物料清单 (SBOM)。它们都存储在一个或多个目标中。目前支持 Git、Dependency Track、OCI-Registry 和 ConfigMaps。 借此,可以在单一位置进行进一步分析、[漏洞扫描](https://github.com/ckotzbauer/vulnerability-operator)等操作。 为了防止扫描已经分析过的镜像,Pod 会被注上已处理镜像的 imageID。 ## Kubernetes 兼容性 镜像包含 `k8s.io/client-go` 的版本。Kubernetes 旨在提供客户端和服务器之间一个小版本的前向和后向兼容性: | sbom-operator | k8s.io/{api,apimachinery,client-go} | 预期 kubernetes 兼容性 | |-----------------|-------------------------------------|-----------------------------------| | main | v0.34.1 | 1.33.x, 1.34.x, 1.35.x | | 0.38.0 | v0.34.1 | 1.33.x, 1.34.x, 1.35.x | | 0.33.0 | v0.30.0 | 1.29.x, 1.30.x, 1.31.x | | 0.31.0 | v0.29.3 | 1.28.x, 1.29.x, 1.30.x | | 0.30.0 | v0.28.4 | 1.27.x, 1.28.x, 1.29.x | | 0.28.0 | v0.27.4 | 1.26.x, 1.27.x, 1.28.x | | 0.26.0 | v0.26.3 | 1.25.x, 1.26.x, 1.27.x | | 0.22.0 | v0.25.4 | 1.24.x, 1.25.x, 1.26.x | | 0.15.0 | v0.24.4 | 1.23.x, 1.24.x, 1.25.x | | 0.10.0 | v0.23.6 | 1.22.x, 1.23.x, 1.24.x | 但是,该 Operator 通常可以在更多版本的 Kubernetes 上工作。 ## 容器镜像仓库支持 该 Operator 依赖 syft 内部机制从符合 OCI 标准的镜像仓库下载镜像。 ## 安装 #### 清单 ``` kubectl apply -f deploy/standard/ ``` #### Helm-Chart 首先创建一个包含所需配置的 YAML 文件,或者使用 helm-flags。 ``` helm repo add ckotzbauer https://ckotzbauer.github.io/helm-charts helm install ckotzbauer/sbom-operator -f your-values.yaml ``` ## 配置 所有参数均为 cli-flags。这些标志可以配置为 args,或作为以 `SBOM_` 为前缀的环境变量,以便将敏感配置作为 secret 值注入。 ### 通用参数 | 参数 | 必需 | 默认值 | 描述 | |-----------|----------|---------|-------------| | `verbosity` | `false` | `info` | 日志级别 (debug, info, warn, error, fatal, panic) | | `cron` | `false` | `""` | 后台服务间隔 (CRON)。详情请参见 [Trigger](#analysis-trigger)。 | | `ignore-annotations` | `false` | `false` | 强制分析所有镜像,包括来自已注解 Pod 的镜像。 | | `format` | `false` | `json` | SBOM 格式。(可选 `json`, `syftjson`, `cyclonedxjson`, `spdxjson`, `github`, `githubjson`, `cyclonedx`, `cyclone`, `cyclonedxxml`, `spdx`, `spdxtv`, `spdxtagvalue`, `text`, `table` 之一) | | `targets` | `false` | `git` | 发送生成的 SBOM 的目标的逗号分隔列表。可能的目标 `git`, `dtrack`, `oci`, `configmap`。使用 `job-image` 时忽略 | | `pod-label-selector` | `false` | `""` | Kubernetes Pod 标签选择器。 | | `namespace-label-selector` | `false` | `""` | Kubernetes Namespace 标签选择器。 | | `fallback-pull-secret` | `false` | `""` | 当所有其他方式失败时作为备用加载的 Kubernetes Pull-Secret 名称(必须与 sbom-operator 在同一 namespace 中) | | `registry-proxy` | `false` | `[]` | 要使用的代理镜像仓库主机。Flag 可多次使用。值映射例如 `docker.io=ghcr.io` | | `delete-orphan-images` | `false` | `true` | 自动删除孤立镜像 | ### Helm-Config 示例 ``` args: targets: git git-author-email: XXX git-author-name: XXX git-repository: https://github.com/XXX/XXX git-path: dev-cluster/sboms verbosity: debug cron: "0 30 * * * *" envVars: - name: SBOM_GIT_ACCESS_TOKEN valueFrom: secretKeyRef: name: "sbom-operator" key: "accessToken" ``` ## 分析触发器 ### Cron 设置 `cron` 标志后,Operator 将按指定间隔运行,并检查集群中已更改的镜像。 允许使用来自 [github.com/robfig/cron](https://github.com/robfig/cron) 的所有选项作为 cron 语法。 ### 实时 当省略 `cron` 标志时,Operator 使用 Cache-Informer 立即处理已更改的 Pod。在此模式下,启动时也会进行一次性分析,以将目标与实际集群状态同步。如果您配置了 job-image,则没有初始启动同步。 ## 目标 可以将生成的 SBOM 存储到不同的目标(甚至同时存储到多个)。所有目标都使用 Syft 作为分析器。 如果您想使用其他工具来分析镜像,请查看 [Job image](#job-images) 部分。不存在于集群中的镜像将从配置的目标中移除(OCI-Target 除外)。 ### Dependency Track #### Dependency Track 参数 | 参数 | 必需 | 默认值 | 描述 | |-----------|----------|---------|-------------| | `dtrack-base-url` | 使用 `dtrack` 目标时为 `true` | `""` | Dependency-Track 基础 URL,例如 'https://dtrack.example.com' | | `dtrack-api-key` | 使用 `dtrack` 目标时为 `true` | `""` | Dependency-Track API key | | `dtrack-label-tag-matcher` | `false` | `""` | Dependency-Track Pod-Label-Tag 匹配正则 | | `dtrack-ca-cert-file` | `false` | `""` | 使用 mTLS 连接到 dtrack 时的 CA 证书文件路径 | | `dtrack-client-cert-file` | 提供 `dtrack-ca-cert-file` 时为 `true` | `""` | 使用 mTLS 连接到 dtrack 时的客户端证书文件路径 | | `dtrack-client-key-file` | 提供 `dtrack-ca-cert-file` 时为 `true` | `""` | 使用 mTLS 连接到 dtrack 时的客户端密钥文件路径 | | `dtrack-default-parent-project` | `false` | `""` | 应使用的默认父项目 UUID。如果设置并找到了父项目注解,这将覆盖默认值 | | `dtrack-use-short-name` | `false` | `""` | 使用短镜像名称(不含 registry)作为项目名称 | | `dtrack-parent-project-annotation-key` | `false` | `""` | 用于自动设置父项目的 Kubernetes pod annotation key,例如 "my.pod.annotation" | | `dtrack-project-name-annotation-key` | `false` | `""` | 用于自动设置自定义 dtrack 项目名称的 Kubernetes pod annotation key,例如 "my.pod.annotation" | | `kubernetes-cluster-id` | `false` | `"default"` | Kubernetes Cluster ID(用于 Dependency-Track 或 Job-Images)| 集群中的每个镜像都作为一个项目创建,使用完整镜像名称(registry 和镜像路径,不含 tag)作为项目名,image-tag 作为项目版本。 当没有 image-tag 但有 digest 时,digest 将用作项目版本。 使用 DT 的 `autoCreate` 选项。使用此目标时,您必须将 `--format` 标志设置为 `cyclonedx`。 #### 自定义 dtrack 项目名称: Kubernetes 中的 key 必须后跟项目对应的容器名称。例如 `my.project.name/my-nginx`。 通过特定 Pod 上的注解在 dtrack 中自定义项目名称的值,格式为 `project:version` 或仅为 `project`,其中版本默认为 `latest`。例如 `MyParentProject` 或 `MyParentProject:1.0` #### 在 Dependency Track 自动设置父项目: Kubernetes 中的 key 必须后跟父项目对应的容器名称。例如 `my.parent.project/my-nginx`。 特定 Pod 上的父项目注解值格式为 `project:version` 或仅为 `project`,其中版本默认为 `latest`。例如 `MyParentProject` 或 `MyParentProject:1.0` #### Pod 注解示例: ``` apiVersion: v1 kind: Pod metadata: annotations: my.parent.project/my-nginx: MyParentProject my.project.name/my-nginx: MyNginxProject:1.0 my.parent.project/my-sidecar: MyOtherParentProject my.project.name/my-sidecar: MySidecarProject:1.0.1 spec: containers: - image: nginx:latest name: my-nginx ... - image: some-other-image:latest name: my-sidecar ... ... ``` #### sbom-operator 配置: ``` --dtrack-parent-project-annotation-key=my.parent.project --dtrack-project-name-annotation-key=my.project.name ``` ### Git #### Git 参数 | 参数 | 必需 | 默认值 | 描述 | |-----------|----------|---------|-------------| | `git-workingtree` | `false` | `/work` | 放置 git-repo 的目录。 | | `git-repository` | 使用 `git` 目标时为 `true`。 | `""` | Git-Repository-URL (HTTPS)。 | | `git-branch` | `false` | `main` | 要检出的 Git-Branch。 | | `git-path` | `false` | `""` | Git-Repository 内部的文件夹路径。 | | `git-author-name` | 使用 `git` 目标时为 `true`。 | `""` | Git-Commits 使用的作者名称。 | | `git-author-email` | 使用 `git` 目标时为 `true`。 | `""` | Git-Commits 使用的作者邮箱。 | | `git-access-token` | `false` | `""` | 具有写入权限的 Git-Personal-Access-Token。 | | `git-username` | `false` | `""` | Git-Username | | `git-password` | `false` | `""` | Git-Password | | `github-app-id` | `false` | `""` | GitHub App-ID。 | | `github-app-installation-id` | `false` | `""` | GitHub App-Installation-ID。 | Operator 将使用下面描述的特定文件夹结构保存所有文件。当配置了 `git-path` 时,该路径上方的所有文件夹都不会被应用程序触碰。假设 `git-path` 设置为 `dev-cluster/sboms`。如果没有给出 `git-path`,下面的结构直接位于仓库根目录中。 该结构基本为 `////sbom.json`(见下例)。 如果配置了其他输出格式,文件扩展名可能会有所不同。 您可以使用带有 `--git-access-token` 的基于令牌的身份验证(例如 GitHub 的 PAT),带有用户名和密码的 BasicAuth(`--git-username`, `--git-password`)或 Github App 身份验证(`--github-app-id`, `--github-app-installation-id`, env: `SBOM_GITHUB_APP_PRIVATE_KEY`)。私钥必须经过 Base64 编码。 **注意**:要求仓库的指定分支已完全初始化。没有创建不存在分支的逻辑。只需提交一个 `README.md` 或类似文件即可使工作正常进行。 ``` dev-cluster │ └───sboms │ └───docker.io | │ | └───library | │ | └───busybox | │ | └───sha256_ae39a6f5... | │ sbom.json | └───ghcr.io │ └───kyverno │ └───kyverno | │ | └───sha256_9e3f14e5... | │ sbom.json | └───kyvernopre │ └───sha256_e48f87fd... │ sbom.json | └───policy-reporter │ └───sha256_b70caa7a... │ sbom.json ``` ### OCI-Registry #### OCI-Registry 参数 | 参数 | 必需 | 默认值 | 描述 | |-----------|----------|---------|-------------| | `oci-registry` | 使用 `oci` 目标时为 `true` | `""` | OCI-Registry | | `oci-user` | 使用 `oci` 目标时为 `true` | `""` | OCI-User | | `oci-token` | 使用 `oci` 目标时为 `true` | `""` | OCI-Token | 在此模式下,Operator 将生成 SBOM 并将其存储到 OCI-Registry 中。然后 SBOM 可以由 cosign, Kyverno 或任何其他工具处理。例如: ``` COSIGN_REPOSITORY= cosign download sbom ``` Operator 需要 Registry-URL、用户和令牌作为密码来向 registry 进行身份验证。需要写入权限。 ### ConfigMap 此目标将 SBOM 存储为 Kubernetes-ConfigMap。它们放置在与相应 pod 相同的 namespace 中,名称由 pod 和 container 名称组成。Configmap 被标记为 `ckotzbauer.sbom-operator.io=true` 并注有 `ckotzbauer.sbom-operator.io/image-id=`。 内容以 configmap-key `sbom` 存储为 brotli 压缩的二进制数据。 ## Job-Images #### Job-Image 参数 | 参数 | 必需 | 默认值 | 描述 | |-----------|----------|---------|-------------| | `job-image` | `false` | `""` | 用于代替 Syft 处理镜像的 Job-Image | | `job-image-pull-secret` | `false` | `""` | 用于私有 job-images预先存在的 pull-secret-name | | `job-timeout` | `false` | `3600` | Job-Timeout(以秒为单位)(`activeDeadlineSeconds`) | | `kubernetes-cluster-id` | `false` | `"default"` | Kubernetes Cluster ID(用于 Dependency-Track 或 Job-Images)| 如果您不想使用 Syft 分析镜像,可以尝试 Job-Image 功能。Operator 创建一个 Kubernetes-Job,在其中使用任何可能的工具进行分析。Operator 不进行目标处理,Job 中的工具必须自行处理 SBOM。目前有两种可能的集成: | Tool | 描述 | | ---- | ----------- | | [Codenotary VCN](job-images/vcn/README.md) | 来自 Codenotary 的 VCN-Tool 可以在 Codenotary Cloud 中公证您的镜像。(收费) | 此功能作为通用方法构建。任何遵循[这些规范](job-images/SPEC.md)的镜像都可以用作 job-image。 例如 Manifest (`deploy/job-image`): ``` --job-image=ghcr.io/ckotzbauer/sbom-operator/vcn: ``` 例如 Helm: ``` jobImageMode: true envVars: - name: SBOM_JOB_VCN_LC_API_KEY value: "" ``` 所有以 `SBOM_JOB_` 为前缀的 operator-environment 变量都会传递给 Kubernetes job。 ## 安全 Docker 镜像基于 scratch-image,以减少攻击面并保持镜像小巧。 此外,镜像和发布工件使用 [cosign](https://github.com/sigstore/cosign) 签名,并使用 provenance-files 进行验证。 发布过程满足 SLSA Level 2。所有这些“元数据文件”也存储在专用仓库 `ghcr.io/ckotzbauer/sbom-operator-metadata` 中。 如果发现安全问题,请参阅 [Security process](https://github.com/ckotzbauer/.github/blob/main/SECURITY.md)。 ### 签名验证 ``` COSIGN_EXPERIMENTAL=1 COSIGN_REPOSITORY=ghcr.io/ckotzbauer/sbom-operator-metadata cosign verify ghcr.io/ckotzbauer/sbom-operator: --certificate-github-workflow-name create-release --certificate-github-workflow-repository ckotzbauer/sbom-operator ``` ### 证明验证 ``` COSIGN_EXPERIMENTAL=1 COSIGN_REPOSITORY=ghcr.io/ckotzbauer/sbom-operator-metadata cosign verify-attestation ghcr.io/ckotzbauer/sbom-operator: --certificate-github-workflow-name create-release --certificate-github-workflow-repository ckotzbauer/sbom-operator ``` ### 下载证明 ``` COSIGN_REPOSITORY=ghcr.io/ckotzbauer/sbom-operator-metadata cosign download attestation ghcr.io/ckotzbauer/sbom-operator: | jq -r '.payload' | base64 -d ``` ### 下载 SBOM ``` COSIGN_REPOSITORY=ghcr.io/ckotzbauer/sbom-operator-metadata cosign download sbom ghcr.io/ckotzbauer/sbom-operator: | jq -r '.payload' | base64 -d ``` ## [许可证](https://github.com/ckotzbauer/sbom-operator/blob/master/LICENSE) ## [更新日志](https://github.com/ckotzbauer/sbom-operator/blob/master/CHANGELOG.md) ## 贡献 请参阅 [贡献指南](https://github.com/ckotzbauer/.github/blob/main/CONTRIBUTING.md)。 ## 行为准则 请参阅 [行为准则指南](https://github.com/ckotzbauer/.github/blob/main/CODE_OF_CONDUCT.md)。
标签:Dependency Track, DevSecOps, EVTX分析, Go, Linux安全, OCI Registry, Operator, Ruby工具, SBOM, Syft, Web截图, WSL, 上游代理, 占用监测, 子域名突变, 容器安全, 提示注入, 文档安全, 日志审计, 活动识别, 漏洞分析, 硬件无关, 请求拦截, 资产管理, 跌倒检测, 路径探测, 软件物料清单, 镜像扫描, 集群管理