详解:access-token端点设计全指南)
background-agents模型供应商账号中介Broker详解access-token端点设计全指南【免费下载链接】background-agentsAn open-source background agents coding system项目地址: https://gitcode.com/GitHub_Trending/ba/background-agents在开源项目background-agentsOpen-Inspect中模型供应商账号中介 broker 负责为沙箱安全签发模型访问凭证而access-token端点正是这条凭证链路的入口。本文面向新手用最少代码讲清楚为什么需要 broker、access-token 端点如何鉴权、令牌刷新为何要排队以及它和 runtime-credential 端点的分工。为什么需要中介先理解凭证隔离问题 background-agents 是一个后台编码 Agent 系统用户在网页上描述需求系统在云端沙箱里启动 AI 编码代理干活。这里有个天然矛盾AI 订阅凭证OpenAI、xAI 等是长期有效的敏感资产泄露代价极高沙箱是执行代码的隔离环境必须能用这些凭证才能调用模型。如果把长期凭证直接塞进沙箱环境变量任何一个有代码执行能力的 Agent 都可能把它读走。background-agents 的解法是凭证中介broker架构长期凭证只存放在控制面control-plane并整体加密沙箱每次需要访问模型时向access-token端点申请一枚短命访问令牌用完即弃。这个设计的完整背景记录在 provider-accounts.md 中其中Broker Architecture一节是端点设计的权威说明。access-token 端点一个 provider 中立的沙箱接口核心路由只有一行定义在 model-provider-accounts.tsPOST /sessions/:id/provider-auth/:provider/access-token它的巧妙之处在于provider 中立OpenAI、xAI 走同一条路由而不是各自维护一个端点。请求处理逻辑handleProviderAccess做了四步判断步骤判断结果1用沙箱身份查 D1 中该会话绑定的认证行未配置 →4042认证模式是legacy_scoped_oauth转交旧版刷新器兼容处理3认证模式是api_key409该走密钥注入不该走 broker4账号模式调用ModelProviderAccountBroker.getAccess()签发令牌一个关键安全细节沙箱不能自己指定用哪个账号。它只能提交会话 ID provider真正绑定哪个账号 ID 由创建会话时写入的不可变认证行决定。这堵死了沙箱探测其他账号的路径——这正是文档里sandbox cannot submit a provider-account ID要表达的意思。鉴权边界只认沙箱不认人 ️该路由通过admit()挂载了SCM_AGNOSTIC_SANDBOX_ROUTENO_AUTHORIZATION见 shared.ts含义是调用者必须是该会话对应的沙箱身份sandbox principal携带别的沙箱 ID 直接被拒普通用户或服务凭证一律拒绝——账号列表、凭证读取对人类用户有独立的管理端路由沙箱只能走这条消费端响应统一加Cache-Control: no-store成功或失败都不允许被缓存防止令牌经缓存层扩散。Broker 内部三步拿到访问令牌ModelProviderAccountBroker 的getAccess()是整个系统的心脏流程可以概括为校验账号可用性账号必须存在、provider 匹配、状态为active未禁用、未归档优先用缓存令牌加密凭证里可能已缓存 access token若剩余有效期超过 provider 的刷新缓冲refreshBufferMs直接返回不打扰上游需要刷新时领取锁再刷新通过数据库的条件更新原子地声明我要刷新了exchange_state: idle → in_flight只有领取成功的进程才真正调用 provider 的刷新接口。第 3 步是设计中最精彩的部分。为什么刷新要排队旋转式刷新令牌的并发难题 ⏳OpenAI 这类 provider 采用旋转式刷新令牌旧的 refresh token 用完即失效必须原子地持久化新值。如果两个控制面进程同时刷新A 用旧 refresh token 换到新令牌 T1成功持久化B 也拿旧 refresh token 去换 → 上游报已失效旧令牌被白白消费账号被迫重连。background-agents 用数据库行上的持久租约解决这个问题SQL 片段见 provider-accounts.md 的Concurrency and Rotation一节实现核心在 claimed-provider-credential-exchange.ts抢锁UPDATE ... SET exchange_statein_flight WHERE credential_version? AND exchange_stateidle恰好一个进程赢落败者轮询败方不重试刷新而是短暂 sleep 后重读数据库等赢家把新凭证写回claim_unavailable分支默认 100ms 间隔完成赢家用匹配的owner generation version条件更新一次性写入新凭证并释放锁超时兜底in_flight标记超过 15 秒DEFAULT_EXCHANGE_TIMEOUT_MS视为模糊交换走 fencing 把账号标记为reconnect_required宁可靠人工重连也绝不重放已消费的令牌。还有一个容易忽视的失败原则如果刷新成功但新凭证无法落盘broker 不会返回这枚 access tokenreconnect_required错误。因为返回它只是短期成功后续必然全断——文档称之为 fail-closed。access-token 与 runtime-credential一对孪生端点 broker 边界其实有两个沙箱路由按凭证类型分工端点适用 provider交付物特点POST /sessions/:id/provider-auth/:provider/access-tokenOpenAI、xAI短命 brokered 令牌每次请求按需签发/刷新POST /sessions/:id/provider-auth/:provider/runtime-credentialClaudeAnthropic setup token存储型静态令牌每次 bridge 启动交付一次后者实现在 provider-runtime-credentials.ts文件头注释写得很清楚access-token 路由per request 铸一枚短命令牌runtime-credential 路由则把存储的静态密钥本身交给沙箱。它同样要求账号 active、解密发生在所有校验之后并带 1 小时过期缓冲EXPIRY_GUARD_MS过期即条件式标记reconnect_required。这种按凭证类型分发的设计让新增 provider 时只需注册 adapter 声明其runtimeCredentialKind路由层无需改动。新手速览这套设计值得借鉴的 4 个点 ✅长期凭证永不出控制面沙箱只能按会话→账号的不可变绑定取短命令牌凭证泄露面被压到最小单一路由 类型分发provider 中立端点 适配层adapter registry避免每家 provider 各开一个端点的蔓延数据库即分布式锁用一条条件UPDATE实现跨进程互斥不依赖特定平台的 Durable Object可移植到任何事务型存储fail-closed 优先于可用性模糊结果可能已消费旋转令牌、落盘失败一律导向重连用一次人工操作换取凭证状态绝对正确。如果你想动手读源码建议按这个顺序先看 provider-accounts.md 的 Broker Architecture 与 Concurrency 两节建立全局再读 model-provider-account-broker.ts主流程、claimed-provider-credential-exchange.ts抢锁/完成/失败分支最后对照 model-provider-accounts.ts 的端点接线测试用例model-provider-account-broker.test.ts则覆盖了exchange_busy、reconnect_required等每种错误码的路径。【免费下载链接】background-agentsAn open-source background agents coding system项目地址: https://gitcode.com/GitHub_Trending/ba/background-agents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考