Codex sandbox_permissions approval doesn't get surfaced through app-server
What issue are you seeing?
While integrating Codex through codex app-server, I saw a codex turn stall on a permission/escalation prompt that appeared in the codex session transcript, but no matching app-server item/*/requestApproval server request over JSON-RPC.
This leaves app-server clients unable to display or resolve the approval. The turn appears active but cannot progress until the hidden approval times out.
- Codex CLI: 0.130.0
- Mode: codex app-server --listen stdio://
- Approval policy: on-request
- Sandbox: workspace-write
- Platform: Linux
What steps can reproduce the bug?
- Start app-server:
codex app-server --listen stdio:// \
-c 'model="gpt-5.5"' \
-c 'approval_policy="on-request"' \
-c 'thread_sandbox="workspace-write"' \
-c 'turn_sandbox_policy="workspace-write"'
- Initialize app-server over stdio.
- Start a thread in a git worktree whose .git metadata lives outside the sandbox writable roots.
- Start a turn asking Codex to stage/commit changes, or otherwise run a command that requires sandbox escalation, for example git add .... This should trigger codex for sandbox_permissions approval.
- Observe the app-server JSON-RPC stream.
- Compare it with the saved Codex session transcript under ~/.codex/sessions/....
What is the expected behavior?
I expect app-server to surface a item/*/requestApproval as with other approval requests.
Additional information
Here's what it looked like for me:
session transcript:
{
"type": "function_call",
"name": "exec_command",
"arguments": {
"cmd": "git add foobar",
"workdir": "/tmp/testbranch1",
"yield_time_ms": 1000,
"max_output_tokens": 12000,
"sandbox_permissions": "require_escalated",
"justification": "Allow staging the test file in this git worktree; the git metadata lives under /home/... outside the writable sandbox.",
"prefix_rule": ["git", "add"]
}
}
After 300 seconds, the session transcript recorded:
{
"type": "function_call_output",
"output": "aborted by user after 300.0s"
}
But the app-server client never received an approval request it could answer.
4 Comments
Just leaving a note here as I am absolutely invested in the outcome for this - without it only options within paseo are full access permissions, which is too unsafe to be able to use in my case..really keen to see this one resolved. Linux daemon and codex server runtime .130 - win 11 and ios paseo clients latest as of today).
Thanks for the detailed report. I investigated this path and I don’t think this is an app-server bug.
The important detail is that
approval_policy = "on-request"is not, by itself, enough to guarantee that escalation requests are surfaced to the app-server client asitem/commandExecution/requestApproval. If the session is configured with an automatic approvals reviewer, such asguardian_subagent/ auto-review, the escalation is handled by that reviewer instead of being routed to the client for manual approval.I was able to exercise the repro shape directly: app-server over stdio,
workspace-write,on-request, a git worktree whose.gitmetadata points outside the writable root, and anexec_commandcall withsandbox_permissions = "require_escalated". Whenapprovals_reviewer = "user"was set, app-server correctly emitteditem/commandExecution/requestApproval.So the behavior described here is most likely explained by the session using an automatic approvals reviewer, not by app-server dropping the approval request.
If you still believe this is a bug, please provide a raw JSON-RPC trace that includes the
thread/startresponse, especially theapprovalsReviewervalue, plus the subsequent turn events. Without that, this looks like a configuration/client expectation issue rather than a Codex defect.Hi @etraut-openai, thanks for looking into this!
Edit: just noticed you asked for the subsequent turn event logs as well, my bad. I'm attaching PII-redacted logs here:
Codex:
codex-session-transcript-excerpt-public-redacted.json
App-server:
app-server-full-stream-public-redacted.json
Main things I'm seeing from these two logs:
git add <changed-files>call that fails with:fatal: Unable to create '/repo/.git/worktrees/<worktree>/index.lock': Read-only file systemexec_commandcall with:sandbox_permissions: "require_escalated"prefix_rule: ["git", "add"]requestApprovalentry and nowaitingOnApprovalstatus transition.failed to record rollout items: thread <opaque-id> not foundThanks again!
Even if an automatic reviewer handles an escalation, app-server clients still need an event for the pending state.
I would stream an approval lifecycle item with correlation id, command/tool call id, sandbox policy, requested permission, reviewer route (
clientvsauto), final decision, and timeout/error state. Then clients can renderhandled by auto reviewerinstead of looking stalled with no resolvable approval.---
_Generated with ax._