OpenClaw

OpenClaw

why your openclaw approvals feel calm right before they break

openclaw's approval system has a trust leak that looks like things working. here is the firewall model and the repo that catches it.

OpenClaw Unboxed's avatar
Josh Davis's avatar
OpenClaw Unboxed and Josh Davis
Apr 21, 2026
∙ Paid

most people i chat with here and on instagram think the approval problem is friction.

i think (know now) that the real problem is just drift.

one week the stack asks too often.
the next week it asks less.
after that, nobody remembers what changed.

that’s how people end up in the two worst states.

OpenClaw is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.

the first one is approval spam. the agent keeps stopping for shell access, browser actions, file access, or node commands. people get annoyed. they start hunting for the shortcut.

the second one looks better on the surface. prompts get quieter. workflows feel smoother. then a wrapper gets trusted instead of the tool you meant to trust, or an interpreter gets trusted instead of one script, or the approval ui disappears and the fallback quietly allows more than you meant.

that second state is worse because it feels calm.

openclaw’s current security docs are direct about the trust model. one gateway, meaning the host machine where openclaw runs, is one trusted operator boundary. it isn’t a hostile multi-tenant wall for adversarial users sharing one gateway or one agent. if multiple untrusted users can message one tool-enabled agent, they’re steering the same delegated tool authority. session keys don’t change that. they’re routing selectors, not auth boundaries.

that point should change how you think about approvals.

this isn’t a popup problem.

it’s an access design problem.

why this matters so much right now

openclaw now spells the approval stack out more clearly than most people think. the exec approvals docs separate three controls: security, which sets the trust mode. ask, which decides when to prompt. and askfallback, which decides what happens when the approval ui can’t reach you. the same docs also make the yolo path plain. setting security to full and ask to off means host exec runs without prompts unless some stricter layer wins first.

that’s not a product failure.

it’s a trust choice.

and it’s got teeth.

there’s a second reason this matters now. anthropic said claude code users accept 93 percent of permission prompts anyway. that’s the whole approval-fatigue argument in one number. once people stop reading the prompt, the prompt is no longer doing the job people claim it’s doing.

that part maps cleanly onto openclaw.

if your review flow depends on a human staying fresh through every prompt, you don’t have a stable trust model. you have temporary attention.

where this goes wrong in the field

one path looks harmless.

a user approves a command like whoami.
a shell wrapper gets trusted instead of the underlying tool.

here’s what that means. when you type whoami, the runtime might execute it through something like /bin/zsh -lc ‘/usr/bin/whoami’. you thought you approved whoami. the system actually recorded /bin/zsh as the trusted binary.

the current docs already point at this class of problem from two angles. safe bins, which are pre-approved simple tools like grep or wc, are supposed to stay narrow and boring. strict inline eval exists because running code directly inside an interpreter isn’t the same thing as running a saved script. the docs also warn against putting interpreters or shells into safe bins in the first place.

that warning is there because the issue tracker shows the failure mode in plain english. one february issue shows a user approving a harmless whoami command and ending up with /bin/zsh persisted in the allowlist because the runtime executed through /bin/zsh -lc. after that, future commands through the same wrapper no longer needed fresh approval.

that’s not a tiny edge case.

that’s the trust model leaking through a wrapper.

another path is uglier.

a user approves the interpreter instead of one script.

a march issue lays that out directly. allow always stores the resolved binary path and drops the arguments. approve python3 once, and the trust grant stops being about one script. it becomes trust in the interpreter path unless another layer catches the difference. that means python3 with any arguments, any flags, any code passed through -c.

there’s a third issue here.

cross-host approvals don’t always behave the way people assume. openclaw has an open issue for wsl2 gateway to windows node flows where gateway-side path validation breaks node-targeted workdirs. that’s a different class of bug, but it lands in the same place. people think they’re managing approvals. they’re really inheriting wrapper behavior, interpreter behavior, and host-layout assumptions.

that’s why i think approval review needs a firewall model.

what the approval firewall is

the approval firewall isn’t another prompt layer.

it’s a narrower operating model for where trust gets created, how it gets widened, and how you verify the state you already created.

in practice, it comes down to a few rules.

  • gateway trust and node trust are separate. don’t confuse them.

  • copying one client runtime into another is how trust bleeds across boundaries.

  • a shell wrapper hides the real binary inside it.

  • python3 covers every script on the machine, not the one you approved.

  • if the approval ui goes missing, the safer default is to block the action.

  • and every permission-tuning session should leave behind a diff you can inspect later.

that last part matters more than most people realize.

a lot of people don’t have a policy problem.

they have an archaeology problem.

they don’t know what got trusted last week.

what i’d do instead

i’d stop asking one setting to solve all of this.

i’d use a small stack of controls that each do one narrow job well.

start strict

for real work, i’d rather begin with the allowlist set so only approved binaries can run. ask on-miss so the system prompts me when something new tries to execute. askfallback deny so a missing approval ui blocks the action instead of allowing it. and strict inline eval on. if there’s no reachable approval path, the safer default is block. if askfallback is set to full, a missing ui becomes silent trust expansion.

keep safe bins boring

stdin-only filters like wc, cut, head, and tail. nothing fancy. no shells. no interpreters. no file-loader flags that quietly turn one parser into a generalized read path.

treat wrappers as suspect until proven otherwise

if execution keeps flowing through /bin/sh -lc or /bin/zsh -lc, review the resulting approval file right away. don’t assume the trusted thing is the tool you meant.

diff approval state after every tuning pass

not after the incident.

not once a quarter.

right after you add a node, widen shell access, update wrappers, or move one workflow from personal to shared use.

what success looks like

this is the part too many hardening posts skip.

if you apply a strict baseline and the setup is healthy, you should be able to verify a few things fast.

  • check the gateway approvals file. defaults should read deny, on-miss, and deny.

  • your main agent needs to show allowlist, on-miss, and deny.

  • look at the allowlist. shells and interpreters have no business being there, and that includes powershell and pwsh on windows.

  • strict inline eval stays on.

  • node hosts get their own approvals file, separate from the gateway.

  • trust one new binary and check the diff. only that binary should appear. nothing wider.

if you can’t explain a new trust grant in one sentence, don’t keep it.

that’s the whole point of the repo in this post.

OpenClaw is a reader-supported publication. To receive new posts and support my work, consider becoming a free or paid subscriber.

upgrading here gets you the exact build behind articles. deployable configs, hardened baselines, install steps, inspection scripts, verification tooling, risk scoring, 44 tested assertions, ci integration, a beginner walkthrough, fix instructions for every finding type, and real workflows you will run, ship, or sell.

this articles repo built for production

👇 here is the 30+ file repo you need that ships with four core layers

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2026 Josh Davis | substack.com/@joshdavis10x · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture