feat(acp): add resumeSessionId to sessions_spawn for ACP session resume#41847
feat(acp): add resumeSessionId to sessions_spawn for ACP session resume#41847onutc merged 3 commits intoopenclaw:mainfrom
Conversation
🔒 Aisle Security AnalysisWe found 2 potential security issue(s) in this PR:
1. 🟡 IDOR risk: sessions_spawn forwards user-controlled resumeSessionId to ACPX/Codex session resume without authorization/validation
DescriptionThe If
Vulnerable flow (high-level):
Vulnerable code: const result = await spawnAcpDirect(
{
task,
label: label || undefined,
agentId: requestedAgentId,
resumeSessionId,
cwd,
mode: mode && ACP_SPAWN_MODES.includes(mode) ? mode : undefined,
thread,
sandbox,
streamTo,
},
{
agentSessionKey: opts?.agentSessionKey,
...
},
);RecommendationAdd authorization and validation before allowing At minimum:
Example (format validation + owner-only gate): import { looksLikeSessionId } from "../../sessions/session-id.js";
import { ToolAuthorizationError, ToolInputError } from "./common.js";
// ... inside execute
const resumeSessionId = readStringParam(params, "resumeSessionId");
if (resumeSessionId) {
if (!looksLikeSessionId(resumeSessionId)) {
throw new ToolInputError("resumeSessionId must be a UUID");
}
// If this tool can be invoked by non-owner senders, require owner or a config allowlist.
if (!opts?.senderIsOwner) {
throw new ToolAuthorizationError("resumeSessionId is restricted to owner senders.");
}
}Stronger approach: maintain a mapping of allowed 2. 🔵 Sensitive resumeSessionId exposed via child process command-line arguments (--resume-session)
DescriptionThe ACPX runtime passes
Vulnerable code: const resumeSessionId = asTrimmedString(input.resumeSessionId);
const ensureSubcommand = resumeSessionId
? ["sessions", "new", "--name", sessionName, "--resume-session", resumeSessionId]
: ["sessions", "ensure", "--name", sessionName];RecommendationAvoid placing sensitive identifiers in process argv. Options (best to worst):
Example approach using an env var (requires // Prefer: acpx reads resume id from env or stdin rather than argv
const env = { ...process.env, ACPX_RESUME_SESSION_ID: resumeSessionId };
spawn(resolved.command, resolved.args /* without resumeSessionId */, { cwd, env });Analyzed PR: #41847 at commit Last updated on: 2026-03-10T09:56:22Z |
Greptile SummaryThis PR adds an optional One logic gap to address:
Confidence Score: 2/5
|
|
Addressed @greptile-apps feedback in 886a3d3:
Good catch — without this, agents that omit |
|
Perfect! The guard implementation looks clean:
This prevents the silent failure where agents would get a fresh session instead of resuming. Good catch and solid fix! ✅ |
Thread resumeSessionId through the ACP session spawn pipeline so agents can resume existing sessions (e.g. a prior Codex conversation) instead of starting fresh. Flow: sessions_spawn tool → spawnAcpDirect → initializeSession → ensureSession → acpx --resume-session flag → agent session/load - Add resumeSessionId param to sessions-spawn-tool schema with description so agents can discover and use it - Thread through SpawnAcpParams → AcpInitializeSessionInput → AcpRuntimeEnsureInput → acpx extension runtime - Pass as --resume-session flag to acpx CLI - Error hard (exit 4) on non-existent session, no silent fallback - All new fields optional for backward compatibility Depends on acpx >= 0.1.16 (openclaw/acpx#85, merged, pending release). Tests: 26/26 pass (runtime + tool schema) Verified e2e: Discord → sessions_spawn(resumeSessionId) → Codex resumed session and recalled stored secret. 🤖 AI-assisted
Add early-return error when resumeSessionId is passed without runtime="acp" (mirrors existing streamTo guard). Without this, the parameter is silently ignored and the agent gets a fresh session instead of resuming. Also update schema description to note the runtime=acp requirement. Addresses Greptile review feedback.
886a3d3 to
d7950d9
Compare
|
Landed after rebasing onto current
Thanks @pejmanjohn! |
上游更新摘要(abb8f6310 → bda63c3,164 commits): ### 新功能 - ACP: 新增 resumeSessionId 支持 ACP session 恢复(openclaw#41847) - CLI: 新增 openclaw backup create/verify 本地状态归档命令(openclaw#40163) - Talk: 新增 talk.silenceTimeoutMs 配置项,可自定义静默超时(openclaw#39607) - ACP Provenance: 新增 ACP 入站溯源元数据和回执注入(openclaw#40473) - Brave 搜索: 新增 llm-context 模式,返回 AI 精炼摘要(openclaw#33383) - browser.relayBindHost: Chrome relay 可绑定非 loopback 地址(WSL2 支持)(openclaw#39364) - node-pending-work: 新增 node.pending.pull/ack RPC 接口 - Telegram: 新增 exec-approvals 处理器,支持 Telegram 内命令执行审批 - Mattermost: 新增 target-resolution,修复 markdown 保留和 DM media 上传 - MS Teams: 修复 Bot Framework General channel 对话 ID 兼容性(openclaw#41838) - secrets/runtime-web-tools: 全新 web runtime secrets 工具模块 - cron: 新增 store-migration,isolated-agent 直送核心通道,delivery failure notify - TUI: 自动检测浅色终端主题(COLORFGBG),支持 OPENCLAW_THEME 覆盖(openclaw#38636) ### 修复 - macOS: launchd 重启前重启已禁用服务,修复 openclaw update 卡死问题 - Telegram DM: 按 agent 去重入站 DM,防止同一条消息触发重复回复(openclaw#40519) - Matrix DM: 修复 m.direct homeserver 检测,保留房间绑定优先级(openclaw#19736) - 飞书: 清理插件发现缓存,修复 onboarding 安装后重复弹窗(openclaw#39642) - config/runtime snapshots: 修复 config 写入后 secret 快照丢失问题(openclaw#37313) - browser/CDP: 修复 ws:// CDP URL 反向代理和 wildcard 地址重写 - agents/failover: 识别 Bedrock tokens per day 限额为 rate limit ### 版本 - ACPX 0.1.16 - iOS/macOS 版本号更新 - Android: 精简后台权限 构建验证:待执行
Summary
Add
resumeSessionIdparameter tosessions_spawnso agents can resume existing ACP sessions (e.g. a prior Codex conversation) instead of starting fresh. The agent replays conversation history viasession/load.Flow
Changes
sessions-spawn-tool.ts— AddresumeSessionIdparam with description so agents discover and use itacp-spawn.ts— Thread throughSpawnAcpParamsmanager.types.ts/manager.core.ts— Thread throughAcpInitializeSessionInputtypes.ts— Add toAcpRuntimeEnsureInputextensions/acpx/src/runtime.ts— Pass as--resume-sessionflag to acpx CLIAll new fields are optional (backward-compatible).
Dependency
Requires acpx >= next release (openclaw/acpx#85 merged, pending npm publish). The
--resume-sessionCLI flag was added there. Version bump commit will follow once published.Testing
sessions_spawn(resumeSessionId="...")→ Codex resumed session and recalled stored secret🤖 AI-assisted (Codex for initial implementation, manually reviewed and refined)
Note: Happy to open a Discussion first if preferred for new ACP features — wanted to get the implementation up for visibility since the acpx side (PR #85) is already merged.