Skip to content

官方 OAuth 改为槽终端登录 - #615

Merged
dofastted merged 9 commits into
mainfrom
feat/slot-oauth-login
Oct 19, 2026
Merged

dofastted merged 9 commits into
mainfrom
feat/slot-oauth-login

Conversation

@dofastted

@dofastted dofastted commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Anthropic 普通 OAuth 的 Claude Code 方式改为在已运行的槽容器里执行 claude auth login。容器未运行或 cli-node 未安装时不打开登录。
  • 面板弹出槽终端,shell 就绪后自动执行登录。授权链接在终端复制,授权码由用户直接粘贴,面板不再中转。
  • 新槽没有 credentials.json 时,打开登录终端前先创建空文件,并把官方 .credentials.json 链接到它。官方 CLI 写入后,worker 和面板读同一份。
  • 宿主机不再自己构造 claude_code 授权链接。Cookie 导入和 Setup Token 保持原路径。

Test plan

  • node --test test/unit/claude-auth-login.test.mjs test/unit/oauth-auth-url.test.mjs test/unit/slot-shell-rc.test.mjs
  • node --test --test-name-pattern 'claude_code|generate-auth-url then|setup token' test/e2e/panel-api.e2e.test.mjs
  • pnpm -C web exec tsc --noEmit --pretty false
  • 新槽登录:空 credentials.json 经 .credentials.json 链接写入后,worker 能读到 refresh token
  • 真实槽容器里打开官方登录终端,复制链接并粘贴授权码

Note

High Risk
Changes authentication and OAuth credential handling (new session lifecycle, credential reads, and routing); mistakes could block login or mishandle tokens.

Overview
Claude Code OAuth no longer uses host-built authorize URLs. For flavor claude_code, the panel starts an in-slot claude auth login session (container running + cli-node required) via a new PTY helper and claude-auth-login.mjs; PKCE, the CAI link, and token exchange stay inside the official CLI. Host generateAuthUrl now errors on claude_code, and exchange-code routes through completeClaudeAuthLogin when appropriate.

Panel UX shifts to the slot terminal. Users can open a dialog with WsTerminal (login=1 / KIN_PANEL_LOGIN) so claude auth login runs after the shell is ready; the authorize link and pasted code stay in the terminal instead of the credential form. The PTY path still supports feeding codes from code.inbox for API-driven completion and copies full OAuth from the CLI’s credentials file with scope checks.

Supporting changes: cli-node-guard whitelists KIN_AUTH_LOGIN=1; tests and e2e expectations updated to reject pre-container login and document the new flow. Cookie import and setup-token paths are unchanged.

Reviewed by Cursor Bugbot for commit 2fc774c. Configure here.

容器运行且 cli-node 已安装后,claude auth login 自己生成链接并换票。宿主机不再构造 claude_code 授权链接。
授权码由用户直接粘进终端,不再由面板中转。

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2fc774c. Configure here.

) : null}
</div>
</DialogContent>
</Dialog>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Terminal login never commits OAuth

High Severity

Claude Code login now only opens a slot terminal and runs claude auth login. It never calls generate-auth-url / exchange-code, so completeClaudeAuthLogin and commitImportedOauth never run. The CLI writes ~/.claude/.credentials.json, while the Go worker only owns credentials.json. The slot stays without imported tokens, identity, or schedulability after a successful paste.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2fc774c. Configure here.

dofastted and others added 5 commits October 19, 2026 23:17
没有 credentials.json 时先建空文件,再把官方 .credentials.json 链过去,避免登录写到 worker 读不到的独立文件。
Co-authored-by: ted <kuhlmangarry24@gmail.com>
集群节点、未运行容器和缺少 cli-node 的槽不能打开官方登录终端。凭证链接失败时终端不再继续启动。
Co-authored-by: ted <kuhlmangarry24@gmail.com>
普通运维 ticket 即使带 login=1 也不能升级成官方登录终端。

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Agentic Security Review 发现两处高危沙箱逃逸:槽内可写的 bind-mount 控制文件被宿主机以特权身份信任。

Open in Web View Automation 

Sent by Cursor Security Agent: Security Reviewer

for (const pid of [ptyPid, childPid]) {
if (pid && pidAlive(pid)) {
try {
process.kill(pid, 'SIGTERM')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Agentic Security Review
Severity: HIGH

stopClaudeAuthLoginSession 会读取 vms/<id>/run/auth-login 下的 pty.pid / child.pid,并对这些 PID 发送 SIGTERM/SIGKILL,而不校验它们是否真是本次拉起的 python PTY 或 docker exec。该目录经 /run/kin bind-mount 进入槽容器,且 run/ 会被 chown 给槽用户;槽内进程可以预先创建 auth-login 并写入任意宿主机 PID。控制面 systemd unit 未设 User=,通常以 root 发信号,可杀掉 PID 1、dockerd 或其他宿主机进程。同一可写目录里的 status.json 也可被改成钓鱼 auth_url,在植入的 PID 仍存活时被当成可复用会话。

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 748da4d. Configure here.

if (!fs.existsSync(workerFile)) {
if (!create) return { wrote: false, error: 'worker credentials.json missing' }
fs.mkdirSync(claudeDir, { recursive: true, mode: 0o700 })
fs.writeFileSync(workerFile, '{}\n', { mode: 0o600 })

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Agentic Security Review
Severity: HIGH

新增 create: true 路径用 existsSync + writeFileSync 创建 credentials.json,二者都会跟随符号链接。本地槽把整个 cli-home bind 到 /home/kincli,没有集群节点上那种把 ~/.claude 嵌套挂成宿主机目录的保护。槽内可以把 credentials.json 换成指向宿主机路径的悬空 symlink;打开官方登录终端时,特权宿主机助手会把 { } 写到链接目标(随后还可能 chown 给槽 uid),从而在沙箱外创建或覆盖文件。

Fix in Cursor Fix in Web

Reviewed by Cursor Security Reviewer for commit 748da4d. Configure here.

shell 只负责拿到票。会话结束时写入槽唯一使用的 credentials.json,并删除官方 CLI 的临时副本。
shell 拿到的票交给 commitImportedOauth。导入后 .credentials.json 继续链接到 worker 的 credentials.json,终端和槽使用同一份。
@dofastted
dofastted merged commit 3054cb8 into main Oct 19, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants