Repository navigation
[Grok/dsh 75] 组织身份连接远程工作区 #207
Copy link
Copy link
Closed
Labels
ready-for-agentAgent-grabbable workAgent-grabbable work
Description
Activity
- added a commit that references this issue
on Sep 25, 2026 已实现并快进推送到
rewrite/grok-dsh-20260920:bced29083d2a7f1212b83bb01e8fb7e88ed43e3b(快进范围5b300a8..bced290)。Rebase 说明:分支起点是
9bd0449(#191)。开发期间 #206(5b300a8,deep-research workflow)先合入,rebase 一次,没有冲突,两边的新增都保留了。#173 这期间没有推送。下列检查都在最终基线上重跑。做法:可部署的身份服务替身,不伪造官方设施
参考实现把已登录的组织 bearer 发给官方 Computer Hub。这里没有官方 Hub、SSO 或付费账号,所以映射为:组织自己部署的 OpenID Connect 服务(用真实的 Ory Hydra v26.2.0 验证,Apache-2.0,sqlite 版本,按发布页 checksums 校验)加上 #190 的 SSH 远端。组织的共享远端主机把组织密钥限制为强制命令(restrict,command="…/org-agent.sh"),这个密钥能到达的只有codsh --rust agent --leader stdio。实现内容
- 远端策略(新文件
rust/src/remote_identity.rs):requirements.toml(或managed_config.toml)中的[remote_access] identity = "required",加上issuer、audience、introspection_url(RFC 7662;https 或回环 http;官方 x.ai/grok.com 端点拒绝;可选introspection_client_id+ 只有属主可读的introspection_secret_file,Basic 认证)、teams、deny_subjects、recheck_secs(默认 30)、locked+lock_message、applies_to = "all"。优先级是 requirements > managed > user,用户的config.toml写identity = "off"无效。策略不完整或读不出来时,所有连接都拒绝(fail closed)。remote_access/remote_identity已加入策略键白名单。 - 远端网关(在
agent --leader stdio代理里):认证之前只放行initialize和authenticate(方法codsh-org-identity,令牌放在_meta."codsh/identity",由网关自己处理,不会转发给 leader)。其余请求都回-32000并带data.reason。initialize结果会注入authMethods(issuer、audience、teams),并在认证前去掉liveSessions。令牌要被 introspection 报告为 active,issuer 必须存在且一致,audience 一致,团队在允许列表中,而且不能是 refresh token。认证之后每个请求都重新向身份服务确认,连接期间还有定时复查。过期、在身份服务处撤销(包括codsh --rust logout)、deny_subjects、locked、连接中途换主体、连续 3 次认证失败,都会发出_codsh/remote_access_revoked、在 leader 上取消这个连接启动的轮次,然后断开。身份服务不可达或返回非 JSON 时拒绝;不跟随重定向。 - 客户端(
acp.rs、main.rs):只有 UI 登录状态不授予任何远程访问。codsh --rust login的会话只发给[[remote_identity]] target = "ssh://host[:port][/path]"中列出、audience与远端要求一致的目标(按完整路径段匹配)。issuer 也必须一致;如果 JWT 的aud指向别的受众,就不发送。每个请求前都重新读取 auth.json:会话刷新后重新认证,会话被清除或无法刷新时,请求在发出前就停下。空闲时令牌快过期会自动续期。收到撤销通知后显示原因,标记为断开,/reconnect会重新认证。remote check(含--json的identity字段)和/remote会显示是否要求身份、结果、主体和团队,或拒绝原因。 - 审计:两端都写只有属主可读的 JSONL(客户端
remote-identity.log,主机remote-access.log,1 MiB 轮转),记录用途(audience/issuer)、目标及其配置来源、主体、团队、结果,以及令牌 SHA-256 的前 12 位十六进制指纹,从不记录令牌本身;错误信息也不含令牌。 - 要求身份的主机会拒绝远程克隆(
--codsh-remote-lifeline,退出码 2),因为普通 ssh 命令无法携带身份。没有策略的远端行为与 [Grok/dsh 58] 远程工作区连接与执行 #190 完全相同。 CODSH_SHELL_SLEEP加入 dsh 子进程环境白名单(mock 模型的测试参数,之前实际没有传过去)。- 文档:README 中英文(映射、配置、限制)、CONTEXT.md、CONTRIBUTING.md(Hydra 下载、校验、
CODSH_TEST_HYDRA)、packages/cli/README.md、remote --help、changeset。
验收对照
- 组织认证明确映射到远程连接,只有 UI 登录不会授权:有测试覆盖“已登录但目标未配置,什么都不发送”和“不认证的客户端被拒”。
- 过期、组织/团队不匹配、撤销、重连和管理员锁定都作用在真实请求上:有 Hydra 签发的短期令牌、Hydra 撤销、logout 撤销、
deny_subjects/locked,以及轮次进行中被撤销后远端命令被取消。 - 用途和发送边界可审计;令牌不能被另一个配置的目标复用(beta 令牌客户端不发给 alpha,强行发送时远端按 audience 拒绝;issuer 不匹配时客户端和远端都拒绝);错误里不含令牌。
- 端到端用可部署的身份服务(Hydra + 组织登录/授权应用)和远端服务(真实 OpenSSH + 真实 dsh)验证;普通的 [Grok/dsh 58] 远程工作区连接与执行 #190 显式远程认证不依赖本票。
检查(干净环境、最终基线
bced290)cargo fmt --check通过;pnpm typecheck通过。- clippy
-D warnings:只有两处已存在的filesystem_sandbox(tail_marker、needless_return)报错;加-A dead_code -A clippy::needless_return后无告警。 cargo test --workspace --no-fail-fast:bin 632 通过、4 失败(含新增 7 个remote_identity单元测试,其中一个用本机 introspection 端点验证 Basic 认证、secret 文件权限、refresh token 和缺少 issuer 的拒绝);其余 crate 498 + 42 + 61 + 2 + 379 + 61 全部通过,2 个 ignored。4 个失败都是已存在问题,涉及的文件本票都没改:filesystem_sandbox2 个,以及privacy::drafts_stay_local…和voice::substitute_route…(这两个测试捕获的 HTTP 请求体不完整,这次单独重跑也失败)。pnpm test(带CODSH_TEST_OPENSSH、CODSH_TEST_HYDRA):99 个文件,2533 通过、2 跳过、1 失败。失败的是reference-evidence(负载下 5 秒超时),用--testTimeout=60000单独重跑 11/11 通过。新增的scripts/rust-remote-identity.spec.mjs6/6 通过(真实 Hydra + 真实 sshd + 真实 dsh);rust-remote.spec.mjs和rust-clone.spec.mjs也通过。- PTY(Linux,
pnpm run build:rust之后):rust-remote-pty-test.py通过。rust-auth-pty-test.py只在 macOS 上运行,这里按设计退出,没有跑。本票没有新增 PTY 脚本。 - 全部在本机回环上运行,没有使用付费服务或官方设施。
未验证 / 限制
- 没有官方 Computer Hub、SSO 或付费组织账号;只验证了 Hydra 这一个真实的 OIDC 实现。
- 只在 Linux 上验证,macOS 和 Windows 未验证。
- Hydra 的设备码端点路径与 codsh 的
/oauth2/device/code不一致,所以测试用的是回环 PKCE 登录,没有覆盖设备码登录。 - 检查位于 codsh 的 leader 代理中:能开 shell 的密钥可以绕过,必须用强制命令部署(README 已写明)。
agent serve套接字不受网关约束。 - 撤销只取消本连接启动的轮次;之前某个已关闭连接留下、仍在运行的轮次,不会因为之后的撤销而停止(主机上
codsh --rust leader kill可以停止)。 - 团队来自令牌里的 claim;目录中的团队变更要等下一次签发的令牌才生效。
- 需要 client 认证的 introspection 端点只用本机测试端点验证过,没有对真实 IdP 验证。
- 没有修改 inventory。
- 没有改 main、npm 发布和默认版本;没有编辑 PR test(reference): pin Grok provenance and compatibility inventory #213(它的 head 就是集成分支,会随推送自动更新)。
#207 阻塞的只有 #211,它仍被其他 11 个未关闭的票阻塞(其中 #206 已合入但还没关闭),所以本票关闭后没有新解锁的后续票。
- 远端策略(新文件
Metadata
Metadata
Assignees
Labels
ready-for-agentAgent-grabbable workAgent-grabbable work
Parent
#132
Ticket: 75
Status: ready-for-agent
User Stories: 36, 60, 61(见父规格)
What to build
已配置组织身份的用户连接远程 dsh 工作区时,登录、组织限制和凭据撤销实际作用于远端访问。
Acceptance criteria
Blocked by
Delivery contract
用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。