OpenClaw’s Codex Harness Still Has to Prove Tool Policy Is a Runtime Boundary, Not a Config Wish
There are two ways to ship a tool policy in an agent platform. One is as configuration: a tidy object, a feature flag, maybe a helper function with a reassuring test name. The other is as an actual runtime boundary: the exact place where the model tries to run bash, apply a patch, call an app, or touch a plugin, and the orchestrator gets a blocking vote before anything happens.
OpenClaw’s latest Codex harness issue is about the distance between those two things. Issue #82372, opened May 16, reports that Codex app-server turns can still bypass plugin before_tool_call policy enforcement even after PR #82078 fixed the obvious feature-flag mismatch from deprecated features.codex_hooks to stable features.hooks. That first fix mattered. It was just not the whole boundary.
The reported failure is more interesting, and more useful for anyone operating coding agents. The helper that builds the Codex native hook relay config exists. The stable hooks feature exists. But in the installed release path, runCodexAppServerAttempt may call the app-server without enabling the relay at all: nativeHookRelay is falsy, options.nativeHookRelay?.enabled === false is also false, and threadConfig receives void 0 instead of buildCodexNativeHookRelayConfig(...). In plain English: the firewall was built, but the public entrance may not have routed traffic through it.
The dangerous part is the seam, not the flag
This is exactly where agent-platform security gets slippery. OpenClaw is not only managing its own tools; it is translating policy into another runtime’s native protocol. Codex has app-server features, code mode, dynamic tools, plugin apps, and native execution surfaces. OpenClaw has sender policies, plugin hooks, approval modes, and tool allowlists. The security property only holds if all of those layers agree at the moment of execution.
PR #82377 is the direct response to the hook-relay seam. Opened at 2026-05-16T00:58:28Z, it changes two files with 24 additions and one deletion, making createCodexAppServerAgentHarness().runAttempt() explicitly pass nativeHookRelay: { enabled: true } into the app-server attempt runner. It also adds a regression test for that public harness seam. That is the correct test target. A helper-level test that proves a config generator can emit hooks is useful; a public-harness test that proves the installed path actually passes the relay is the difference between intent and enforcement.
The companion fix, PR #82374, exposes an even cleaner version of the same category error. Telegram toolsBySender deny-all could resolve to toolsAllow: [], while the Codex app-server still sent features.code_mode=true, could enable plugin app config, and treated an empty dynamic-tool allowlist as unrestricted. The UI-level answer was “zero tools.” The model-runtime answer was “native code tools and app surfaces are still around.” That mismatch is where incidents are born.
The patched behavior is far more explicit: thread/start receives dynamicTools: [], features.code_mode: false, features.code_mode_only: false, no enabled Google Calendar app, and no app/list request when toolsAllow is empty. The focused Codex tests reportedly passed 153 out of 153 across thread-lifecycle.test.ts and run-attempt.test.ts. That is the right shape of fix because it closes the runtime surfaces, not just the OpenClaw-side catalog.
What operators should verify before trusting Codex policy
If you run OpenClaw with Codex and high-trust tools, do not treat this as an obscure GitHub plumbing thread. This is the kind of boundary you should validate in your own environment. Create a policy that denies a visible action — a file write outside the workspace, a shell command, a plugin app call — and confirm the denial happens from the actual channel, model, and harness you use in production. If your test only inspects config or checks that a tool count is zero, you have not tested the boundary. You have tested the dashboard.
Also watch the distinction between dynamic OpenClaw tools and model-native tools. Many agent security checklists say “use allowlists,” and that advice is fine as far as it goes. The sharper question is: allowlist of what? If the orchestrator denies its plugin catalog but the downstream runtime still exposes bash, apply_patch, code mode, app discovery, or a native browser, your allowlist is partial. Partial allowlists are worse than no allowlists when they produce confidence without coverage.
Plugin authors should take the same lesson. Harness-specific enforcement belongs in the compatibility matrix. A plugin hook that works through Pi or a standard OpenClaw tool path may not automatically cover Codex app-server, Claude native execution, or the next ACP backend. The agent ecosystem is moving toward richer native runtimes because they are more capable. That also means policy is crossing more serialization layers, feature flags, and protocol boundaries. Every one of those translations needs a test that fails closed.
To OpenClaw’s credit, the repo response was fast. #82372 was not dismissed after the earlier #82350 confusion, and the follow-up PRs appeared within roughly twenty minutes of the report. That is a healthy maintainer loop. But the incident still captures the uncomfortable truth of agent security in 2026: “we configured the policy” is not the same as “the model could not act.” Runtime boundaries must be proven where the action happens.
The editorial take: Codex integration is not just a model-provider feature. It is a security translation layer. If OpenClaw wants Codex-native tools to be production-grade, hook relay and deny-all semantics cannot be best-effort config wishes. They have to be boring, explicit, installed-path guarantees.
Sources: OpenClaw issue #82372, OpenClaw PR #82377, OpenClaw PR #82374, OpenClaw PR #82078