Skip to main content
ChatCLI was designed to be a powerful tool, but power requires control. In Coder Mode (/coder), the AI has the ability to read, write, create, and execute commands on your system. To ensure you are always in control, we implemented a governance system inspired by ClaudeCode.

How Does It Work?

Every time the AI suggests an action (such as creating a file or running a script), ChatCLI checks your local security rules before executing.

The 3 Permission States

Allow (Permitted)

The action is executed automatically, without interruption. Ideal for read commands (read, tree, search) and read-only Git operations (git-status, git-diff, git-log, git-changed, git-branch).

Deny (Blocked)

The action is silently blocked (or with an error for the AI). Ideal for protecting sensitive files or destructive commands.

Ask (Prompt)

ChatCLI pauses and displays an interactive menu for you to decide. This is the default for unconfigured actions.

Interactive Approval Menu

When an action falls into the “Ask” state, you will see a security box with contextual information about the action:
+========================================================+
|              SECURITY CHECK                             |
+========================================================+
 Action: Write file
         file: main.go
 Rule:   no rule for '@coder write'
 --------------------------------------------------------
 Choice:
   [y] Yes, execute (once)
   [a] Always allow (@coder write)
   [n] No, skip
   [d] Always block (@coder write)

 > _
The prompt displays the action in human language (e.g., “Write file”, “Execute shell command”, “Modify file (patch)”) and the parsed details from the JSON arguments, instead of showing raw JSON.

Recognized Action Types

SubcommandPrompt LabelDetails Displayed
execExecute shell command$ <command>, dir: <cwd>
testRun tests$ <command>, dir: <cwd>
writeWrite filefile: <path>
patchModify file (patch)file: <path>
readRead filefile: <path>
searchSearch codeterm: <pattern>, dir: <path>
treeList directory structuredir: <path>

Prompt with Context in Parallel Mode

When the action is requested by a multi-agent mode worker, the prompt includes additional information about which agent is making the request:
+========================================================+
|              SECURITY CHECK                             |
+========================================================+
 Agent:  shell
 Task:   Run auth module tests
 --------------------------------------------------------
 Action: Execute shell command
         $ go test ./pkg/auth/...
 Rule:   no rule for '@coder exec'
 --------------------------------------------------------
This allows you to know exactly which agent is requesting the action and why, facilitating informed security decisions.

Options

1

y (Yes)

Executes only this time. Next time, it will ask again.
2

a (Always)

Creates a permanent ALLOW rule for this command (e.g., allows all writes with @coder write).
3

n (No)

Skips execution. The AI receives an error informing that the user denied.
4

d (Deny)

Creates a permanent DENY rule. The action will be automatically blocked in the future.
For exec commands, the “Always” and “Deny Forever” options are not available, as each execution is unique and requires individual approval.

Rule Management

Rules are saved locally in ~/.chatcli/coder_policy.json. You can edit this file manually if desired, but the interactive menu is the easiest way to configure. The matching uses the effective @coder subcommand even when args is JSON (e.g., {"cmd":"read"} becomes @coder read).

Local Policy (Per Project)

You can add a local policy in the project directory:
  • Local: ./coder_policy.json
  • Global: ~/.chatcli/coder_policy.json
If merge: true, local rules merge with global ones (local overrides matching patterns).
{
  "merge": true,
  "rules": [
    { "pattern": "@coder write", "action": "ask" },
    { "pattern": "@coder exec --cmd 'rm -rf'", "action": "deny" }
  ]
}

Policy Example (coder_policy.json)

{
  "rules": [
    {
      "pattern": "@coder read",
      "action": "allow"
    },
    {
      "pattern": "@coder git-status",
      "action": "allow"
    },
    {
      "pattern": "@coder write",
      "action": "ask"
    },
    {
      "action": "deny",
      "pattern": "@coder exec --cmd 'rm -rf'"
    }
  ]
}

Word Boundary Matching

The policy system uses word boundary matching, ensuring that rules do not partially match different subcommands:
RuleCommandResult
@coder read = allow@coder read file.txtAllowed
@coder read = allow@coder readlink /tmpDoes not match (falls to Ask)
@coder read --file /etc = deny@coder read --file /etc/passwdDeny (path-prefix match)
This means @coder read will never allow @coder readlink or @coder readwrite accidentally.

Command Validation (50+ Patterns)

Beyond policy governance, @coder exec validates each command against 50+ regex patterns that detect:

Data destruction

rm -rf, dd if=, mkfs, drop database

Remote execution

curl | bash, base64 | sh

Code injection

python -c, eval, $(curl ...)

Process substitution

<(cmd), >(cmd)

Kernel manipulation

insmod, modprobe, rmmod

Evasion

${IFS;cmd}, VAR=x; bash
You can add custom patterns via CHATCLI_AGENT_DENYLIST:
export CHATCLI_AGENT_DENYLIST="terraform destroy;kubectl delete namespace"
For the complete list of ChatCLI security protections, see the Security and Hardening documentation.

Best Practices

1

Start with Caution

Keep write commands (write, patch, exec) as ask until you feel confident in the agent.
2

Allow Reads

Generally, it is safe to give “Always” for coder read, coder tree, coder search, and read-only Git (git-status, git-diff, git-log).
3

Be Specific

Matching uses word boundary for subcommand prefixes and path-prefix for arguments. You can allow coder exec --cmd 'ls but block coder exec --cmd 'rm.
4

Safe Exec

@coder exec blocks dangerous patterns by default (50+ rules). Use --allow-unsafe only when necessary.

Governance in Multi-Agent Mode (Parallel)

Security policies are fully respected by multi-agent mode workers. When /coder or /agent operates in parallel mode, each worker checks the coder_policy.json rules before executing any action.

Behavior

RuleWorker Action
allowAction executed automatically by the worker
denyAction blocked; the worker receives [BLOCKED BY POLICY] and continues its flow
askThe worker pauses, the progress spinner is suspended, and the security prompt is displayed
Security prompts from multiple workers are serialized — only one prompt at a time is displayed, avoiding visual overlap. Rules created during the session (via “Always” or “Deny”) are immediately visible to all subsequent workers.

Coder Mode UI

You can control the style and banner of /coder via environment variables:
VariableValuesDescription
CHATCLI_CODER_UIfull (default), minimalInterface style
CHATCLI_CODER_BANNERtrue (default), falseShow/hide the cheat sheet
These settings appear in /status and /config.