This repository has been archived on 2026-09-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
workload-sts/AGENTS.md
T

108 lines
6.5 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.
# workload-sts - AI Agent Guide
## Specification-Driven Development
- 所有新功能和外部可观察行为变更都采用 specification-first:先更新
`docs/specification.md` 或对应设计文档,再编写实现。
- 规格必须在实现前说明范围、非目标、协议行为、验证规则、失败语义、安全边界和验收
标准,并达到可由人工作出待决策选择的详细程度。
- 规格处于 `Review` 时,只能完善设计、测试计划和不冻结实现的实验;获得人工批准前,
不得把待决策项当成已确认合同实现。
- 从批准的验收标准派生测试,再实现使测试通过的最小纵向切片。
- 实现过程中发现歧义或需要改变已批准行为时,先停止实现,更新规格并重新请求 review。
- 规格描述外部合同和设计决策;除非构成兼容性合同,不要过早固定 Go package、函数名、
SQL schema 或内部模块结构。
## Project Boundary
本项目只负责:
```text
验证上游 workload credential
-> 映射规范化 principal
-> 判断是否允许为目标 audience/scope 签发
-> 签发短期 JWT assertion
```
以下内容不属于本项目:
- OpenBao secret、policy、client token、lease、renewal 和 revocation;
- Kubernetes RBAC 和 ServiceAccount 生命周期;
- Gitea Actions job、runner 和 workflow 调度;
- PVE/microVM 生命周期、vsock metadata 和平台 attestation;
- 人工用户目录、密码、MFA 和交互式登录。
不要为了完成下游集成而把这些职责拉入 workload-sts。需要时只定义标准协议边界和测试
替身。
## Protocol and Identity Rules
- 优先实现并复用 OAuth 2.0、RFC 8693、JWT、SPIFFE 和 Kubernetes 的标准语义;不得在
有成熟标准或库可用时发明私有协议、token 格式或表达式解析器。
- OAuth issuer 固定为 `https://identity.ad.ddupan.top`;变更 issuer 是破坏性迁移,必须
先形成单独规格和迁移计划。
- SPIFFE 是未来可接入的上游身份协议;第一阶段不把内部 principal 表示成 SPIFFE ID,
也不以 URI 命名代替真正的 SVID 验证。
- 严格区分上游 credential audience 与输出 JWT audience。Kubernetes SA JWT 用于向
workload-sts 证明身份;workload-sts JWT 用于访问 OpenBao、Kubernetes 或其他明确的
Resource Server。
- 客户端不能控制输出 `sub`、任意 claims、签名算法或最大 TTL。
- `client_id` 必填且没有默认值。v1 中它是未经认证的调用方自报审计标签;不得用于
principal mapping、授权、输出 claims 或 metric label。未来启用 client authentication
时继续使用同一字段,不通过省略字段表达匿名或默认 client。
- `client_id` 必须匹配 `^[a-z0-9](?:[a-z0-9-]{1,61}[a-z0-9])$`,即长度 3–63,且中横线
不能位于首尾。不得在不同入口使用更宽松的验证规则。
- trust binding 至少绑定 credential type、issuer/verifier 和 source subject;不能只按
`sub` 建立跨 issuer 信任。
- SA trust binding 中的 issuance rule 限制 principal、audience 和 scope,并直接绑定唯一
token profile;CEL 只处理经过验证的类型化上下文条件。客户端不能请求 profile。CEL
错误必须失败关闭。
- 面向 OpenBao 的 JWT 只是登录 assertion。不得在 workload-sts 中调用 Bao 登录接口或
管理随后签发的 Bao token。
## Security-Critical Handling
- subject token、输出 JWT、Authorization header、OAuth client secret、OpenBao token、
mTLS 私钥和签名私钥不得进入日志、metric、trace、数据库、测试快照或错误消息。
- 禁止记录 token endpoint 请求/响应体原文。审计只记录 request ID、受控 issuer/verifier
ID、principal、audience、批准后的 scope/profile、policy version、结果和输出 `jti`。
- JWT verifier 必须校验配置的 issuer、允许算法、signature、audience、`exp` 和 `nbf`;
禁止只 decode 不 verify。
- discovery/JWKS URL 必须由管理员配置。不得根据未验证 token 的 header 或 claim 动态
获取任意 URL。
- 未知 issuer、principal、audience、scope、profile、`kid` 或算法必须拒绝;依赖不可用
时失败关闭,不得签发降级 token。
- 测试必须使用明显的假 token 和独立密钥。不得复制 homelab 的真实 ServiceAccount
token、SVID、OpenBao token 或 OAuth 凭据到仓库和测试 artifact。
- 生产签名私钥不得存入数据库或普通配置。workload-sts 可以使用自己的 Kubernetes
identity 获取最小权限 Bao 运行凭据来调用 Transit;不得与客户端的 Bao token 混淆。
签名后端与轮换合同以已批准规格为准。
## Documentation Responsibilities
- `README.md` 是项目入口,只描述当前能力、边界和文档导航,不替代规范。
- `docs/specification.md` 是外部行为、验收标准和已确认决策的权威来源。
- `docs/architecture.md` 解释组件与信任边界;与规范冲突时以规范为准。
- `docs/security.md` 记录威胁、缓解措施和发布前安全验收。
- 已确认决策与待批准决策必须分开。不要把提案、候选默认值或 PoC 结果写成既定事实。
- 修改协议或 claim 合同时,同时检查 README、architecture、security 和测试是否需要同步。
## Human-Reviewable Changes
- 每次改动聚焦一个行为或决策,不混入无关重构、依赖升级、格式化或清理。
- 保持每个提交边界可独立 review,并在可行时保持构建和相关测试通过。
- 达到一个完整提交边界时,先询问用户是否创建 commit;不要未经明确授权提交或推送。
- 创建或提交 PR 前必须再次请求用户明确授权。提交或推送许可不等于 PR 许可。
- commit message、PR、issue 和项目文档默认优先使用中文;代码标识符、命令、配置键、
RFC 名称和使用英文可避免歧义的技术字段可以保留英文。
## Verification
- 文档改动至少运行 `git diff --check`,并检查链接、示例与已确认决策一致。
- 实现改动运行与该纵向切片直接相关的格式化、静态检查和测试;具体命令在工具链确定后
写入本文件及开发文档。
- OAuth2/JWT/SPIFFE 互操作行为必须用真实标准实现或官方测试向量验证,不能只测试项目
自己的 signer 与 verifier 能互相接受。
- 安全相关测试至少覆盖错误 issuer、signature、audience、算法、过期时间、未生效时间、
claim 注入、权限扩大和 token 泄漏。