REST API 参考
SupKube 的全部能力都通过一套 REST API 暴露,前端界面本身就是这套 API 的消费者。本文列出全部 88 个端点、各自所需的最低角色,以及认证与授权的完整判定规则。
前置条件
- 一个可用的访问令牌(见下节「认证」)。
- 所有端点都在
/api/v1前缀下,通过您暴露 SupKube 界面的同一个地址访问。
认证
SupKube 支持三种认证方式:两种 Bearer 令牌(OIDC JWT 与静态令牌)以及 HTTP Basic。两种 Bearer 令牌使用完全相同的请求头:
Authorization: Bearer <令牌>
服务端按令牌的结构决定走哪条校验路径,不需要您指定用的是哪一种:
Authorization: Bearer <token>
│
▼
能按 "." 拆成三段非空内容吗?
(即结构上像不像一个 JWT)
│
┌────────────────┴────────────────┐
像 JWT 不像 JWT
│ │
▼ ▼
┌──────────────┐ ┌──────────────────┐
│ OIDC 校验 │ │ 静态令牌表 │
│ 走 JWKS,慢 │ │ SHA-256 哈希 │
│ │ │ 常数时间比对,快 │
└──┬────────┬──┘ └───┬──────────┬───┘
通过│ 失败│ 命中│ 未命中│
▼ ▼ ▼ ▼
身份=用户 401 身份=token:<名称> 401
╳ 不回退 ╳ 不回退
这是刻意的安全设计,不是实现疏漏。如果 JWT 校验失败后还允许回退去查静态令牌表,攻击者就可以构造一个结构像 JWT、但实际用于撞哈希的令牌,绕过签名校验。
因此:一个看起来像 JWT 的令牌,签名不对就直接 401,绝不会再被当作静态令牌尝试;反之亦然。
静态令牌用 SHA-256 哈希存储并以常数时间比对,且匹配成功后不提前退出循环——保持循环长度恒定,避免通过响应时间推断令牌前缀。
OIDC 令牌(适合人)
由内置 Dex 或您接入的外部身份提供方签发,走标准登录流程。界面用的就是这种。
静态令牌(适合脚本与 CI)
OIDC 适合人在浏览器里点,但不适合无人值守的脚本——它需要完整的授权码流程,令牌还会过期。静态令牌提供一个独立于 OIDC 的「机器通道」。
静态令牌由 Helm 的 auth.staticTokens 渲染进 AUTH_STATIC_TOKENS_JSON 环境变量。这类身份的 subject 会被合成为 token:<名称> 的形式,因此在审计日志里能与真人用户区分开。
角色为 editor 的静态令牌同样受命名空间范围约束,范围在令牌定义里指定。
OIDC 与 HTTP Basic 两条路径都会按用户身份去查 RBAC 绑定表来决定角色;静态令牌不会——它的角色直接写在令牌条目上。
这带来一个实用后果:当身份提供方的用户组声明断链、所有人回落到兜底角色时,预置的静态令牌仍然可用。它是 RBAC 配置失误时唯一不受影响的通道,详见角色与权限里的自救通道一节。
HTTP Basic(无 IdP 环境兜底)
除上述两种 Bearer 令牌外,SupKube 还接受 Authorization: Basic <base64>,走 htpasswd 校验。这条路径由请求头前缀直接区分,与上面那张图的 JWT 结构判断无关:
Authorization: Basic ──▶ htpasswd 校验
Authorization: Bearer ──▶ 上图的 JWT 结构分派
详见认证与 SSO。
AUTH_STATIC_TOKENS_JSON 为空或解析失败时,SupKube 不会因此拒绝启动,也不会关闭认证——它只是让静态令牌通道不可用,OIDC 通道照常工作。这是刻意的:一个写坏的 JSON 不应该把所有人挡在门外。
授权模型
角色只有三个,能力逐级包含:
viewer ────► editor ────► admin
只读 读 + 增删改 读 + 增删改 + 管基础设施
(受命名空间限制) (集群范围)
授权分两层,两层都通过才会真正执行:
请求
│
▼
┌──────────────┐ 失败 ┌─────┐
│ 第一层:认证 ├─────────►│ 401 │
└──────┬───────┘ └─────┘
│ 通过
▼
┌──────────────────────────┐ 路径不在权限表 ┌─────┐
│ 第二层:角色检查(中间件) ├──────────────────►│ 403 │ ← 默认拒绝
│ 查「方法 + 路径」的最低角色 │ 角色不够 └─────┘
└──────┬───────────────────┘──────────────────► 403
│ 通过
▼
┌──────────────────────────┐ editor 且 ns 不在范围内 ┌─────┐
│ 第三层:命名空间检查 ├───────────────────────────►│ 403 │
│ (在具体 handler 内部) │ └─────┘
└──────┬───────────────────┘
│ 通过
▼
执行操作
为什么命名空间检查不在中间件里
因为「这次操作会碰哪些命名空间」这个信息的位置不固定:可能在 URL 路径里(DELETE /backups/:name 需要反查备份属于哪个命名空间)、可能在请求体里(POST /backups)、也可能两边都有(POST /restores 带命名空间映射)。集中到中间件需要为每个端点配置提取规则,比在少数几个写操作的 handler 里各调一次检查更复杂。
命名空间范围只约束 editor
| 角色 | 命名空间范围 |
|---|---|
admin | 集群范围,不受限 |
editor | 仅限分配给它的命名空间,操作触及范围外的命名空间会被拒绝 |
viewer | 集群范围,但只读 |
editor 越界时返回:
{
"error": "namespace not in your scope",
"namespace": "other-ns",
"scope": ["my-app", "my-app-staging"]
}
权限表是「默认拒绝」的
如果一个端点没有登记在权限表里,请求不会被放行,而是直接 403:
{
"error": "endpoint not in RBAC table (this is a SupKube bug — please report)"
}
这条错误信息不是权限配置问题,您改任何角色绑定都不会让它消失。它表示后端新增了一个端点但忘了登记权限,属于 SupKube 的缺陷。这个设计是刻意的——让遗漏以「功能不可用」的形式立刻暴露,而不是以「未授权访问」的形式静默放行。
角色不足时返回的则是另一种,能看出差距在哪:
{
"error": "insufficient role",
"required": "admin",
"current": "editor"
}
免认证的公开端点
绝大多数 /api/v1/* 都要求认证,但下列端点被刻意豁免:
| 路径 | 豁免原因 |
|---|---|
/api/v1/status | 存活探针,供 Kubernetes 与负载均衡器调用 |
/api/v1/auth/providers | 登录页需要在未登录状态下知道有哪些身份提供方 |
/api/v1/auth/callback | OIDC 回调,此时用户尚未持有令牌 |
/api/v1/auth/logout | 登出 |
/api/v1/dr-posture | 只读的备份/容灾态势快照,供 SupInsight 以服务间调用方式摄取 |
/api/v1/dr-posture 会暴露容灾态势这个端点不需要任何凭据就能读取,设计上假定它只被集群内服务通过内部 DNS 访问,公网入口由 nginx 另行拦截。
如果您把 SupKube 直接暴露在公网且没有在入口层限制这个路径,任何人都能读到您的备份覆盖情况与容灾评分。部署时请确认入口规则覆盖了它。
端点总表
路径中的 :name、:namespace、:id 为占位符,替换为实际值。
权限表支持功能模块在初始化时追加条目(跨集群导入策略、备份就绪性检查、AI 助手都是这样注册的),因此完整端点集合不止主表里那些。下文已把动态注册的部分一并列出。
状态与总览
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/status | viewer |
| GET | /api/v1/events | viewer |
| GET | /api/v1/dashboard/summary | viewer |
| GET | /api/v1/dashboard/topology | viewer |
| GET | /api/v1/velero-health | viewer |
| GET | /api/v1/plugins/status | viewer |
| GET | /api/v1/local-store/status | viewer |
/api/v1/events 是 SSE 事件流,供 SupInsight、MCP Server 这类外部代理订阅状态变化,避免轮询。
应用与命名空间
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/applications | viewer |
| GET | /api/v1/applications/:namespace/details | viewer |
| GET | /api/v1/applications/:namespace/storage-capability | viewer |
| POST | /api/v1/applications/:namespace/snapshot | editor |
| GET | /api/v1/namespaces | viewer |
| POST | /api/v1/namespaces | admin |
| GET | /api/v1/backup-advisor | viewer |
| GET | /api/v1/backup-advisor/:namespace | viewer |
备份
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/backups | viewer |
| GET | /api/v1/backups/:name | viewer |
| GET | /api/v1/backups/:name/resources | viewer |
| GET | /api/v1/backups/:name/artifacts | viewer |
| GET | /api/v1/backups/:name/artifact-breakdown | viewer |
| GET | /api/v1/backups/:name/errors | viewer |
| POST | /api/v1/backups | editor |
| DELETE | /api/v1/backups/:name | editor |
| POST | /api/v1/backups/:name/force-delete | editor |
还原
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/restores | viewer |
| GET | /api/v1/restores/:name | viewer |
| GET | /api/v1/restores/:name/results | viewer |
| POST | /api/v1/restores/preflight | editor |
| POST | /api/v1/restores | editor |
| DELETE | /api/v1/restores/:name | editor |
| GET | /api/v1/resources/yaml | viewer |
建议的调用顺序是先 preflight 再 restores:预检会在真正执行前返回阻断项与修复建议。
策略(计划备份)
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/schedules | viewer |
| GET | /api/v1/schedules/:name | viewer |
| POST | /api/v1/schedules | editor |
| PATCH | /api/v1/schedules/:name | editor |
| POST | /api/v1/schedules/:name/run-once | editor |
| DELETE | /api/v1/schedules/:name | editor |
PATCH 是全表唯一使用该方法的端点,用于局部更新策略而不必提交完整对象。
存储位置与快照位置
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/storage-locations | viewer |
| GET | /api/v1/storage-locations/:name | viewer |
| POST | /api/v1/storage-locations | admin |
| PUT | /api/v1/storage-locations/:name | admin |
| DELETE | /api/v1/storage-locations/:name | admin |
| POST | /api/v1/storage-locations/:name/verify | admin |
| GET | /api/v1/volume-snapshot-locations | viewer |
| GET | /api/v1/volume-snapshot-locations/:name | viewer |
| POST | /api/v1/volume-snapshot-locations | admin |
| DELETE | /api/v1/volume-snapshot-locations/:name | admin |
| POST | /api/v1/vault/provision | admin |
存储是备份的落点,配错会让所有备份失效,因此写操作一律要求 admin,editor 无法染指。
变换规则与变换集
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/transforms | viewer |
| GET | /api/v1/transforms/:name | viewer |
| POST | /api/v1/transforms | admin |
| PUT | /api/v1/transforms/:name | admin |
| DELETE | /api/v1/transforms/:name | admin |
| GET | /api/v1/transform-sets | viewer |
| GET | /api/v1/transform-sets/:name | viewer |
| POST | /api/v1/transform-sets | admin |
| PUT | /api/v1/transform-sets/:name | admin |
| DELETE | /api/v1/transform-sets/:name | admin |
| POST | /api/v1/transform-sets/:name/preview-resolution | viewer |
| POST | /api/v1/transform-sets/apply-conflict-fixes | editor |
注意两个例外:preview-resolution 只是预览、不落盘,所以 viewer 就能调;apply-conflict-fixes 作用于一次具体的还原,归 editor。
多集群
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/clusters | viewer |
| GET | /api/v1/clusters/:name | viewer |
| POST | /api/v1/clusters | admin |
| DELETE | /api/v1/clusters/:name | admin |
| POST | /api/v1/clusters/test | admin |
| POST | /api/v1/clusters/:name/test | admin |
| GET | /api/v1/multicluster/summary | viewer |
| POST | /api/v1/backup-copy/preflight | editor |
| POST | /api/v1/backup-copy | admin |
POST /api/v1/backup-copy 当前返回 501 Not Implemented,只有预检端点可用。详见备份与还原操作。
任务与日志
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/actions | viewer |
| GET | /api/v1/actions/:id | viewer |
| GET | /api/v1/logs | viewer |
| GET | /api/v1/logs/components | viewer |
| GET | /api/v1/audit-logs | admin |
身份与设置
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/auth/me | viewer |
| GET | /api/v1/auth/rbac/bindings | admin |
| GET | /api/v1/settings/branding | viewer |
| PUT | /api/v1/settings/branding | admin |
| GET | /api/v1/settings/cleanup | admin |
| PUT | /api/v1/settings/cleanup | admin |
| POST | /api/v1/admin/cleanup/orphans | admin |
GET /api/v1/settings/branding 是白标定制配置里唯一对 viewer 开放的读接口——侧边栏和页头需要在每次加载时渲染,因此不能要求高权限。
跨集群导入策略
这组端点由导入策略模块动态注册(不在主权限表里),能力与策略组对齐:
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/import-policies | viewer |
| GET | /api/v1/import-policies/:name | viewer |
| POST | /api/v1/import-policies | editor |
| PUT | /api/v1/import-policies/:name | editor |
| DELETE | /api/v1/import-policies/:name | editor |
| POST | /api/v1/import-policies/:name/run-once | editor |
| POST | /api/v1/import-policies/:name/pause | editor |
| POST | /api/v1/import-policies/:name/resume | editor |
用法见跨集群灾备。
备份就绪性检查
| 方法 | 路径 | 最低角色 |
|---|---|---|
| POST | /api/v1/policies/preflight | editor |
策略保存前的静态预检,返回通过/警告/阻断三级结论。处理逻辑内部还会对草案涉及的每个命名空间做范围校验。
AI 评分与助手
| 方法 | 路径 | 最低角色 |
|---|---|---|
| POST | /api/v1/ai/score | viewer |
| GET | /api/v1/ai/scores | viewer |
| GET | /api/v1/ai/explain/:taskId | viewer |
| POST | /api/v1/ai/chat | viewer |
DR 评分引擎是确定性规则引擎,不调用大语言模型。这组 ai/* 端点属于 Copilot 助手,默认关闭(ai.enabled=false)且需要配置外部密钥。
存储驱动与 MCP
| 方法 | 路径 | 最低角色 |
|---|---|---|
| GET | /api/v1/storage/csi-autoconfig | viewer |
| POST | /api/v1/storage/csi-autoconfig/install | admin |
| POST | /api/v1/mcp/confirmations | editor |
| GET | /api/v1/mcp/confirmations/:id | editor |
| DELETE | /api/v1/mcp/confirmations/:id | editor |
mcp/confirmations 是给 MCP Server 做「危险操作二次确认」用的握手接口。MCP Server 本身当前未随产品部署。
验证方法
确认令牌可用,以及自己被解析成了什么身份与角色:
curl -s https://supkube.example.com/api/v1/auth/me \
-H "Authorization: Bearer $TOKEN"
返回里会带上角色与命名空间范围。若返回 401,说明令牌两条通道都没通过;若某个具体接口返回 403,对照本文表格确认所需最低角色。
用一个只读接口验证连通性与版本:
curl -s https://supkube.example.com/api/v1/status \
-H "Authorization: Bearer $TOKEN"