# EONYX permissions and security: control over every action


An agent reads code, edits it and runs commands.
So it has to stay **inside explicit permissions**.
EONYX stacks several layers: a static gateway, a file sandbox, plan mode and a hard block on dangerous commands.

<!--more-->

## 🚦 The permission gateway

### Static policy

Tools split in two.
**Always allowed** are the read-only ones.
**Requiring permission** are writes, commands, commits and MCP tools.

No questions asked for `read`, `ls`, `glob`, `grep`, `git_status`, `git_diff`, `git_log`, `todo_write`.
Everything else meets the gateway:

```json
"permissions": {
  "allowed_tools": ["bash", "write", "edit"],
  "sandbox": true
}
```

- **`allowed_tools`** — tools that run without confirmation.
- **`sandbox`** — locks the file tools inside the project root. More below.
- **`--yolo`**, or `/yolo` in the TUI — allows everything for this session.

If a tool is not allowed and `--yolo` is off, the policy denies it: *"permission denied for tool …: re-run with --yolo or add … to permissions.allowed_tools"*.

{{< admonition type="note" title="A denial does not break the flow" >}}
A blocked tool comes back to the model as an **error result**, not a crash.
The model sees the denial and adapts, usually by proposing another route.
The conversation stays consistent.
{{< /admonition >}}

### The interactive layer in the TUI

Interactive mode adds a dialog on top of the static policy.
When the policy refuses a tool, EONYX asks:

- **Allow once** — this one time.
- **Allow always (this session)** — until the session ends.
- **Deny** — reject it. Esc means deny.

"Allow always" remembers the tool for the session, so it stops asking.

### Plan mode

`/plan` is a stricter think-first gate.
While it is on, only read-only tools run: `read`, `ls`, `glob`, `grep`, `picker`, `git_status`, `git_diff`, `git_log`, `fetch`, `task`, `todo_write`.
Anything that writes or executes is blocked, **regardless** of `allowed_tools` and `--yolo`:

> plan mode is on: "…" is blocked until you approve the plan — run /plan to exit plan mode and enable edits

When the plan is ready a dialog appears: **implement**, **allow edits**, or **keep planning**.
Handy when you want the agent to study the code and propose a plan before touching anything.

## 🧱 Boundaries and guardrails

### The file sandbox

`permissions.sandbox: true` locks `read`, `write`, `edit`, `multi_edit` and `ls` inside the **project root**.
That is the directory holding `eonyx.json`, or the working directory if there is none.
A path outside it is refused:

> path "…" is outside the project sandbox (…); set permissions.sandbox to false to allow paths outside the project

The sandbox is **off** by default.
Turn it on for an untrusted task, or when you want a guarantee that nothing outside the project is touched.
Tools with no path argument are unaffected: `bash`, `glob`, `grep`, `fetch` and the git tools.

### Blocking dangerous commands

Below the gateway sits one more, coarser layer.
The built-in shell, `mvdan/sh`, hard-blocks a small set of commands at policy level.
Not even `--yolo` unlocks them:

```text
shutdown · reboot · halt · poweroff · mkfs · init
```

An attempt returns *"command "…" is blocked by shell policy"*.
This is insurance against catastrophe, not real isolation.

### Hooks

**Pre-hooks** add control of your own.
A `before` hook with a non-zero exit code **blocks** the tool.
For example, forbid `bash` when the working directory is your home:

```json
"hooks": {
  "bash": { "before": "[ \"$EONYX_CWD\" = \"$HOME\" ] && exit 1 || exit 0" }
}
```

There is a whole article on hooks.

## 📋 Summary

{{< admonition type="abstract" title="Cheat sheet" >}}
- **Permission gateway**
  - reading is always allowed (`read`, `ls`, `glob`, `grep`, the git status tools, `todo_write`); everything else goes through the gateway
  - `allowed_tools` allows without questions, `--yolo` removes the gateway for the session
  - the TUI asks allow once / always / deny; a denial does not break the flow
- **Plan mode**
  - `/plan` — read-only until you approve the plan
- **Boundaries and guardrails**
  - `sandbox` locks the file tools inside the project root
  - the coarse shell block: `shutdown`/`reboot`/`mkfs`… not even with `--yolo`
  - pre-hooks can block a tool with their exit code
{{< /admonition >}}

