Skip to main content

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 的静态令牌同样受命名空间范围约束,范围在令牌定义里指定。

静态令牌的角色不查 RBAC 绑定表

OIDC 与 HTTP Basic 两条路径都会按用户身份去查 RBAC 绑定表来决定角色;静态令牌不会——它的角色直接写在令牌条目上。

这带来一个实用后果:当身份提供方的用户组声明断链、所有人回落到兜底角色时,预置的静态令牌仍然可用。它是 RBAC 配置失误时唯一不受影响的通道,详见角色与权限里的自救通道一节。

HTTP Basic(无 IdP 环境兜底)​

除上述两种 Bearer 令牌外,SupKube 还接受 Authorization: Basic <base64>,走 htpasswd 校验。这条路径由请求头前缀直接区分,与上面那张图的 JWT 结构判断无关:

Authorization: Basic ──▶ htpasswd 校验
Authorization: Bearer ──▶ 上图的 JWT 结构分派

详见认证与 SSO。

note

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)"
}
看到这个错误请报 bug

这条错误信息不是权限配置问题,您改任何角色绑定都不会让它消失。它表示后端新增了一个端点但忘了登记权限,属于 SupKube 的缺陷。这个设计是刻意的——让遗漏以「功能不可用」的形式立刻暴露,而不是以「未授权访问」的形式静默放行。

角色不足时返回的则是另一种,能看出差距在哪:

{
"error": "insufficient role",
"required": "admin",
"current": "editor"
}

免认证的公开端点​

绝大多数 /api/v1/* 都要求认证,但下列端点被刻意豁免:

路径豁免原因
/api/v1/status存活探针,供 Kubernetes 与负载均衡器调用
/api/v1/auth/providers登录页需要在未登录状态下知道有哪些身份提供方
/api/v1/auth/callbackOIDC 回调,此时用户尚未持有令牌
/api/v1/auth/logout登出
/api/v1/dr-posture只读的备份/容灾态势快照,供 SupInsight 以服务间调用方式摄取
/api/v1/dr-posture 会暴露容灾态势

这个端点不需要任何凭据就能读取,设计上假定它只被集群内服务通过内部 DNS 访问,公网入口由 nginx 另行拦截。

如果您把 SupKube 直接暴露在公网且没有在入口层限制这个路径,任何人都能读到您的备份覆盖情况与容灾评分。部署时请确认入口规则覆盖了它。

端点总表​

路径中的 :name、:namespace、:id 为占位符,替换为实际值。

部分端点由功能模块动态注册

权限表支持功能模块在初始化时追加条目(跨集群导入策略、备份就绪性检查、AI 助手都是这样注册的),因此完整端点集合不止主表里那些。下文已把动态注册的部分一并列出。

状态与总览​

方法路径最低角色
GET/api/v1/statusviewer
GET/api/v1/eventsviewer
GET/api/v1/dashboard/summaryviewer
GET/api/v1/dashboard/topologyviewer
GET/api/v1/velero-healthviewer
GET/api/v1/plugins/statusviewer
GET/api/v1/local-store/statusviewer

/api/v1/events 是 SSE 事件流,供 SupInsight、MCP Server 这类外部代理订阅状态变化,避免轮询。

应用与命名空间​

方法路径最低角色
GET/api/v1/applicationsviewer
GET/api/v1/applications/:namespace/detailsviewer
GET/api/v1/applications/:namespace/storage-capabilityviewer
POST/api/v1/applications/:namespace/snapshoteditor
GET/api/v1/namespacesviewer
POST/api/v1/namespacesadmin
GET/api/v1/backup-advisorviewer
GET/api/v1/backup-advisor/:namespaceviewer

备份​

方法路径最低角色
GET/api/v1/backupsviewer
GET/api/v1/backups/:nameviewer
GET/api/v1/backups/:name/resourcesviewer
GET/api/v1/backups/:name/artifactsviewer
GET/api/v1/backups/:name/artifact-breakdownviewer
GET/api/v1/backups/:name/errorsviewer
POST/api/v1/backupseditor
DELETE/api/v1/backups/:nameeditor
POST/api/v1/backups/:name/force-deleteeditor

还原​

方法路径最低角色
GET/api/v1/restoresviewer
GET/api/v1/restores/:nameviewer
GET/api/v1/restores/:name/resultsviewer
POST/api/v1/restores/preflighteditor
POST/api/v1/restoreseditor
DELETE/api/v1/restores/:nameeditor
GET/api/v1/resources/yamlviewer

建议的调用顺序是先 preflight 再 restores:预检会在真正执行前返回阻断项与修复建议。

策略(计划备份)​

方法路径最低角色
GET/api/v1/schedulesviewer
GET/api/v1/schedules/:nameviewer
POST/api/v1/scheduleseditor
PATCH/api/v1/schedules/:nameeditor
POST/api/v1/schedules/:name/run-onceeditor
DELETE/api/v1/schedules/:nameeditor

PATCH 是全表唯一使用该方法的端点,用于局部更新策略而不必提交完整对象。

存储位置与快照位置​

方法路径最低角色
GET/api/v1/storage-locationsviewer
GET/api/v1/storage-locations/:nameviewer
POST/api/v1/storage-locationsadmin
PUT/api/v1/storage-locations/:nameadmin
DELETE/api/v1/storage-locations/:nameadmin
POST/api/v1/storage-locations/:name/verifyadmin
GET/api/v1/volume-snapshot-locationsviewer
GET/api/v1/volume-snapshot-locations/:nameviewer
POST/api/v1/volume-snapshot-locationsadmin
DELETE/api/v1/volume-snapshot-locations/:nameadmin
POST/api/v1/vault/provisionadmin

存储是备份的落点,配错会让所有备份失效,因此写操作一律要求 admin,editor 无法染指。

变换规则与变换集​

方法路径最低角色
GET/api/v1/transformsviewer
GET/api/v1/transforms/:nameviewer
POST/api/v1/transformsadmin
PUT/api/v1/transforms/:nameadmin
DELETE/api/v1/transforms/:nameadmin
GET/api/v1/transform-setsviewer
GET/api/v1/transform-sets/:nameviewer
POST/api/v1/transform-setsadmin
PUT/api/v1/transform-sets/:nameadmin
DELETE/api/v1/transform-sets/:nameadmin
POST/api/v1/transform-sets/:name/preview-resolutionviewer
POST/api/v1/transform-sets/apply-conflict-fixeseditor

注意两个例外:preview-resolution 只是预览、不落盘,所以 viewer 就能调;apply-conflict-fixes 作用于一次具体的还原,归 editor。

多集群​

方法路径最低角色
GET/api/v1/clustersviewer
GET/api/v1/clusters/:nameviewer
POST/api/v1/clustersadmin
DELETE/api/v1/clusters/:nameadmin
POST/api/v1/clusters/testadmin
POST/api/v1/clusters/:name/testadmin
GET/api/v1/multicluster/summaryviewer
POST/api/v1/backup-copy/preflighteditor
POST/api/v1/backup-copyadmin
跨存储位置复制尚未交付

POST /api/v1/backup-copy 当前返回 501 Not Implemented,只有预检端点可用。详见备份与还原操作。

任务与日志​

方法路径最低角色
GET/api/v1/actionsviewer
GET/api/v1/actions/:idviewer
GET/api/v1/logsviewer
GET/api/v1/logs/componentsviewer
GET/api/v1/audit-logsadmin

身份与设置​

方法路径最低角色
GET/api/v1/auth/meviewer
GET/api/v1/auth/rbac/bindingsadmin
GET/api/v1/settings/brandingviewer
PUT/api/v1/settings/brandingadmin
GET/api/v1/settings/cleanupadmin
PUT/api/v1/settings/cleanupadmin
POST/api/v1/admin/cleanup/orphansadmin

GET /api/v1/settings/branding 是白标定制配置里唯一对 viewer 开放的读接口——侧边栏和页头需要在每次加载时渲染,因此不能要求高权限。

跨集群导入策略​

这组端点由导入策略模块动态注册(不在主权限表里),能力与策略组对齐:

方法路径最低角色
GET/api/v1/import-policiesviewer
GET/api/v1/import-policies/:nameviewer
POST/api/v1/import-policieseditor
PUT/api/v1/import-policies/:nameeditor
DELETE/api/v1/import-policies/:nameeditor
POST/api/v1/import-policies/:name/run-onceeditor
POST/api/v1/import-policies/:name/pauseeditor
POST/api/v1/import-policies/:name/resumeeditor

用法见跨集群灾备。

备份就绪性检查​

方法路径最低角色
POST/api/v1/policies/preflighteditor

策略保存前的静态预检,返回通过/警告/阻断三级结论。处理逻辑内部还会对草案涉及的每个命名空间做范围校验。

AI 评分与助手​

方法路径最低角色
POST/api/v1/ai/scoreviewer
GET/api/v1/ai/scoresviewer
GET/api/v1/ai/explain/:taskIdviewer
POST/api/v1/ai/chatviewer
与 DR 评分不是一回事

DR 评分引擎是确定性规则引擎,不调用大语言模型。这组 ai/* 端点属于 Copilot 助手,默认关闭(ai.enabled=false)且需要配置外部密钥。

存储驱动与 MCP​

方法路径最低角色
GET/api/v1/storage/csi-autoconfigviewer
POST/api/v1/storage/csi-autoconfig/installadmin
POST/api/v1/mcp/confirmationseditor
GET/api/v1/mcp/confirmations/:ideditor
DELETE/api/v1/mcp/confirmations/:ideditor

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"

相关文档​