harbor防篡改依赖oci签名+notary v2/cosign+内容信任策略,需在harbor.yml中显式启用content_trust: enabled: true并配置notary服务,否则签名无效;golang工程须调用harbor api校验签名状态,确保签名被收录。

Harbor 本身不提供“防篡改”扫描能力,它只做镜像内容漏洞扫描(CVE)和签名验证;真正的防篡改靠的是 OCI 镜像签名 + Notary v2 / Cosign + Harbor 的内容信任策略,Golang 工程只需配合这套链路完成签名校验与推送拦截。
Harbor 启用 Notary v2 签名验证必须开启 content trust
Harbor 默认不启用镜像签名强制校验,即使你用 Cosign 签了名,推送时也不会被拦。必须在 harbor.yml 中显式开启内容信任:
- 设置
content_trust: enabled: true(v2.8+ 版本才支持 Notary v2) - 确保
notary: enabled: true且已正确配置证书(Notary 服务需独立部署或由 Harbor 内置托管) - 重启 Harbor:
./install.sh --with-notary --with-trivy(注意:Notary v1 已弃用,v2 是默认选项)
没开这个开关,Golang 程序再怎么验签名也没用——Harbor 根本不检查。
Golang 工程推送前用 Cosign 签名镜像
Trivy 扫描的是漏洞,不是完整性。防篡改依赖的是镜像 digest + 签名绑定。Cosign 是当前最轻量、与 Go 生态集成最好的签名工具:
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 先构建并推送镜像到 Harbor:
docker build -t my-harbor.example.com/proj/api:v1.2 . && docker push my-harbor.example.com/proj/api:v1.2 - 再用 Cosign 签名(需提前配置 OIDC 或私钥):
cosign sign --yes my-harbor.example.com/proj/api:v1.2 - Golang 里调用签名操作,推荐用
cosign.SignAPI(来自github.com/sigstore/cosign/v2),而非 exec.Command —— 更可控、可复用凭证上下文 - 注意:签名目标必须是带 tag 的镜像,不能是
@sha256:...digest 形式(Cosign v2.2+ 支持 digest 签名,但 Harbor v2.8 仅校验 tag 绑定签名)
Golang 调用 Harbor API 校验镜像签名状态
你无法靠本地 Cosign verify 判断 Harbor 是否认可该签名——因为 Harbor 可能禁用策略、或 Notary 服务不可达。必须查 Harbor 的签名元数据接口:
- 请求路径:
/api/v2.0/projects/{project_name}/repositories/{repo_name}/artifacts/{tag}/signature - 返回
200且signatures数组非空,才表示 Harbor 已成功收录并验证该签名 - 若返回
404,说明签名未同步进 Harbor 的 Notary 存储(常见于网络延迟或 Notary 服务异常) - Golang 示例片段:
resp, err := http.Get("https://my-harbor.example.com/api/v2.0/projects/proj/repositories/api/artifacts/v1.2/signature"),别漏掉 bearer token 认证头
跳过这步直接上线,等于把“已签名”当“已受信”,实际运行时仍可能拉到未签名镜像。
CI/CD 中拦截无签名或签名失效的镜像推送
防篡改不是一次性的动作,而是持续策略。Golang 工程的 CI 流程里,应在 docker push 后立即触发签名与校验,失败则中断发布:
- 用
cosign verify --certificate-oidc-issuer https://accounts.google.com --certificate-identity your@domain.com my-harbor.example.com/proj/api:v1.2做本地预检(可选) - 必须调 Harbor API 查 signature 接口,确认签名已就位
- 若校验失败,
os.Exit(1)终止 pipeline —— 不要只打日志 - 避免在 Go 服务中实时校验拉取的镜像(runtime verify 开销大、易被绕过),策略应前置到构建和推送阶段
签名本身不加密镜像内容,只绑定 digest 与身份。真正容易被忽略的是:Harbor 的 content trust 开关、Notary 服务健康状态、以及签名后是否真被 Harbor 接收——这三者缺一不可,任一环节断开,“防篡改”就形同虚设。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










