Files
pikasTech-agentrun/docs/reference/spec-v01-provider-profile-management.md
T
2026-06-08 23:31:33 +08:00

17 KiB
Raw Blame History

v0.1 Provider Profile 管理规格

本文是 AgentRun v0.1 provider profile 管理能力的长期规格。实施跟踪见 pikasTech/agentrun#28HWLAB v0.2 WebUI 配置入口见 pikasTech/HWLAB#917

设计目标

  • agentrun-mgr 提供 provider profile 状态查询、API Key 写入、Secret/config 更新和 canary 验证 REST API。
  • AgentRun 后端直接信任来自 HWLAB hwlab-cloud-api 的服务端委托调用,不实现浏览器用户登录、Web session、HWLAB 用户角色或 OpenFGA 判断。
  • 浏览器和 HWLAB Cloud Web 不直接访问 AgentRun,也不把原始 API Key 传入 run/session/command payload。
  • AgentRun 只返回脱敏状态:profile、SecretRef、resourceVersion、hash 后缀、validation result、run/command/job identity 和 failureKind。
  • provider profile 仍通过现有 backendProfileexecutionPolicy.secretScope.providerCredentials[]、profile-scoped SecretRef 和 writable CODEX_HOME 装配到 runner。

职责边界

组件 职责
agentrun-mgr provider profile 管理 API、Secret/config 写入、状态查询、canary 创建、validation 状态聚合和脱敏审计。
agentrun-runner 按既有 backendProfile/SecretRef 装配 runtime,执行 canary run,不读取管理 API 的用户上下文。
HWLAB hwlab-cloud-api 用户鉴权、业务授权、Web/CLI 同源 API、审计 actor、调用 AgentRun 管理 API。
HWLAB hwlab-cloud-web “管理”页面和 API Key 表单;不直接调用 AgentRun。

AgentRun 不承担 HWLAB 用户鉴权。它只做机器层 contract 校验:调用来源、tenant/project/profile allowlist、SecretRef scope、payload schema、redaction 和幂等性。AgentRun 不判断某个 HWLAB 用户是否能配置 API Key,也不保存 HWLAB Web session、API key 或 OpenFGA decision。

Profile 列表

v0.1 可管理 profile 分为内建 profile 与动态 profile slug。内建 profile 是无需 Secret 也必须出现在列表中的稳定能力;动态 profile 是管理员通过 HWLAB Cloud API / HWLAB CLI 或 AgentRun CLI 写入受控 Secret 后立即可见、可配置、可验证的 profile,不需要为每个新 slug 修改 AgentRun 或 HWLAB 服务代码。

profile backendKind 默认 SecretRef 说明
codex codex-app-server-stdio agentrun-v01/agentrun-v01-provider-codex Codex API profile。
deepseek codex-app-server-stdio agentrun-v01/agentrun-v01-provider-deepseek DeepSeek profile,经 HWLAB Moon Bridge 到 DeepSeek 官方 upstream。
minimax-m3 codex-app-server-stdio agentrun-v01/agentrun-v01-provider-minimax-m3 MiniMax-M3 profile。
dsflash-go codex-app-server-stdio agentrun-v01/agentrun-v01-provider-dsflash-go DeepSeek V4 Flash profile,经 HWLAB Moon Bridge 到 OpenCode Zen Go upstreamSecret 额外要求 model-catalog.json,模型目录与 config.toml 均声明 1M/900k context。

动态 profile slug 必须匹配小写 slug 规则 ^[a-z0-9][a-z0-9-]{0,63}$,并固定映射到同 namespace 内 agentrun-v01-provider-<profile> SecretRefrequired keys 仍为 auth.jsonconfig.toml。profile 管理 API 不得允许任意 namespace、任意 Secret name、runtime-default 或不符合 slug 规则的 profile。新增普通 OpenAI/Codex-compatible provider profile 时,管理员应优先通过 provider-profiles set-config / set-key / validate 创建动态 slug;只有需要新的 backend kind、特殊装配规则、额外 Secret key、租户策略或产品级固定友好名时,才更新本规格、内建 capability、CLI 示例和验证规格。

REST API

Provider profile 管理 API 属于 agentrun-mgr 公共 REST API 的服务端委托面:

GET  /api/v1/provider-profiles
GET  /api/v1/provider-profiles/:profile
DELETE /api/v1/provider-profiles/:profile
GET  /api/v1/provider-profiles/:profile/config
PUT  /api/v1/provider-profiles/:profile/config
PUT  /api/v1/provider-profiles/:profile/credential
POST /api/v1/provider-profiles/:profile/validate
GET  /api/v1/provider-profiles/:profile/validations/:validationId

所有成功和失败响应都必须是 JSON。失败响应至少包含 failureKindmessagerequestId。除显式 GET /api/v1/provider-profiles/:profile/config 返回 config.toml 明文供 HWLAB admin 管理页查看外,其他响应不得包含 API Key 原文、Codex auth.json 明文、Codex config.toml 明文、base64 Secret data、Authorization header、Kubernetes token 或 provider request header。

GET /api/v1/provider-profiles

返回所有内建 profile 与已存在动态 profile 的脱敏状态。动态 profile 通过受控 Secret 的 name、label 或 annotation 发现;删除动态 profile 的最后一个 Secret 后,它不再出现在 collection list 中。字段至少包含:

  • profile
  • backendKind
  • configured
  • secretRef.namespace/name/keys
  • resourceVersion
  • keyHashSuffixcredentialHashSuffix
  • configHashSuffix
  • updatedAt
  • lastValidation.status/failureKind/message/runId/commandId/jobName

Secret 缺失时仍要返回 profile capability,并把状态标为 configured=falsefailureKind=secret-unavailable;不得因为 Secret 未配置而隐藏 profile。

DELETE /api/v1/provider-profiles/:profile

删除 profile 对应 Kubernetes Secret。

  • 内建 profilecodexdeepseekminimax-m3dsflash-go)删除后,capability 仍必须保留在 GET /api/v1/provider-profiles 列表中,但状态回到 configured=false / failureKind=secret-unavailable
  • 动态 slug 删除后,若没有剩余 Secret,对应 slug 不再出现在 collection list 中;显式 GET /api/v1/provider-profiles/:profile 仍可返回该 slug 的未配置状态。
  • 响应必须返回 removedalreadyAbsent,并保持 Secret/API Key 脱敏。

GET/PUT /api/v1/provider-profiles/:profile/config

GET 返回当前 profile 的 configToml、SecretRef、resourceVersion 和 hash 后缀,供 HWLAB admin 管理页查看。PUT 接收 configToml,保存时只替换同一 Secret 的 config.toml,保留现有 auth.json,并返回 resourceVersion 和 configHashSuffix

PUT /api/v1/provider-profiles/:profile/credential

请求体由 HWLAB 后端或受控 CLI 发送,最小形态:

{
  "apiKey": "<write-only>",
  "config": {
    "model": "<optional>",
    "baseUrl": "<optional>"
  },
  "delegatedBy": {
    "system": "hwlab-v02",
    "userId": "<hwlab-user-id>",
    "username": "<hwlab-username>",
    "requestId": "<hwlab-request-id>"
  },
  "reason": "hwlab-provider-management"
}

规则:

  • apiKey 只在本次 request 内用于生成 Secret data,不能落入 Postgres、event、trace、日志或响应。
  • Manager 写入 profile 对应 Kubernetes Secret 的 auth.jsonconfig.toml,并返回新的 resourceVersion 与不可逆 hash 后缀;dsflash-go 同时生成或保留 model-catalog.json
  • Manager 可记录 delegatedBy 的脱敏审计信息,但不把它作为用户鉴权依据。
  • 非 HWLAB 委托调用可以用于 operator CLI,但也必须走同一 schema 和 redaction。
  • 非法 profile、非法 baseUrl、SecretRef scope 越界、Kubernetes 写入失败和 config render 失败必须结构化失败。

POST /api/v1/provider-profiles/:profile/validate

触发一个真实 canary。它必须通过 AgentRun 自身 run/command/runner-job 路径执行,不得只做静态 Secret 读取、mock provider 或直接 curl provider 作为通过证据。响应短返回:

{
  "validationId": "val_...",
  "profile": "deepseek",
  "runId": "run_...",
  "commandId": "cmd_...",
  "jobName": "agentrun-v01-runner-...",
  "status": "running",
  "pollUrl": "/api/v1/provider-profiles/deepseek/validations/val_..."
}

GET /validations/:validationId 聚合 command result、runner job status、events 和 provider failureKind,返回 running|completed|failed|cancelled。成功时必须能证明当前 backendProfile、SecretRef、CODEX_HOME、provider status 和 assistant reply;失败时必须保留 provider/secret/runner failureKind。

DeepSeek 配置规则

deepseek profile 的 Codex config 必须指向 HWLAB v0.2 Moon Bridge,而不是 hyue

baseUrl: http://hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local:4000/v1
expected request path: /v1/responses
upstream: DeepSeek 官方 API

AgentRun 不直接拥有 DeepSeek 官方 upstream URL 的业务路由;它只把 Codex app-server 请求送到 HWLAB Moon Bridge。若 HWLAB bridge 需要独立 upstream Secret 或 rolloutAgentRun 管理 API 必须在响应中返回 requiresExternalBridgeUpdate=true 或由 HWLAB 委托请求显式声明 bridge 同步已完成。AgentRun 不得把 deepseek 配置改到 hyueapi.com,也不得因 DeepSeek 失败 fallback 到 codex

dsflash-go 配置规则

dsflash-go 是内建 DeepSeek V4 Flash / OpenCode Zen Go profile,不是普通动态 slug。它必须通过 Codex stdio profile 形态运行,并满足以下固定规则:

  • model 必须是 deepseek-v4-flash,不得被 deepseek-chat 或其他模型覆盖。
  • config.toml 必须声明 model_context_window = 1000000model_auto_compact_token_limit = 900000
  • config.toml 必须声明 model_catalog_json = "/home/agentrun/.codex-dsflash-go/model-catalog.json"Secret 中必须存在同名 model-catalog.json,其中 deepseek-v4-flash 的 context window 与 config.toml 一致。
  • base URL 必须指向 HWLAB Moon Bridge service 或 wrapper-local bridge,禁止指向 hyueapi.com;当前 G14 v0.2 默认服务入口是 http://hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local:4000/v1
  • PUT /credentialPUT /config 均必须在不打印 Secret value 的前提下生成或保留 model-catalog.json;状态查询只显示 key presence/hash 摘要。
  • 若上游 compact 路径返回 404、not found、unsupported、no route 或 not implementedadapter 必须归类为 provider-compact-unsupported,避免被泛化成 backend-failed

Secret 与 RBAC

Manager ServiceAccount 需要最小 Secret 管理权限,只允许 getlistcreatereplacedeletepatch 受控 provider profile Secret

  • agentrun-v01-provider-codex
  • agentrun-v01-provider-deepseek
  • agentrun-v01-provider-minimax-m3
  • agentrun-v01-provider-dsflash-go
  • agentrun-v01-provider-<dynamic-lowercase-slug>

不得授予 Manager 更新 namespace 内任意 Secret 的宽权限;动态 Secret 必须受 agentrun-v01-provider- 前缀、profile label/annotation 和 slug 校验约束。状态查询只读取受控 Secret metadata 和 key presence/hash,不返回 Secret value。

Secret 写入后,runner Job 仍按 spec-v01-secret-distribution.md 通过 SecretRef projection 装配;run/command payload 中不出现 API Key。

Secret 写入不得留下包含 Secret data 的 Kubernetes last-applied 注解。Manager 更新 credential 时应使用不会生成 kubectl.kubernetes.io/last-applied-configuration 的 patch/update 路径,或在写入完成后显式删除该注解;状态响应、event、trace 和 CLI 输出仍只能返回 SecretRef、resourceVersion、hash 后缀和 redacted validation identity。

CLI

AgentRun CLI 提供 operator 和综合联调入口:

./scripts/agentrun provider-profiles list
./scripts/agentrun provider-profiles show deepseek
./scripts/agentrun provider-profiles config deepseek
./scripts/agentrun provider-profiles remove deepseek
./scripts/agentrun provider-profiles set-key deepseek --key-stdin
./scripts/agentrun provider-profiles set-config deepseek --config-stdin
./scripts/agentrun provider-profiles validate deepseek --wait --timeout-ms 120000
./scripts/agentrun provider-profiles set-config my-provider --config-stdin
./scripts/agentrun provider-profiles set-key my-provider --key-stdin

CLI 必须调用 manager REST API,不直连 Postgres,不读取 Kubernetes Secret value。set-key --key-stdin 从 stdin 读入 API Key,默认输出只包含 SecretRef、resourceVersion、hash 后缀、failureKind 和下一步验证命令。

审计与脱敏

Manager 审计事件允许记录:profile、action、delegatedBy.system、delegatedBy.userId、requestId、SecretRef、old/new hash 后缀、resourceVersion、validationId、runId、commandId、jobName、failureKind。禁止记录:API Key 原文、Secret data、Codex auth/config 明文、Authorization header、provider request header/body、Kubernetes token。

验收规格

T1 profile 状态

阅读本文和 spec-v01-secret-distribution.md,调用 GET /api/v1/provider-profiles./scripts/agentrun provider-profiles list。确认 codexdeepseekminimax-m3dsflash-go 等内建 profile 全部可见,缺 Secret 时显示 configured=falsesecret-unavailable,不隐藏 capability;已创建的动态 slug 也会列出;所有输出都不得包含 Secret value。

T2 DeepSeek 写入

./scripts/agentrun provider-profiles set-key deepseek --key-stdin 写入测试 key。确认输出只有 resourceVersion/hash 后缀和 redacted SecretRefPostgres、event、trace、日志和 CLI 输出不含完整 key。

T3 DeepSeek canary

./scripts/agentrun provider-profiles validate deepseek --wait 触发真实 runner canary。通过证据必须包含 validationId、runId、commandId、jobName、backendProfile=deepseek、SecretRef=agentrun-v01-provider-deepseek、terminal completed 和非空 assistant reply。

T4 HWLAB 委托

通过 HWLAB v0.2 Cloud API /v1/admin/provider-profiles/deepseek/credential/validate 调用本 API,确认 AgentRun 不要求 HWLAB 用户凭据,不读取 Web session,不返回用户权限判断;但会记录 delegatedBy.system=hwlab-v02 和 requestId 的脱敏审计。

T5 redaction

检查 manager 日志、AgentRun events、CLI 输出和 validation result,确认不包含 API Key 原文、Codex auth.jsonconfig.toml、Secret data 或 Authorization header。

T6 profile 删除

./scripts/agentrun provider-profiles remove <profile> 删除一个动态 slug,再删除一个内建 profile。确认动态 slug 从 collection list 消失;内建 profile 仍留在 list 中但 configured=falseCLI/日志/响应不输出 Secret value。

T7 动态 profile 无代码变更

用 HWLAB CLI 或 AgentRun CLI 对一个临时动态 slug 执行 set-configset-keylistremove。通过证据必须显示 profile SecretRef 为 agentrun-v01-provider-<slug>configured=true 只在 auth.jsonconfig.toml 同时存在时成立、删除后 collection list 不再包含该 slug,并且整个过程没有 AgentRun/HWLAB service code change、PR、PipelineRun 或 rollout 作为前置条件。

T8 dsflash-go model catalog

./scripts/agentrun provider-profiles set-key dsflash-go --key-stdin 或同源 HWLAB 委托 API 写入测试 key。确认输出只包含脱敏 SecretRef、resourceVersion/hash 后缀和 validation identityKubernetes Secret 中存在 auth.jsonconfig.tomlmodel-catalog.json 三个 keyconfig.toml 使用 deepseek-v4-flash、1M/900k context 和固定 model_catalog_json 路径;provider-profiles show dsflash-go 必须显示三项 key presence,且不输出任何 Secret value。

实现状态

能力 状态 说明
Provider profile 管理规格 已定义/已落地 本文为 AgentRun v0.1 profile 管理权威规格。
REST 管理 API 已实现 agentrun-mgr 提供 /api/v1/provider-profiles*,覆盖 list/show/remove/set-key/validate/validation。
动态 profile slug 已实现 小写 slug 通过 agentrun-v01-provider-<slug> SecretRef 动态生效;普通 provider API Key/config 轮换不需要为每个新 slug 修改服务代码或触发专门 CI/CD。
CLI 管理入口 已实现 ./scripts/agentrun provider-profiles list/show/remove/set-key/set-config/validate 调用 manager REST API,不直连 Secret value。
DeepSeek Secret 写入 已实现/需硬化 已按受控 SecretRef 更新 auth.json/config.toml 并保持 HWLAB Moon Bridge 官方链路;后续必须去除 credential update 产生 last-applied-configuration 注解的副作用。
dsflash-go model catalog 已实现 dsflash-go 使用 deepseek-v4-flash、1M/900k context、固定 model_catalog_json 路径和 Secret 内 model-catalog.jsoncompact unsupported 明确归类为 provider-compact-unsupported
Provider canary 已实现 canary 通过真实 run/command/runner-job 路径执行,并返回 validationId、runId、commandId、jobName 和 terminal status。
HWLAB 委托信任边界 已验证 HWLAB v0.2 通过 Cloud API 委托调用本 APIAgentRun 不读取 HWLAB Web session,也不做用户级鉴权。