Skip to main content

How to require approval before an AI agent runs risky commands?

Summary

  • Put a policy layer between the agent and its tools, and have it answer "ask" for risky actions. In Omnigent, the open-source meta-harness for coding agents, every policy returns ALLOW, ASK or DENY, and ASK pauses the action until a person approves or rejects it.
  • The builtin ask_on_os_tools policy asks before any file or shell operation. Narrower builtins gate GitHub writes, working-directory changes, PII in model requests, or a per-session risk score that builds up over time.
  • You can add a policy by asking the agent in chat, from the session's info panel in the web UI, in an agent's YAML, or server-wide. Session policies are checked first, then the agent's, then the server's.
  • The open-source project is labeled "Status: alpha". Omnigent on Databricks is in Beta and supports the built-in policies plus custom policies written in CEL; custom Python policies aren't supported there.

How to require approval before an AI agent runs risky commands?

Route the agent's actions through a policy engine and make the risky ones return "ask." Omnigent, an open-source meta-harness for Claude Code, Codex, Cursor, OpenCode, Hermes, Pi and custom agents, does this with policies that "intercept every action (tool calls, LLM requests, file operations)" and decide whether to allow it, ask for approval, or deny it. The quickest gate is the builtin ask_on_os_tools policy, which asks before any file or shell operation. The project's README labels it "Status: alpha".

What can an approval policy decide?

Verdict What happens
ALLOW The action proceeds.
ASK The action is paused for user approval: approved becomes ALLOW, refused becomes DENY.
DENY The action is blocked, and the agent receives an error.

Policies are stateful. Each one "maintains its own state across the entire session," which is how a spend budget or a risk score builds up over many turns. Several policies can be active at once, and they're evaluated in declaration order. In the web UI, an ASK pauses the session and asks whether you want to continue: approve to keep going, or reject to stop the call. The desktop app sends OS notifications when an agent asks for input.

Which builtin policies can pause an agent?

All builtins live under omnigent.policies.builtins. These can pause for approval:

  • ask_on_os_tools "requires user approval before any sys_os_read, sys_os_write, sys_os_edit, or sys_os_shell tool call." It takes no parameters.
  • block_working_dir_changes gates shell commands that change the working directory (cd, pushd, git -C) or manage git worktrees. Set its action to "ask" to approve them case by case; the default is "deny".
  • github_policy restricts writes to write_repos and write_branches, and "shell commands with ambiguous targets return ASK."
  • risk_score_policy "accrues a per-session risk score from tool calls and sensitive data labels" and escalates guarded_tools to ASK or DENY (its escalate_action) once the score exceeds threshold.
  • deny_pii_in_llm_request scans outgoing messages for PII, with an action of DENY or ASK.
  • cel_policy holds custom logic written in CEL (Common Expression Language), configured with an expression and a reason.

How do you add an approval gate?

Policies attach at three levels:

  1. Session (end user). Ask in chat, for example "Add a policy that asks me before running shell commands." The agent has a built-in sys_add_policy tool: it picks a policy from the registry, configures it and asks for your approval. You can also toggle policies from the session's info panel in the web UI.
  2. Agent YAML (developer). Declare a policies block, and it applies every time that agent starts.
  3. Server-wide (admin). Add policies to the server config YAML and start the server with omnigent server --config server_config.yaml, or manage them at runtime through the /v1/policies REST API.

Session policies are evaluated first, then the agent's, then the server's, and all three levels are enforced together. This policies block for an agent's YAML asks before file and shell operations and limits GitHub writes:

policies:
  approve_shell:
    type: function
    handler: omnigent.policies.builtins.safety.ask_on_os_tools
  github_access:
    type: function
    handler: omnigent.policies.builtins.github.github_policy
    factory_params:
      write_repos:
        - myorg/frontend
      write_branches:
        - "feature/*"

When no builtin fits, a custom Python policy on your own server can return ASK. This one pauses only on a destructive shell command and abstains on everything else:

from omnigent.policies.schema import PolicyEvent, PolicyResponse

def ask_before_rm(event: PolicyEvent) -> PolicyResponse | None:
    if event["type"] != "tool_call":
        return None
    if event["data"]["name"] != "sys_os_shell":
        return None
    command = event["data"]["arguments"].get("command", "")
    if "rm -rf" in command:
        return {"result": "ASK"}
    return None

To make it discoverable in chat and the UI, export a POLICY_REGISTRY list from its module and add the module under policy_modules in the server config.

How Databricks approaches agent approvals

On Databricks, "Omnigent is in Beta." Databricks operates a managed Omnigent server that integrates with your workspace's identity provider, and agents get model access through the Foundation Model APIs and Unity Gateway. You need the Omnigent preview enabled for the workspace and a region that supports Unity Gateway. The policy surface is narrower: Omnigent on Databricks "supports the built-in contextual policies and custom policies written in Common Expression Language (CEL). Custom Python policies are not supported." Use the builtins above, or cel_policy, instead of a Python module.

FAQs

Do policies work with Claude Code and Codex?

Yes. The policy tutorial uses a Claude Code session and says policies "work the same across every agent type," and the harness docs say native-TUI mode is "wrapped with Omnigent's collaboration and policy layer."

What happens when I reject a request?

A refused ASK becomes DENY: the action is blocked and the agent receives an error.

Can approval depend on what the agent has already done?

Yes. risk_score_policy adds points per tool call or sensitive data label and escalates guarded tools once the score crosses its threshold. cost_budget asks the first time session spend crosses each soft threshold.

Can I limit what an approved command can touch?

Pair approvals with a sandbox. The enforce_sandbox policy "forces a specific sandbox configuration on agent start," with settings such as allow_network, write_paths and read_paths.

The information provided herein is for general informational purposes only and may not reflect the most current product capabilities or configurations.