Skip to content

feat(codex): support app-server network proxy profiles#93538

Merged
vincentkoc merged 8 commits into
mainfrom
codex-network-proxy-app-server
Jun 17, 2026
Merged

feat(codex): support app-server network proxy profiles#93538
vincentkoc merged 8 commits into
mainfrom
codex-network-proxy-app-server

Conversation

@vincentkoc

Copy link
Copy Markdown
Member

Summary

  • Adds appServer.networkProxy for the bundled Codex plugin so OpenClaw can enable Codex's managed network proxy through an app-server permission profile.
  • Builds the Codex config patch for features.network_proxy.enabled plus permissions.<profile>.network.*, including loopback proxy URLs, domain allowlists, SOCKS options, and local/private-network escape hatches.
  • Sends Codex's current protocol shape, permissions: { type: "profile", id }, on thread start/resume and keeps bound turns sticky instead of reselecting an ephemeral generated profile.
  • Updates plugin metadata, docs, binding persistence, and tests for the app-server thread lifecycle and conversation binding paths.

Linked context

Which issue does this close?

  • None.

Which issues, PRs, or discussions are related?

  • None.

Was this requested by a maintainer or owner?

  • Maintainer request from Vincent to support Codex's new network proxy in OpenClaw's app-server proxy setup.

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Codex app-server runtime config can now opt into managed network proxy profiles and route OpenClaw app-server threads through the generated profile selection.
  • Real environment tested: Crabbox with Blacksmith Testbox tbx_01kv7mhsy79j2f048vxzhb78f3 from branch codex-network-proxy-app-server.
  • Exact steps or command run after this patch: node scripts/run-vitest.mjs extensions/codex/src/app-server/config.test.ts extensions/codex/src/app-server/thread-lifecycle.test.ts extensions/codex/src/conversation-binding.test.ts && env OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 corepack pnpm check:changed
  • Evidence after fix: targeted sync was 12 files; focused Vitest passed 3 passed, 187 passed; check:changed selected lanes=extensions, extensionTests, docs; Blacksmith run summary ended exit=0.
  • Observed result after fix: mock loopback proxy config is normalized into Codex network profile config; thread start/resume use the profile object; bound turns omit sandbox/profile overrides when the persisted proxy profile is still active; explicit sandbox overrides still win.
  • What was not tested: a live upstream Codex network egress request through a real proxy server. The PR verifies OpenClaw's payload/config contract and lifecycle behavior with mock proxy config plus type/lint/check gates.
  • Proof limitations or environment constraints: pnpm docs:list and scripts/committer were not run locally because this Codex worktree is linked/sparse and local pnpm wrapper paths attempt dependency reconciliation; validation was run through the repo's Crabbox/Testbox path instead.
  • Before evidence: prior Testbox run tbx_01kv7m6nevz7vct3tfazeyta0e failed check:changed on bounded-turn.ts config typing after the rebase; this branch includes the typed merge fallback and the final Testbox gate is green.

Tests and validation

  • node scripts/run-vitest.mjs extensions/codex/src/app-server/config.test.ts extensions/codex/src/app-server/thread-lifecycle.test.ts extensions/codex/src/conversation-binding.test.ts
  • Crabbox/Testbox tbx_01kv7mhsy79j2f048vxzhb78f3: targeted Vitest plus OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 corepack pnpm check:changed
  • .agents/skills/autoreview/scripts/autoreview --mode local --base origin/main reported no accepted/actionable findings.

Regression coverage added or updated:

  • Network proxy config schema and patch generation, including mock loopback proxy URL/domain rules.
  • Codex app-server thread start/resume profile selection and sticky turn behavior.
  • Conversation binding persistence and bound-turn sandbox/profile behavior.
  • Bounded-turn config merge typing after the rebase.

Dependency/protocol proof:

  • Checked sibling Codex source at codex-rs/app-server-protocol/src/protocol/v2/permissions.rs:505 through permissions.rs:519: PermissionProfileSelectionParams is tagged and uses the Profile { id, modifications } shape.
  • Checked codex-rs/app-server-protocol/src/protocol/v2/thread.rs:117 through thread.rs:124 and thread.rs:274 through thread.rs:281: thread start/resume expose permissions: Option<PermissionProfileSelectionParams> and cannot combine it with sandbox.
  • Checked codex-rs/app-server-protocol/src/protocol/v2/turn.rs:75 through turn.rs:84: turn/start has optional permissions, but this PR avoids using it for generated thread-local profiles unless an explicit sandbox override is requested.

Risk checklist

Did user-visible behavior change? (Yes/No)

Yes, for users who opt into the new Codex app-server network proxy config.

Did config, environment, or migration behavior change? (Yes/No)

Yes, new optional plugin config keys under appServer.networkProxy.

Did security, auth, secrets, network, or tool execution behavior change? (Yes/No)

Yes, network sandbox/proxy behavior changes when explicitly enabled.

What is the highest-risk area?

Misrouting sandbox/profile selection across thread start, resume, and bound turns.

How is that risk mitigated?

The runtime only enables the profile when appServer.networkProxy.enabled is set, persists the active generated profile name in bindings, omits reselecting ephemeral profiles on bound turns, keeps explicit sandbox overrides higher priority, and covers those cases in unit tests plus Testbox type/lint gates.

Current review state

What is the next action?

Maintainer review.

What is still waiting on author, maintainer, CI, or external proof?

CI after PR creation. No known author-side blockers.

Which bot or reviewer comments were addressed?

Local autoreview initially caught the protocol shape and ephemeral profile reselection issues; both were fixed before this PR. Final autoreview is clean.

AI-assisted: yes; the implementation was reviewed against upstream Codex protocol source and validated with Crabbox/Testbox before opening.

@vincentkoc vincentkoc self-assigned this Jun 16, 2026
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation extensions: codex size: L maintainer Maintainer-authored PR labels Jun 16, 2026
@vincentkoc
vincentkoc marked this pull request as ready for review June 16, 2026 07:22
@clawsweeper

clawsweeper Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed June 16, 2026, 3:49 AM ET / 07:49 UTC.

Summary
The PR adds optional Codex plugin appServer.networkProxy config, emits Codex permission-profile config for managed proxy networking, persists profile binding metadata, and updates docs/tests for thread start/resume and bound turns.

PR surface: Source +311, Tests +324, Docs +74. Total +709 across 12 files.

Reproducibility: yes. from source inspection: enable appServer.networkProxy and the PR builds thread start/resume requests with object-shaped permissions, while current Codex protocol requires a string profile id.

Review metrics: 1 noteworthy metric.

  • Codex plugin config surfaces: 15 added. The new appServer.networkProxy object and nested keys control sandboxed network egress, so maintainers should review the config contract before merge.

Stored data model
Persistent data-model change detected: serialized state: extensions/codex/src/app-server/session-binding.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🌊 off-meta tidepool
Patch quality: 🧂 unranked krab
Result: blocked by patch quality or review findings.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Change permissions to the string profile id contract and rerun the focused Codex app-server tests plus the protocol check.

Risk before merge

  • [P1] Codex app-server currently expects permissions to be a string profile id; this PR sends an object, so opt-in network-proxy thread start/resume and bind paths can reject the request before the profile is selected.
  • [P1] The PR adds network-proxy config and sandbox/profile selection surface, so the protocol fix still needs normal security-boundary and upgrade review before merge.

Maintainer options:

  1. Send String Profile IDs (recommended)
    Update the OpenClaw protocol types, helpers, and tests so thread/resume/turn permissions is the profile name string that current Codex app-server expects.
  2. Pause For A Future Codex Shape
    If this PR targets an unreleased Codex protocol change, pause until that upstream contract is merged and cite the new Codex source before landing OpenClaw support.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Update the Codex app-server permissions contract in OpenClaw to match current Codex source by typing thread/resume/turn permissions as a string profile id, sending `networkProxy.profileName` directly, and updating the focused thread-lifecycle/conversation-binding tests plus protocol check evidence.

Next step before merge

  • [P2] A narrow repair can align the OpenClaw protocol types, request builders, and tests with Codex's string profile-id permissions contract.

Security
Cleared: No supply-chain, dependency, secret-handling, or direct security bypass was found; the network/sandbox boundary concern is covered as a merge risk and functional finding.

Review findings

  • [P1] Send permission profile ids as strings — extensions/codex/src/app-server/protocol.ts:79-83
Review details

Best possible solution:

Keep the plugin-local network-proxy feature, but align OpenClaw's protocol types and runtime requests to Codex's string profile-id permissions contract before merge.

Do we have a high-confidence way to reproduce the issue?

Yes, from source inspection: enable appServer.networkProxy and the PR builds thread start/resume requests with object-shaped permissions, while current Codex protocol requires a string profile id.

Is this the best way to solve the issue?

No; the feature belongs in the Codex plugin, but this implementation does not match the upstream app-server protocol. The narrower fix is to keep the config patch and send the selected profile name as the permissions string.

Full review comments:

  • [P1] Send permission profile ids as strings — extensions/codex/src/app-server/protocol.ts:79-83
    Current Codex app-server declares thread/start.permissions, thread/resume.permissions, and turn/start.permissions as named profile id strings, but this type makes OpenClaw send { type: "profile", id }. With appServer.networkProxy.enabled, Codex will receive an object where it expects a string and can reject the request before selecting the generated profile; keep the config patch, but send the profile name directly.
    Confidence: 0.95

Overall correctness: patch is incorrect
Overall confidence: 0.92

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 1ae0eacf4b0f.

Label changes

Label justifications:

  • P2: This is a normal-priority feature PR with a concrete blocking protocol defect but limited blast radius because the new network proxy path is opt-in.
  • merge-risk: 🚨 compatibility: The PR sends a permissions object where current Codex app-server expects a string, so users enabling the new config can hit a protocol rejection.
  • merge-risk: 🚨 security-boundary: The PR changes Codex sandbox/network permission profile selection and adds local/private-network escape hatches that green CI alone does not settle.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🌊 off-meta tidepool and patch quality is 🧂 unranked krab.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Not applicable: The external-contributor proof gate does not apply to this maintainer PR; the body reports Testbox/mock contract proof, but not a live proxy egress run.
Evidence reviewed

PR surface:

Source +311, Tests +324, Docs +74. Total +709 across 12 files.

View PR surface stats
Area Files Added Removed Net
Source 7 330 19 +311
Tests 3 325 1 +324
Docs 2 74 0 +74
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 12 729 20 +709

Acceptance criteria:

  • [P1] node scripts/run-vitest.mjs extensions/codex/src/app-server/config.test.ts extensions/codex/src/app-server/thread-lifecycle.test.ts extensions/codex/src/conversation-binding.test.ts.
  • [P1] pnpm codex-app-server:protocol:check.
  • [P1] env OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 corepack pnpm check:changed.

What I checked:

Likely related people:

  • vincentkoc: Current-main blame and git log show Vincent Koc recently maintained the Codex app-server config/thread lifecycle/conversation binding surface, including commit 983e0f2. (role: recent area contributor; confidence: high; commits: 983e0f2ba080; files: extensions/codex/src/app-server/config.ts, extensions/codex/src/app-server/thread-lifecycle.ts, extensions/codex/src/conversation-binding.ts)
  • fuller-stack-dev: GitHub PR metadata for feat: add Codex hosted web search #93446 shows Jason recently merged Codex hosted-search work that touched the same app-server thread lifecycle area now being extended. (role: adjacent recent contributor; confidence: medium; commits: 1e0062b44a51; files: extensions/codex/src/app-server/thread-lifecycle.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jun 16, 2026
@vincentkoc
vincentkoc force-pushed the codex-network-proxy-app-server branch from 9850eb6 to 2be6ee7 Compare June 17, 2026 04:43
@vincentkoc
vincentkoc force-pushed the codex-network-proxy-app-server branch 2 times, most recently from 324547a to 42a8886 Compare June 17, 2026 05:52
@vincentkoc

Copy link
Copy Markdown
Member Author

Merge-ready proof for 42a8886df3a5fc5f2dc76d8beab39b3d1301298e.

Summary:

  • Added Codex app-server networkProxy config that starts threads with features.network_proxy.enabled, default_permissions, and a generated permissions profile.
  • Bound app-server turns now persist and compare the network-proxy profile/fingerprint, rotate stale bindings, and avoid per-turn sandboxPolicy only when the thread profile is current.
  • /btw side-thread forks carry the proxy config, and explicit thread-id binds start a fresh proxy-backed thread instead of falsely marking a resumed thread as proxy-protected.
  • Default generated profile names now include a fingerprint (openclaw-network-<fingerprint>) to avoid stale Codex deep-merge collisions.

Codex contract checked:

  • openai/codex origin/main cb15c647608ea848713837e4b49975e5a1481051
  • codex-rs/core/src/config/permissions.rs:774-784 recognizes :workspace_roots.
  • codex-rs/features/src/feature_configs.rs:133-137 and codex-rs/config/src/permissions_toml.rs:322-330 use Unix socket allow|deny.
  • ThreadStartParams.ts:12-19 supports config; TurnStartParams.ts:13-45 has no request-level permissions.

Verification:

  • Local: node scripts/run-vitest.mjs extensions/codex/src/app-server/config.test.ts extensions/codex/src/app-server/approval-bridge.test.ts extensions/codex/src/app-server/session-binding.test.ts extensions/codex/src/app-server/thread-lifecycle.test.ts extensions/codex/src/app-server/thread-lifecycle.binding.test.ts extensions/codex/src/app-server/side-question.test.ts extensions/codex/src/conversation-binding.test.ts (7 files, 345 tests).
  • Local hygiene: git diff --check, conflict-marker scan, and diff scrub clean.
  • Autoreview: .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main clean after source-checked Codex contract prompt.
  • Crabbox: AWS run_3fc8abfa77fb, lease cbx_69d02551f208, passed docs:list, the same 7 focused Vitest files (345 tests), and check:changed (extensions, extensionTests, docs); lease stopped cleanly.
  • GitHub CI: current PR checks green on this head; PR is open, non-draft, and mergeable.

@vincentkoc
vincentkoc force-pushed the codex-network-proxy-app-server branch from 42a8886 to 192575a Compare June 17, 2026 08:40
@vincentkoc
vincentkoc force-pushed the codex-network-proxy-app-server branch from 192575a to 9900b14 Compare June 17, 2026 09:01
@vincentkoc
vincentkoc merged commit 5c34695 into main Jun 17, 2026
18 checks passed
@vincentkoc
vincentkoc deleted the codex-network-proxy-app-server branch June 17, 2026 09:01
@vincentkoc

Copy link
Copy Markdown
Member Author

Merged via squash.

Thanks @vincentkoc!

@vincentkoc

vincentkoc commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

Post-merge follow-up landed on main to address the network-proxy contract findings from the final autoreview.

Follow-up commit: cf78500

What changed:

  • Generated Codex permission profiles now use :project_roots instead of :workspace_roots.
  • appServer.networkProxy.unixSockets now exposes Codex-native allow / none values in schema, manifest, docs, and tests.
  • Removed the stale private resolveWebSearchDefinition helper that was already failing extension typecheck on current main.

Verification:

  • Local: extension prod/test typecheck passed.
  • Local: node scripts/run-vitest.mjs src/web-search/runtime.test.ts extensions/codex/src/app-server/config.test.ts extensions/codex/src/app-server/thread-lifecycle.test.ts extensions/codex/src/app-server/thread-lifecycle.binding.test.ts extensions/codex/src/app-server/side-question.test.ts passed.
  • Crabbox AWS: run_fb89b1e48341, lease cbx_a6beb8a61254, check:changed passed; lease stopped cleanly.
  • Autoreview: clean, no accepted/actionable findings.

crh-code pushed a commit to crh-code/openclaw that referenced this pull request Jun 18, 2026
Merged via squash.

Prepared head SHA: 9900b14
Co-authored-by: vincentkoc <[email protected]>
Co-authored-by: vincentkoc <[email protected]>
Reviewed-by: @vincentkoc
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 18, 2026
Merged via squash.

Prepared head SHA: 9900b14
Co-authored-by: vincentkoc <[email protected]>
Co-authored-by: vincentkoc <[email protected]>
Reviewed-by: @vincentkoc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation extensions: codex maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant