Files
pikasTech-agentrun/docs/reference/spec-v01-secret-distribution.md
T
2026-05-29 18:05:05 +08:00

175 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# v0.1 Secret 与 provider credential 分发规格
本文定义 AgentRun `v0.1` 的 Secret 和 Code Agent provider credential 分发边界。真实 Code Agent backend 需要上游模型凭据;Codex stdio profile 测试凭据以 `~/.codex/auth.json``~/.codex/config.toml` 形态为输入源,通过 Kubernetes Secret 投影进入 runner/backend Pod。这些值不得进入 Git source、GitOps branch、artifact catalog、event、trace、日志或 CLI 输出。
## 设计目标
- API Key、Codex auth/config 等 provider credential 只通过 Kubernetes SecretRef 分发到需要它的 manager、runner 或 backend adapter。
- `deploy/deploy.json` 只记录 SecretRef 名称、key 名称、mount/env intent 和 secret scope,不记录 Secret 值。
- `v0.1-gitops` 的 rendered manifests 只能引用 Secret 名称和 key,不包含 Secret data。
- `agentrun-mgr` 保存 run 的 `executionPolicy.secretScope`,但保存的是 credential source reference,不是 credential value。
- runner 和 backend adapter 只能消费 manager 已授权的 secret scope,不能枚举 namespace 内所有 Secret。
## Secret 分类
| Secret 类别 | 用途 | 默认消费者 | v0.1 规则 |
| --- | --- | --- | --- |
| Postgres DSN | manager 连接 durable store | `agentrun-mgr` | 只通过 `agentrun-v01-mgr-db/DATABASE_URL` 注入。 |
| Codex stdio profile 凭据文件 | 真实 Code Agent backend 调上游模型 | runner 或 backend adapter | `codex``deepseek` 均使用 `auth.json`/`config.toml` 文件形态,只通过 profile-scoped Kubernetes SecretRef 文件投影注入,不写入 run payload。 |
| Git SSH deploy key | Tekton checkout source/GitOps promotionArgo 读取 GitOps branch | Tekton、Argo CD | 只存在于 `agentrun-ci``argocd` Secret;不进入 runtime Pod。 |
| Registry credential | push/pull private registry | Tekton、runtime imagePullSecret | 只作为 ServiceAccount/imagePullSecret 引用。 |
| Future tenant credential | tenant 专属工具或外部服务 | runner/backend adapter | 必须先定义 SecretRef 和 secret scope,再允许 run 引用。 |
## 固定命名建议
| 对象 | v0.1 建议 |
| --- | --- |
| Manager DB Secret | `agentrun-v01-mgr-db` key `DATABASE_URL` |
| Codex Provider Secret | `agentrun-v01-provider-codex` keys `auth.json``config.toml` |
| DeepSeek Provider Secret | `agentrun-v01-provider-deepseek` keys `auth.json``config.toml` |
| Provider projection target | 只读 `/var/run/agentrun/secrets/<profile>-<index>/auth.json``config.toml`,再复制到当前 run/profile 的 writable `CODEX_HOME` |
| Provider config | 非敏感 base URL/model 可以来自 `config.toml` 或 ConfigMapcredential value 不得放入 ConfigMap。 |
| Tekton Git SSH Secret | `agentrun-ci/agentrun-git-ssh` |
| Argo Git SSH Secret | `argocd/agentrun-git-ssh` |
| Runtime ServiceAccount | `agentrun-v01-mgr``agentrun-v01-runner` |
命名可以在实现时因集群约束调整,但必须满足 lane 独立、用途单一、最小 RBAC 和不跨 `v0.1`/`v0.2` 复用的原则。
## Codex 测试凭据注入
`v0.1` 综合联调使用的 Codex stdio profile 测试凭据源固定为 operator 环境中的文件形态:
```text
~/.codex/auth.json
~/.codex/config.toml
```
这两个文件只能作为 Kubernetes Secret 创建或轮换的输入源。`codex` profile 默认使用 operator 当前 Codex 配置;`deepseek` profile 使用 operator 准备的 DeepSeek-compatible Codex 配置,可以来自另一个 `--codex-home` 或显式 `--auth-file`/`--config-file`。禁止把宿主机 `~/.codex` 以 hostPath 挂入 runner/backend Pod,禁止复制进镜像,禁止提交到 source branch、GitOps branch、artifact catalog、issue、PR、event、trace、日志或 CLI 输出。
默认 Secret projection 规则:
| 项目 | v0.1 规格 |
| --- | --- |
| Kubernetes Secret | `agentrun-v01/agentrun-v01-provider-codex``agentrun-v01/agentrun-v01-provider-deepseek` |
| Secret key | `auth.json`,来自 `~/.codex/auth.json` |
| Secret key | `config.toml`,来自 `~/.codex/config.toml` |
| Projection path | 只读 Secret projection 挂到 `/var/run/agentrun/secrets/<profile>-<index>/auth.json``config.toml`;该路径只作为 credential source。 |
| Runtime config path | runner 启动时把当前 `backendProfile` 授权的 Secret projection 复制到 writable `CODEX_HOME`Kubernetes Job 默认可以使用该 Job 独占的 `/home/agentrun/.codex/auth.json``config.toml`;复用进程必须使用 run/profile 独占目录。 |
| Projection mode | 只读,建议 `0400` 或等价最小权限 |
| Runtime env | `HOME=/home/agentrun``CODEX_HOME=/home/agentrun/.codex``AGENTRUN_CODEX_SECRET_HOME=<projection path>`;不得 fallback 到节点宿主机 home。 |
Secret 创建和轮换必须通过 Kubernetes 密钥管理完成。`deploy/deploy.json` 只写 SecretRef 名称、key 和 mount intent`v0.1-gitops` rendered manifests 只引用 Secret,不包含 Secret data。
## Run secretScope 合同
Run 的 `executionPolicy.secretScope` 只能包含引用,不包含值。示例形态:
```json
{
"providerCredentials": [
{
"profile": "codex",
"secretRef": {
"namespace": "agentrun-v01",
"name": "agentrun-v01-provider-codex",
"keys": ["auth.json", "config.toml"],
"mountPath": "~/.codex"
}
},
{
"profile": "deepseek",
"secretRef": {
"namespace": "agentrun-v01",
"name": "agentrun-v01-provider-deepseek",
"keys": ["auth.json", "config.toml"],
"mountPath": "~/.codex"
}
}
],
"allowCredentialEcho": false
}
```
规则:
- `allowCredentialEcho` 必须固定为 `false`
- `secretRef.namespace` 默认只能是 run 所在 lane namespace 或明确批准的 platform namespace。
- manager 可以保存 `secretRef`,但不得读取 Secret 值后存库。
- runner/backend adapter 获得 Secret 的方式必须来自 Kubernetes env/file projection 或受限 Secret API 读取;Codex 默认从只读 Secret projection 复制 `auth.json``config.toml` 到 writable `CODEX_HOME` 后启动 app-server,不得通过 run payload、event、CLI 参数或日志传递。
- runner/backend adapter 只能选择与 run `backendProfile` 同名的 provider credential`backendProfile=deepseek` 缺少 `deepseek` SecretRef 时必须 `secret-unavailable`,不得 fallback 到 `codex`
- Secret projection 不能直接作为 `CODEX_HOME`。Codex app-server 会读取并可能维护默认配置、PATH 或运行态文件;把只读 Secret volume 直接挂到 `CODEX_HOME` 会造成启动期写入失败。v0.1 的固定边界是:Secret volume 只读、`/home/agentrun``emptyDir` 提供可写 runtime home、复制动作只发生在 runner/backend 容器内且不打印文件内容。
- SecretRef 不存在或 RBAC 不允许时,run 必须失败为结构化 `failureKind=secret-unavailable` 或等价错误,不得降级成无凭证重试风暴。
## 分发路径
`v0.1` 默认路径:
```text
deploy/deploy.json
-> declares SecretRef names and mount/env intent only
Tekton promotion
-> renders SecretRef references into v0.1-gitops manifests
Argo CD
-> syncs workload references to agentrun-v01
Kubernetes Secret
-> created from profile-specific auth.json and config.toml by operator or approved secret-management flow
runner/backend Pod
-> receives Codex auth/config via read-only file projection
-> copies authorized files into writable CODEX_HOME before starting Codex app-server
```
Secret 创建和轮换不由 source branch 自动生成;source branch 只声明需要哪个 SecretRef。后续如果接入 External Secrets、Vault、SealedSecrets 或 SOPS,必须新增或更新本 spec,明确 controller、source of truth、rotation 和 redaction 规则。
## Codex Secret dry-run 工具
`v0.1` 提供只读 CLI 工具,用 operator 本地 `~/.codex/auth.json``~/.codex/config.toml` 形态的文件构造 Kubernetes Secret 创建计划:
```bash
./scripts/agentrun secrets codex render --dry-run [--profile codex|deepseek]
```
可选参数:
- `--codex-home <dir>`:覆盖默认 `~/.codex` 输入目录。
- `--profile <name>`:默认 `codex``deepseek` 使用同一文件形态但默认 Secret name 为 `agentrun-v01-provider-deepseek`
- `--auth-file <path>` / `--config-file <path>`:分别覆盖输入文件路径。
- `--namespace <name>`:默认 `agentrun-v01`
- `--secret-name <name>`:默认随 profile 变化,`codex``agentrun-v01-provider-codex``deepseek``agentrun-v01-provider-deepseek`
输出必须是 JSON,并且只包含 `namespace``secretName``keys`、每个输入文件的 `bytes``sha256`/`contentHash`、整体 hash、redaction 状态、apply 命令形状和 Secret manifest 摘要。输出不得包含 Secret value、`auth.json` 明文、`config.toml` 明文、base64 `data` 字段或可直接恢复 credential 的内容。工具只支持 `--dry-run`;不得执行 `kubectl apply`
失败必须结构化返回 `failureKind`:缺文件、不可读文件或空 credential 归类为 `secret-unavailable`;非法 JSON/TOML 归类为 `schema-invalid`
## 日志与事件 Redaction
- event、trace、日志、CLI 输出、health 和 diagnostics 不得打印 Secret 值。
- `Authorization``api_key``token``password`、URL credential、DSN password、Codex `auth.json``config.toml` 文件内容必须 redacted。
- 可以打印 SecretRef 名称、key 名称、credential source、是否存在、是否被挂载、是否通过 readiness 检查。
- provider auth 失败只能报告 failure kind、HTTP status 分类和 request id;不得打印请求 header 或 body 中的凭据。
## 测试规格
### T1 SecretRef render
阅读本文和 [spec-v01-cicd.md](spec-v01-cicd.md),然后检查 `deploy/deploy.json` 只包含 SecretRef 名称/key 和 mount/env intentrendered GitOps manifest 也只包含 SecretRef,不包含 Secret data。
### T2 Runner credential projection
阅读本文,然后分别启动 `backendProfile=codex``backendProfile=deepseek` 的最小 backend runner dry-run,确认 Pod file projection 挂在 `/var/run/agentrun/secrets/...` 且只读,`/home/agentrun` 是 writable runtime homerunner/backend 只把当前 profile 授权文件复制到 `CODEX_HOME` 后再启动 Codex;event、日志和 CLI 输出只显示 redacted credential source,不显示文件内容。
### T3 Missing secret failure
阅读本文,然后用一个不存在的 provider SecretRef 创建 run,确认 run 失败为结构化 `secret-unavailable`,不会打印 Secret 值,也不会无限重试。
## 规格的实现情况
| 规格项 | 状态 | 说明 |
| --- | --- | --- |
| Secret 分发规格 | 已定义 | 本文为 v0.1 provider credential 分发权威。 |
| Kubernetes SecretRef 注入 | 已实现/已通过主闭环 | runner Job dry-run 和正式 Job 创建路径已按 run `executionPolicy.secretScope.providerCredentials` 生成 Secret volume projection、writable runtime home 和 `AGENTRUN_CODEX_SECRET_HOME`;真实 Secret 与 Codex turn 已通过主闭环。 |
| Codex Secret dry-run 工具 | 已实现 | `./scripts/agentrun secrets codex render --dry-run` 只输出 Secret 创建计划、hash 和 redacted manifest 摘要,不执行 apply。 |
| Codex auth/config file projection | 已实现主路径 | backend readiness 检查 `auth.json`/`config.toml` 可读性,缺失时返回 `secret-unavailable`;真实 runner Job 将只读 projection 复制到 writable `CODEX_HOME`。 |
| DeepSeek profile SecretRef | 已定义/待实现 | 需要新增 `agentrun-v01-provider-deepseek` render、Job projection、profile 选择和负向 missing-secret 验收。 |
| redaction 最小规则 | 已实现主路径 | Secret dry-run 工具、event、Job dry-run 输出、self-test 和真实主闭环均不打印 Secret value;复杂审计按 [spec-v01-validation.md](spec-v01-validation.md) 人工抽查。 |
| 外部 secret manager | 未采用 | 如需 Vault/ExternalSecrets/SOPS,后续单独更新规格。 |