App Server schema/runtime reject documented restricted read access on turn/start
What issue are you seeing?
The current Codex App Server documentation says that sandboxPolicy supports explicit restricted read access:
{
"type": "readOnly",
"access": {
"type": "restricted",
"includePlatformDefaults": true,
"readableRoots": ["/canonical/review/root"]
}
}
The same page documents sandboxPolicy as a per-turn override on turn/start, and says command/exec accepts the same shape.
However, generated production schemas from the current official npm distributions do not expose that stable binding:
@openai/codex@0.147.0(latest)@openai/codex@0.148.0-alpha.19(alpha)
In the generated production types, the readOnly sandbox variant does not expose the documented restricted access object on the stable per-turn surface. The alpha runtime also rejects the documented shape with:
Invalid request: readOnly.access is no longer supported; use permissionProfile for restricted reads
But the generated bindings do not expose a stable permissionProfile equivalent on production TurnStartParams. The available permission-profile surfaces are beta/experimental and therefore cannot replace a documented stable per-turn security boundary.
This creates a three-way contradiction between the documentation, generated production schemas, and runtime validation behavior.
Official documentation: https://learn.chatgpt.com/docs/app-server
What steps can reproduce the bug?
- Install an exact official runtime:
``sh``
npm install @openai/codex@0.147.0
- Generate the App Server TypeScript and JSON schemas with that exact runtime.
- Inspect the generated
SandboxPolicyandTurnStartParams. - Compare them with the documented
readOnly.access.type = "restricted"/readableRootsshape. - Initialize App Server without experimental API capability.
- Start a thread.
- Attempt a
turn/startor sandboxedcommand/execusing the documented restricted-root shape. - Observe that the generated stable contract cannot express it; the alpha candidate additionally rejects
readOnly.accessand points to a permission-profile mechanism not exposed as a stable per-turn binding.
The current registry tags at the time of this report are:
latest = 0.147.0
alpha = 0.148.0-alpha.19
What is the expected behavior?
One stable contract should exist across documentation, generated schemas, and runtime behavior.
Either:
- the documented restricted
readOnly.accessshape is accepted and generated for stableturn/start; or - a supported equivalent is documented and generated on the stable per-turn API, with exact restricted readable roots and no broader-access fallback.
If permissionProfile is the replacement, custom App Server clients need a documented, generated, stable way to bind the selected restricted profile to every turn/start.
Additional information
This matters for security-critical custom App Server clients that must make a source worktree readable but not writable while restricting reads to explicitly authorized canonical roots. Without a stable per-turn binding, a client must either fail closed or weaken its security model.
A detached review/start call also does not document an exact restricted-root sandbox parameter, so it cannot safely substitute for an explicit policy-bound turn/start.
No private credentials, account identifiers, thread IDs, or local repository contents are included in this report.