feat: trusted release keys setting; drop the duplicate release registration route [CI]
ci/woodpecker/push/main-amd64-build Pipeline was successful

The panel now lets the deployer decide which release keys it trusts. The
official CI key is built in and always trusted; an own P-256 public key can be
added (off by default, the private key is rejected) so manifests signed with it
are accepted too. Removing it drops the manifests only it signed. Changes are
audited and need update.confirm.

Admin UI: System > Trust > "Trusted release keys" with a collapsible guide on
generating a key pair and signing a manifest with openssl.

Registration now has one path, POST /api/release/offer (no token, signature
verified). The admin POST /releases route, the release.publish capability and
the ci-release preset are removed.
This commit is contained in:
justme committed 2026-10-08 18:50:16 +08:00
1 parent 904ea2b0ae
commit 0f8f3f9a54
24 files changed
+914 -325

No files matched your search

+3 -2
View File
@@ -146,8 +146,9 @@
| GET | `/api/admin/capabilities` | 能力目录:分组、哪些改变信任、哪些是预留、依赖关系和预设(只读、运维、接入、CI 发布、全部) |
| GET/PATCH | `/api/admin/settings` | 站点公开或私有、是否对访客显示构建信息(`site.show_build`)、保留期、节点定时重启(`fleet.restart_enabled`、`fleet.restart_hour`、`fleet.restart_minute`、`fleet.restart_utc_offset_minutes`,默认开、04:30、UTC+8;改完立即通知在线节点)等 |
| GET | `/api/admin/build-info` | 后端和每个 Agent、Probe 的版本、tag、提交、构建时间、系统,以及节点宿主机更新器报告的更新状态(管理端「系统 → 版本」) |
| GET/POST | `/api/admin/releases` | CI 签名的发布清单:POST 登记(`{manifest, signature}`,需要 `release.publish`,原样转给在线的节点和之后连上的节点),GET 看每个组件最新的一份 |
| POST | `/api/release/offer` | CI 登记发布清单的入口,**不需要令牌**:`{manifest, signature}` 的签名必须能用 Backend 内嵌的发布公钥验过(ECDSA P-256 / SHA-256,DER),否则 403;`seq` 必须比已登记的新,否则 409。登记不依赖面板里的任何凭证,清库、重装、还没有 passkey 时照常工作 |
| GET | `/api/admin/releases` | 每个组件最新的一份签名发布清单 |
| GET/PUT/DELETE | `/api/admin/release-key` | 可信资产来源:GET 看官方发布密钥和(如果有)自有发布公钥的指纹;PUT `{public_key}` 另外信任自己的发布公钥(P-256 的 PEM,拒绝私钥);DELETE 停用它,只有它签过的已登记清单会被丢掉。官方密钥始终信任。PUT/DELETE 需要 `update.confirm`,写审计 |
| POST | `/api/release/offer` | CI 登记发布清单的入口,**不需要令牌**:`{manifest, signature}` 的签名必须能用 Backend 内嵌的官方发布公钥或已开启的自有发布公钥验过(ECDSA P-256 / SHA-256,DER),否则 403;`seq` 必须比已登记的新,否则 409。登记不依赖面板里的任何凭证,清库、重装、还没有 passkey 时照常工作 |
| GET | `/api/admin/links` | 每一对(Probe,Agent)的线路开关:`linked`(最终结果)、`override`(手动设置,`null` 跟随自动连接)、`connected`,以及 `auto_link` |
| PUT | `/api/admin/links/{probe_id}/{agent_id}` | `{enabled: true|false|null}`:手动强制连或不连,`null` 取消手动设置;改完立即重新下发 |
| POST | `/api/admin/nodes/{id}/update` | 请求一个在线的 Agent 或 Probe 更新到它收到的清单(节点不在线返回 409) |