OpenClaw exec approvals advanced
The stdin-only safe bins fast path and its denied flags, trusted binary directories, shell chaining and wrapper rules, interpreter binding, the approvals scope, forwarding prompts to chat channels and native approval clients
The core exec approvals page explains the policy and the prompt. The advanced page is where the sharp edges live: which binaries are allowed to skip the allowlist because they can only read stdin, how the gateway binds an interpreter command to the exact files it will run, which scope a dashboard needs to approve anything, and how a prompt reaches a chat channel and comes back as a decision. Here is that page condensed.
Safe bins
- The safe bins setting names stdin-only binaries that run in allowlist mode without explicit entries, cut, uniq, head, tail, tr and wc by default; they reject positional file arguments and path-like tokens, treat arguments as literal text with no globbing or variable expansion, and validation is deterministic from the argument shape alone, with unknown long flags and ambiguous abbreviations rejected fail-closed and unrecognized short flags falling through to the approval policy.
- grep and sort are not default safe bins and keep explicit allowlist entries for their non-stdin workflows, grep in safe-bin mode taking its pattern only through the explicit pattern flag; awk, sed and jq are always denied as safe bins because their semantics cannot be validated to stdin-only; interpreters and runtimes must never be added, custom safe bins need an explicit profile, the audit warns about unprofiled interpreter bins and the doctor fix can scaffold empty custom profiles to tighten afterwards.
- Safe bins must resolve from trusted directories, the two default system paths, with search-path entries never auto-trusted, so package-manager paths go into the trusted directory list explicitly; the denied-flag list per profile blocks file-reading options such as the recursive and file flags of grep, the output and file-list options of sort, follow on tail and the file-list option on wc.
- Shell chaining is allowed when every top-level segment satisfies the allowlist, redirections stay unsupported, command substitution is rejected even inside double quotes, shell wrappers reduce request environment overrides to a small list, allow-always decisions persist the inner executable behind transparent wrappers and unwrap shell multiplexer applets, and strict inline evaluation keeps inline eval behind review when interpreters are allowlisted.
Session delivery only controls where the prompt appears. It does not by itself authorize every participant in that chat to approve.
Interpreter binding and the approvals scope
Approval-backed interpreter runs are deliberately conservative. The exact arguments, working directory and environment are bound; on the gateway the whole external dispatch chain, each wrapper executable and the final one, is bound before review and re-checked before launch, protected executables by real path and writable ones also by content hash, so a new executable earlier on the search path denies the run. Direct scripts and runtime files are bound to one file snapshot, common package-manager wrappers are unwrapped first, and when the gateway cannot identify exactly one local file, package scripts, eval forms or loader chains, approval-backed execution is denied rather than pretending to cover it. In automatic mode the reviewer only handles fully bound chains: shell command wrappers, environment assignments, applets and builtin dispatch skip automatic review and take the one-shot human path, login and interactive shell wrappers need a human because their startup files sit outside binding, and interactive code-loading options stay denied. When approval is required the tool returns an approval id immediately, a decision that never arrives is a timeout surfaced as a host-command denial with the originating session resumed so the agent sees that the command did not run, and pending approvals expire after 30 minutes. Resolving an approval needs the dedicated approvals scope, which write does not subsume, and the docs call it remote-execution-grade authority to grant deliberately even to a small approval interface.
Forwarding to chat
- The exec approvals forwarding block sends prompts to any chat channel through the normal outbound pipeline, in session, targets or both mode with agent and session filters and channel plus recipient targets; the agent relays an approve command only from an actual pending approval with its exact id, a bare or invented id approves nothing, an allow-once grant covers one command, and the same command resolves plugin approvals when the id is not a pending exec one, with the plugin family configured independently.
- The originating chat can approve by default on Slack, Matrix, Teams and similar deliverable surfaces, while Discord, Telegram and the QQ bot use their resolved approver lists even in the same chat; native approval clients add approver direct messages, origin-chat fanout and interactive cards, enabled per channel with resolvable approvers, Telegram defaulting to automatic and approver messages, and a card that reaches no target falling back to a same-chat notice with the exact command.
- A target can carry an account id to send through one specific bot account and a thread id to stay inside a forum topic; the official mobile apps review pending approvals on an admin connection or when their approvals device was targeted, re-reading the record when an acknowledgement is lost; and the macOS path runs over a same-user socket with a token, a challenge and a short lifetime.
OpenClaw exec approvals is the core policy this page extends and OpenClaw sandboxing explained the boundary the docs prefer for workflows the binding cannot cover.
Why the fast path is narrow
The whole safe-bin design rests on one property: a binary that can only read its stdin cannot exfiltrate a file the policy did not mean to expose. Every rule follows from it, the rejection of positional paths, the literal arguments, the denied file flags, the ban on interpreters and on jq, and the trusted directories that stop a look-alike binary earlier on the search path. The moment a tool can open files or evaluate code, the docs send it to the allowlist with a prompt instead. Telegram on Diali and Slack on Diali are two Diali channels where forwarded prompts can land.
On Diali
On Diali the runtime configuration is generated from the dashboard and replaced at each release, and each customer runtime is its own boundary. Hosted OpenClaw on Diali describes the hosted assistant and Diali security the controls around every command it runs.
- Safe bins read stdin only; interpreters never qualify.
- Interpreter runs bind the whole chain or are denied.
- Approving needs the approvals scope, not write.
Stop reading about it, build one
Set up an agent, pick a channel, and have it working inside the app you already keep open.
