OpenClaw Is Closing the Policy Gap Between Who Asked and What Tool Runs
Approval gates have a branding problem: they look like security controls, but too often they are just modal dialogs with incomplete context. OpenClaw PR #96211 is interesting because it goes after the field most agent platforms quietly hand-wave: requester origin. Not just “what tool is about to run,” but who caused this run, where it entered the system, which channel carried it, and whether the trigger came from a chat message, cron job, embedded runtime, side question, or gateway call.
That distinction sounds bureaucratic until you put a coding agent in the real world. The same shell command can be safe when issued from a trusted local operator session and unsafe when smuggled through a group-chat mention. The same message-send tool can be harmless in a DM workflow and a compliance problem when triggered from an HTTP ingress path. Agent security is full of these “same text, different meaning” cases, and most platforms still treat the command text as the center of the policy universe.
PR #96211 is a draft, but it is not a toy patch. GitHub reports 1,432 additions, 192 deletions, and 47 changed files across Codex app-server code, Copilot extension paths, plugin SDK baselines, hook documentation, gateway and native-relay handling, and new Codex hook-context plumbing. The PR describes the core mechanism as “one canonical, allowlisted requester-origin snapshot” carried through before/after tool hooks across embedded runs, Copilot, Codex, native relay, and gateway paths. Translation: OpenClaw wants every policy hook to reason over the same origin shape instead of a runtime-specific approximation.
The missing column in the approval table
OpenClaw’s plugin hook docs already give operators meaningful control. A before_tool_call hook can rewrite parameters, block execution, or require approval; hook events include fields such as toolName, params, runId, and toolCallId, while context includes agent, session, job, tool-kind, input-kind, and trace data. That is a decent base. But if the hook cannot reliably distinguish requester identity and ingress path, it is still missing the column that turns a generic rule into an enforceable policy.
This matters because agent platforms are becoming routers, not chatbots. A single OpenClaw deployment may accept Slack messages, scheduled jobs, native Codex tool calls, Copilot flows, HTTP API requests, internal side questions, and background subagent completions. Each path can arrive with different identity metadata and different assumptions about who is authorized to do what. A policy system that only sees “agent X called tool Y” is blind to a large part of the risk.
The PR’s security-sensitive detail is that hook-only channel metadata stays out of shell subprocess defaults. That line deserves more attention than the diff size. Policy metadata is useful because it can answer authorization questions. It should not automatically become environment leakage for every subprocess the agent spawns. The best security designs are boring in exactly this way: carry context where it is needed, do not spray it everywhere because some downstream code might find it convenient.
Related issue #50291 shows the observability version of the same problem. Hook events without stable message, run, and parent-span context make distributed tracing unreliable, especially when multiple group-chat messages run concurrently. Related issue #93425 raises the subprocess-boundary angle: per-agent environment injection needs careful review because agent identity and spawned process identity are operationally coupled. Put those together and the theme is obvious. Identity is no longer a profile setting. It is runtime data.
Prompt injection becomes workflow injection when origin disappears
The common framing for coding-agent security is still too model-centric: prevent prompt injection, sandbox shell access, require approval for dangerous tools, redact secrets. All useful. None sufficient. Once agents participate in multi-channel workflows, the attack surface includes the route by which an instruction becomes a tool call.
Imagine a policy that allows database read-only queries from trusted engineers in a private channel, blocks those queries from public channels, and requires approval when triggered by HTTP ingress. That policy is not exotic. It is basic enterprise hygiene. But it only works if the policy hook sees stable requester origin. If a side-question path drops the channel, a native tool bridge flattens requester identity, or a gateway call looks like an ordinary local run, the platform has created a downgrade path. The attacker does not need a better jailbreak; they need the platform to forget where the request came from.
This is where “approval gates” can become approval theater. If an approval prompt says “run shell command?” but does not show that the command was triggered by an untrusted Slack thread, the human is approving with partial facts. If logs later show the tool call but not the requester path, incident response has the same problem in reverse. You can see the action but not the chain of custody.
For practitioners, the immediate move is to audit policies by origin rather than by capability. Do not stop at “which tools can this agent use?” Ask: can a group chat trigger the same shell policy as a local CLI session? Are cron jobs intentionally identity-less, or just missing identity because nobody threaded it through? Do approval hooks distinguish native chat identity from routing target? Can HTTP ingress be tagged differently from human chat? Are side questions and embedded runtimes covered by the same policy contract as the main run?
If the answer is “the model probably knows,” the answer is no. Models do not provide authorization context. Runtime systems do.
There is also an implementation lesson here. Canonical context should be allowlisted, typed, and consistent across runtimes. It should not be a bag of whatever metadata each adapter happens to have. The PR’s scope across Codex, Copilot, gateway, native relay, docs, and SDK baselines is large because the problem is large: every runtime-specific seam is a place where identity can be lost.
The risk, of course, is review complexity. A draft PR touching 47 files across policy-sensitive paths deserves slow review, not applause-by-diffstat. The validation notes — 18 focused test files, 900 tests, TypeScript checks, Oxlint/Oxfmt, SDK API baseline, MDX docs, and a 5,464-link audit — are reassuring, but broad context plumbing has a habit of failing in the weird path nobody uses until production. That is not an argument against the work. It is an argument for treating it like security infrastructure, not feature polish.
The bigger point is that the coding-agent category is maturing past “can it ask before running a command?” The better question is “can it explain why this command is allowed for this requester in this context?” OpenClaw is moving toward that question. Good. The industry needs fewer permission prompts that look serious and more policy hooks that are actually informed.
Sources: OpenClaw PR #96211, OpenClaw plugin hooks docs, OpenClaw issue #50291, OpenClaw issue #93425