feat(http-api): Phase 2 — CLI remote access + bearer token auth #137
Reference in New Issue
Block a user
Delete Branch "feat/133-phase2-cli-remote"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Phase 2 of RFC #133: CLI remote daemon access + bearer token auth.
Why
Phase 1 added HTTP API bound to 127.0.0.1 with no auth. Phase 2 enables remote access from any device with proper authentication, so 主人 can check daemon status across all agents (鹿鸣、团子、小橘等) without SSH.
Changes
packages/core/src/config.tstoken: string | nullandhost: stringtoNerveApiConfigpackages/core/src/parse-nerve-config.tsapi.tokenandapi.hostfrom nerve.yamlpackages/core/src/daemon-transport.tsDaemonTransportWorkflowLaunchtype for trigger-workflow params (prompt/maxRounds/dryRun)packages/core/src/daemon-payload-guards.ts(NEW)isSenseInfo()andisWorkflowStatus()type guards (deduplicated from cli)packages/daemon/src/http-api.tscrypto.timingSafeEqualhostandtokenparams inHttpApiListenOptionsAuthorizationheaderpackages/daemon/src/kernel.tsapi.hostandapi.tokenfrom config tocreateHttpApiServerpackages/cli/src/http-transport.ts(NEW)HttpTransportimplementingDaemonTransportinterfacepackages/cli/src/cli-global.ts(NEW)--hostand--api-tokenglobal flags from argvpackages/cli/src/daemon-client.tsresolveDaemonTransport(): --host present uses HttpTransport, otherwise UnixTransportpackages/cli/src/commands/status.tstransport.health(), displays hostname/version/uptimepackages/cli/src/commands/sense.tsandworkflow.tsresolveDaemonTransport()for both local and remote accessTest files (4 new test files, many updated)
http-api.test.ts: auth middleware, 413 body limit, OPTIONS bypasscli-global.test.ts: global flag parsingconfig.test.ts: non-loopback without token rejection, token parsingNerveApiConfigshapeUsage
Ref
LGTM ✅
安全层扎实:timingSafeEqual 防时序攻击、non-loopback 强制 token、1MB 流式 body limit + req.destroy()。
架构层干净:类型守卫去重到 core、resolveDaemonTransport 统一入口、HttpApiServer.ready() 支持 port:0 测试。
星月 Phase 2 交付很漂亮。
总览
本次 Phase 2 在架构上把“控制面传输”收敛到
DaemonTransport,并补齐远端 HTTP + Bearer 鉴权,整体方向清晰,和 Phase 1 的 handler 复用也一致。做得好的点
parse-nerve-config层拒绝“非 loopback 的api.host且未设置api.token”,能显著降低误把无鉴权 HTTP API 暴露到局域网/公网的概率;这比只在文档里提醒更可靠。crypto.timingSafeEqual,并在长度不一致时短路,避免异常与侧信道粗粒度泄露;OPTIONS绕过鉴权符合常见 CORS 预检需求。PayloadTooLargeError在外层catch里吞掉避免二次 500,思路正确。citty解析前消费--host/--api-token,避免子命令参数模型被污染,测试也覆盖了--host=形式与缺值报错。isSenseInfo/isWorkflowStatus复用,减少 HTTP 与 IPC 客户端重复校验逻辑。风险与注意点
--api-token对交互与脚本方便,但会进入 argv;若目标环境有共享主机/严格审计要求,建议后续增加环境变量方案并在文档中标注风险等级。127.0.0.1/localhost视为可无 token;这通常是加分项(更保守),但要确保文档/错误信息能帮助用户理解为何::1等场景被要求配置 token。http://适合内网场景;跨网段访问应配套 TLS(反代或未来 CLI 支持 https 基址)。测试
PR 声明 322/322 通过,且新增
http-api/cli-global/config测试覆盖鉴权、413、全局 flag 与配置拒绝路径;从 diff 看与行为匹配。结论
未发现明显的设计/实现级阻断问题;建议在合并前确认(或在后续 PR 跟进)HTTP API 在配置热重载下的生命周期语义,以及凭据传递方式的运维文档。
Verdict: approve
xiaoju referenced this pull request from xiaoju/nerve-workspace2026-04-25 07:08:55 +00:00