# v0.2 Provider Profile 管理规格

本文是 HWLAB `v0.2` 通过 WebUI/CLI 配置 AgentRun provider profile、profile config、provider API Key 和 canary 的长期规格。实施跟踪见 [pikasTech/HWLAB#917](https://github.com/pikasTech/HWLAB/issues/917)，AgentRun 后端能力跟踪见 [pikasTech/agentrun#28](https://github.com/pikasTech/agentrun/issues/28)。

## 设计目标

- 在 HWLAB Cloud Web 左侧顶级导航新增“管理”页面，提供 provider API Key 配置、状态查看和验证入口。
- 继续使用 HWLAB 现有 Web session 与 CLI/API key 鉴权；浏览器用户不直接登录 AgentRun，也不直接调用 AgentRun。
- HWLAB Cloud API 是浏览器同源入口，负责恢复 `AuthPrincipal`、执行业务授权和审计，然后把 provider profile 管理动作委托给 AgentRun 后端。
- AgentRun 后端负责 provider profile 的 SecretRef、配置写入、状态查询和 canary 执行能力；AgentRun 信任来自 HWLAB 后端的服务端调用，不重新做用户级鉴权。
- 新增或修改 provider profile 是管理面数据变更：已鉴权的 HWLAB Web/CLI/API 委托 AgentRun 写 profile config、credential 和 validate，不因每个新 slug 修改 Cloud API/Web 静态枚举、服务代码或触发专门 CI/CD。
- API Key 全程只允许写入，不允许在 Web、CLI、日志、trace、issue、AgentRun event 或 API 响应中回显原文。

## 职责边界

| 组件 | 职责 |
| --- | --- |
| `hwlab-cloud-web` | 提供“管理”页面、表单、状态展示和验证结果展示；只调用 HWLAB 同源 API。 |
| `hwlab-cloud-api` | 复用 HWLAB 鉴权与授权，记录审计上下文，把管理动作委托给 AgentRun 后端，并把结果脱敏后返回前端。 |
| `agentrun-mgr` | 提供 provider profile 管理 REST API，更新 AgentRun profile Secret/配置，触发 profile canary，返回脱敏状态。 |
| `hwlab-deepseek-proxy` | 作为 DeepSeek 官方 upstream 的 Moon Bridge；不承载用户管理 UI。 |
| `hwlab-cli` | 提供管理页的非视觉同路径验收入口，走 HWLAB Cloud Web/Cloud API 同源 path。 |

HWLAB 不能代偿 AgentRun 后端缺失能力：如果 AgentRun 没有 provider profile status、config write、credential write 或 validate API，HWLAB 只能返回清晰 blocker，不能直接写 AgentRun Secret、直接 patch Kubernetes，或伪造成功状态。AgentRun 也不能承接 HWLAB 用户鉴权：用户、角色、Web session、API key 和 OpenFGA 判断仍归 HWLAB。

## Web 管理页

`hwlab-cloud-web` 必须增加一个左侧顶级导航入口：

```text
route: #/management
label: 管理
view: provider API Key 管理
```

页面目标是直接可用的运维界面，不是 landing page。首版至少包含：

- provider profile 列表来自 `GET /v1/admin/provider-profiles` 的实时返回，不是前端固定枚举；内建友好名至少覆盖 `deepseek`、`dsflash-go`、`codex-api`、`minimax-m3`，其余动态 slug 直接回显并可立即使用。
- 新增 provider profile slug 属于 AgentRun provider 配置数据变更；当 AgentRun runtime 已支持动态 slug 时，管理员只通过管理页或 `hwlab-cli client provider-profiles set-config/set-key/validate` 即可创建、配置和验证新 slug，HWLAB 不再为每个新 slug 增加 cloud-api/web 静态枚举，也不为此触发专门服务代码改动或单独 CI/CD。
- 每个 profile 的配置状态：`configured`、SecretRef、key hash 后缀、resourceVersion、最近更新时间、最近验证结果。
- API Key 写入表单：保存后立即清空输入框，不回显旧值。
- DeepSeek 链路摘要：必须显示 `HWLAB Moon Bridge -> DeepSeek 官方 upstream`，并明确不是 hyue 通道。
- 保存、验证和查看最近验证结果的操作状态。

前端不得保存完整 API Key 到 localStorage、sessionStorage、URL、DOM data attribute 或调试输出。表单提交失败时，只显示 failureKind/message 和 redacted target，不显示请求体。

## HWLAB Cloud API 合同

面向前端的同源 API 固定归属 HWLAB：

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

- `/v1/provider-profiles` 是已认证用户可读的公开 catalog，只返回工作台下拉选择所需的 `profile/configured/backendKind/bridge` 等非敏感字段，用于工作台和设置页展示动态 slug。
- `/v1/admin/provider-profiles*` 继续是管理员管理入口，负责查看 SecretRef/resourceVersion/hash 后缀、读取/写入 profile config、删除旧 slug、写 key 和触发 validate。

所有接口必须先通过 [spec-v02-auth.md](spec-v02-auth.md) 恢复 `AuthPrincipal`，再按 [spec-user-access.md](spec-user-access.md) 和 [spec-v02-openfga-authorization.md](spec-v02-openfga-authorization.md) 判定是否允许访问管理能力。首版允许只对 `admin` 开放；如果后续引入 `provider_manager` 或等价 relation，必须先写入用户权限规格。

响应必须是 JSON，且不得包含完整 API Key、Kubernetes Secret data、base64 Secret data、Codex `auth.json` 明文或 credential value。`config.toml` 只允许在显式 admin config read 接口和 `hwlab-cli client provider-profiles config` 输出中返回；它必须只包含非 credential 配置，不能夹带 token/key。允许返回的字段包括：

- `profile`
- `configured`
- `secretRef.namespace/name/keys`
- `keyPrefix` 或不可逆 `keyHashSuffix`
- `resourceVersion`
- `updatedAt`
- `configToml`、`configHashSuffix`、`configTomlPrinted`
- `credentialValuesPrinted=false`
- `validation.status/failureKind/message/runId/commandId/jobName/traceId`
- `delegation.agentRunBaseUrl` 的脱敏摘要

## 委托到 AgentRun

HWLAB Cloud API 必须调用 AgentRun 后端的 provider profile 管理 API，而不是直接写 AgentRun Kubernetes Secret。委托请求只在服务端发生；浏览器不持有 AgentRun token、不知道 AgentRun 内部地址，也不直接读取 AgentRun response。

委托请求必须携带最小审计上下文：

```json
{
  "actor": {
    "system": "hwlab-v02",
    "userId": "<hwlab-user-id>",
    "username": "<hwlab-username>",
    "authMethod": "web-session|api-key"
  },
  "requestId": "<hwlab-request-id>",
  "reason": "hwlab-provider-management"
}
```

AgentRun 对该调用不做用户鉴权，但可以校验调用来源、tenant、profile slug 格式和 request schema；不得要求 HWLAB 为每个新 slug 维护 Cloud API/Web 静态 allowlist。HWLAB 必须把 AgentRun 返回的 failureKind 原样保留到审计和前端响应中，不能把 AgentRun provider/Secret 错误改写成 HWLAB auth、HWPOD node-ops 或 Cloud Web 故障。

## DeepSeek v0.2 通道规则

DeepSeek provider 的目标链路固定为：

```text
AgentRun deepseek profile
  -> http://hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local:4000/v1
  -> /v1/responses
  -> DeepSeek 官方 upstream
```

规则：

- `deepseek` profile 不得配置到 `hyueapi.com` 或 `hyueapi.com/responses`。
- `hyueapi.com` 仍是 Codex API 通道的直连域名，不能因为 DeepSeek 配置改动破坏 NO_PROXY 规则。
- 如果 Moon Bridge 通过环境变量读取 upstream key，保存 DeepSeek API Key 后必须触发受控 rollout/restart，或者返回需要 rollout 的明确状态。
- DeepSeek canary 必须证明 bridge 日志命中 `/v1/responses` 并返回 200；出现 hyue 的 `INSUFFICIENT_BALANCE` 不得算通过。

## CLI 同路径验收

`hwlab-cli` 必须提供管理页的非视觉同路径入口，默认走 Cloud Web 同源 API：

```bash
bun tools/hwlab-cli/bin/hwlab-cli.ts client provider-profiles list
bun tools/hwlab-cli/bin/hwlab-cli.ts client provider-profiles config dsflash-go
bun tools/hwlab-cli/bin/hwlab-cli.ts client provider-profiles set-config dsflash-go --config-file /tmp/config.toml
bun tools/hwlab-cli/bin/hwlab-cli.ts client provider-profiles set-key dsflash-go --key-stdin
bun tools/hwlab-cli/bin/hwlab-cli.ts client provider-profiles validate dsflash-go --wait --timeout-ms 120000
bun tools/hwlab-cli/bin/hwlab-cli.ts client provider-profiles remove PROFILE
```

约束：

- CLI 默认只使用 `HWLAB_API_KEY` 恢复同一个 HWLAB actor；已登录 Web session 只允许作为显式 `--web-session`/`--cookie` 诊断入口，不作为 provider 管理命令的默认鉴权来源。
- `config`/`set-config` 只处理 profile config 文本；config 不得包含 provider API Key、Codex `auth.json`、Authorization header 或 bearer token。
- `set-key --key-stdin` 从 stdin 读取 API Key，默认输出只显示 hash/resourceVersion，不打印 key。
- `remove PROFILE` 通过 Cloud API 委托 AgentRun 删除对应 profile Secret；内建 profile 删除后 capability 仍保留，动态 slug 删除后从列表消失。
- `validate --wait` 短连接 submit-and-poll，输出 validationId、runId、commandId、jobName、traceId、status、failureKind 和 redacted bridge upstream 摘要。
- 这些命令不得直接调用 AgentRun 内部 URL，不得直接读写 Kubernetes Secret。

## 审计与脱敏

HWLAB 审计日志记录：actor、profile、动作、requestId、AgentRun delegation id、SecretRef、old/new hash 后缀、config hash 后缀、resourceVersion、validation id 和结果。禁止记录 API Key 原文、Secret data、Codex `auth.json` 明文、Authorization header 或完整 bearer token；显式读取的 `config.toml` 只允许进入对应 admin 响应和 CLI stdout，不写入审计日志正文。

AgentRun event/trace 只允许显示 provider profile、SecretRef 摘要、validation run/command/job identity 和 failureKind。HWLAB 前端和 CLI 必须把任何疑似 secret-like 字段 redacted 后再展示。

## 验收规格

### T1 管理页入口

在部署后的 `http://74.48.78.17:19666/` 打开 HWLAB v0.2，登录后确认左侧顶级导航出现“管理”，路由为 `#/management`，页面能列出 provider profile 状态。未登录访问管理 API 必须返回 auth blocker。

### T2 状态查询

使用 `hwlab-cli client provider-profiles list` 查询状态，确认请求走 Cloud Web 同源 path，输出 actor、profile、SecretRef/resourceVersion/hash 后缀，不输出 Secret data 或 API Key。

### T3 DeepSeek API Key 写入

通过管理页或 `hwlab-cli client provider-profiles set-key deepseek --key-stdin` 保存新 key，确认 HWLAB 后端委托 AgentRun 后端，返回 updated resourceVersion 和 key hash 后缀。失败时必须显示 AgentRun failureKind，不得静默成功。

### T4 DeepSeek canary

通过管理页或 `hwlab-cli client provider-profiles validate deepseek --wait` 触发真实 canary。通过证据必须包含：validationId、runId、commandId、jobName、traceId、terminal status、bridge `/v1/responses` 200，以及不访问 hyue。

### T5 Secret 不泄露

检查 Web 响应、CLI 输出、HWLAB 日志、AgentRun event/trace 和 issue closeout，确认不包含完整 API Key、Codex `auth.json` 明文、base64 Secret data、Authorization header 或 bearer token。显式 admin config read 可以输出 `config.toml`，但不得包含 credential value。

## 实现状态

| 能力 | 状态 | 说明 |
| --- | --- | --- |
| HWLAB 管理页规格 | 已定义/已接入 | 本文为 `v0.2` provider API Key 管理的 HWLAB 权威规格；Cloud Web 已提供 `#/management` 管理页。 |
| Cloud API 委托接口 | 已实现 | `/v1/admin/provider-profiles*` 由 HWLAB Cloud API 鉴权授权后委托 AgentRun `/api/v1/provider-profiles*`，HWLAB 不直写 AgentRun Secret。 |
| AgentRun provider profile 管理 API | 已对接 | 依赖 AgentRun `v0.1` `agentrun-mgr` provider profile 管理 API；后端长期规格和后续硬化项见 [pikasTech/agentrun#28](https://github.com/pikasTech/agentrun/issues/28)。 |
| CLI 同路径入口 | 已实现 | `client provider-profiles list/config/set-config/remove/set-key/validate/validation` 走 HWLAB Cloud Web 同源 API，用作管理页的非视觉同路径验收入口。 |
| DeepSeek canary | 已验证 | DeepSeek profile 经 `hwlab-deepseek-proxy.hwlab-v02.svc.cluster.local:4000/v1` 到 `/v1/responses`，验收必须继续证明不访问 `hyueapi.com`。 |
| Secret 脱敏 | 已实现/持续约束 | Web、Cloud API、CLI 和 issue 证据不得回显完整 API Key；AgentRun Secret 写入的 `last-applied-configuration` 硬化由 AgentRun 侧继续跟踪。 |
