---
url: /zh/guide/commit-signature-verification.md
description: >
  介绍 CNB 平台的提交签名验证机制，说明如何生成并添加 GPG 公钥、 本地签名提交，以及平台默认签名（web-flow.gpg）与 GitHub
  等第三方官方签名的验证规则。
---
你可以使用 GPG 对提交（commit）和标签（tag）进行签名，
CNB 会校验这些签名并在仓库页面标记验证状态。
当提交者向他人证明这些变更确实出自本人时，签名验证非常有用。

## 什么是签名验证

GPG（GNU Privacy Guard）是一种基于非对称加密的签名工具：
你用**私钥**对提交签名，并将对应的**公钥**上传到 CNB。
CNB 收到带签名的提交后，使用你的公钥校验签名，
并比对签名密钥与提交者邮箱是否一致。

校验通过的提交会显示 **已验证（Verified）** 标记，表示：

* 该提交确实由对应私钥的持有者签名；
* 提交未在传输过程中被篡改。

未签名或无法通过校验的提交不会显示已验证标记。

## 管理 GPG 公钥

登录后进入 `个人设置` → [GPG 公钥](//cnb.cool/profile/gpg-keys)，
可以添加、查看和删除公钥。

### 添加公钥

点击「添加 GPG 公钥」，填写以下信息：

* **标题**：公钥的备注名称，便于识别（可选）。
* **公钥内容**：ASCII-armored 格式的公钥，
  必须以 `-----BEGIN PGP PUBLIC KEY BLOCK-----` 开头、
  以 `-----END PGP PUBLIC KEY BLOCK-----` 结尾。

添加后，CNB 会解析并展示公钥的指纹、关联邮箱、子密钥及过期时间等信息。

> 同一指纹的公钥不能重复添加。请上传**公钥**，切勿上传私钥。

### 删除公钥

删除公钥后，该密钥将不能再用于验证后续新产生的提交；
但**此前已验证通过的历史提交记录会被保留**，仍然显示为已验证。

## 生成 GPG 密钥并签名提交

如果你还没有 GPG 密钥，可在本地生成：

```bash
# 生成密钥对，按提示填写姓名与邮箱
gpg --full-generate-key

# 查看密钥 ID（sec 行 rsa4096/ 后的字符串）
gpg --list-secret-keys --keyid-format=long

# 导出 ASCII-armored 格式公钥，复制输出内容到 CNB
gpg --armor --export <你的密钥ID>
```

将导出的公钥添加到 CNB 后，配置 Git 使用该密钥签名：

```bash
# 设置签名所用的密钥
git config --global user.signingkey <你的密钥ID>

# 单次签名提交
git commit -S -m "your message"

# 或设置默认对所有提交签名
git config --global commit.gpgsign true
```

> **邮箱必须匹配**：用于签名的密钥所关联的邮箱，需与提交中的 `committer` / `tagger` 邮箱一致，
> 且该邮箱已在你的账号中验证，否则提交不会显示为已验证。
> 可通过 `git config --global user.email` 确认提交邮箱。

## 平台默认签名（web-flow.gpg）

在 CNB 上直接产生的提交——例如**云原生开发**在线编辑、网页端编辑文件、合并请求（MR）合并等由平台自动生成的提交——会使用**平台默认 GPG 密钥**自动签名，并在页面上显示为已验证。

平台公钥可通过以下地址获取，用于在其他工具中校验这些提交的签名：

```text
https://cnb.cool/web-flow.gpg
```

> **跨平台说明**：该公钥是 CNB 的平台特性公钥，与平台默认的提交者邮箱一一对应。
> 如果你将仓库推送到其他平台（如 GitHub），希望这些提交在对方平台也显示为 verified，
> 需要对方平台单独适配并导入该公钥及对应邮箱，否则只会在 CNB 上显示为已验证。

### 开启或关闭云原生开发的官方签名

你可以自行控制是否对**云原生开发**中的提交启用官方 GPG 签名。
进入 `个人设置` → [云原生开发](//cnb.cool/profile/workspaces)，开关 **GPG 验证** 即可：

* **开启后**：系统会自动为云原生开发中的提交进行签名，以验证代码来源可靠。
* **关闭后**：云原生开发中的提交将不再自动签名，相应提交不会显示为已验证。

> 该设置作用于你的账号，将应用到你的所有仓库。

## 第三方官方签名验证

CNB 支持识别并验证来自 GitHub 等第三方平台**官方密钥**签名的提交。
例如通过 GitHub 网页端操作产生、以 `noreply@github.com` 作为提交者邮箱（committer email）的 GitHub 官方签名提交，
在迁移到 CNB 后仍会显示为已验证。

## 验证状态说明

CNB 会对每个签名给出一个验证结论，常见状态如下：

| 状态                       | 含义                                                 |
|----------------------------|------------------------------------------------------|
| `valid`                    | 签名有效，提交已验证                                 |
| `unsigned`                 | 提交不包含签名                                       |
| `unknown_signature_type`   | 提交或标签中包含非 PGP 签名                          |
| `no_user`                  | 提交者 / 标签者邮箱未关联任何用户                    |
| `unverified_email`         | 已添加 GPG 公钥，但对应邮箱未验证                    |
| `bad_email`                | 提交者邮箱与签名密钥的身份不匹配                     |
| `unknown_key`              | 签名密钥未注册到任何用户账号                         |
| `expired_key`              | 用于签名的密钥已过期                                 |
| `not_signing_key`          | 密钥中找不到「签名」标志                             |
| `malformed_signature`      | 签名格式错误，无法解析                               |
| `invalid`                  | 无法使用签名中的密钥对签名进行加密验证               |

## 常见问题

* **添加了公钥但提交仍未显示已验证？** 请确认：提交邮箱与公钥关联邮箱一致、该邮箱已在账号中验证、且本地确实使用 `-S` 或开启了 `commit.gpgsign` 进行签名。
* **密钥过期怎么办？** 续期或更换密钥后，重新导出公钥并在 CNB 中添加。
