mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-06 08:18:58 +00:00
122 lines
5.5 KiB
Text
122 lines
5.5 KiB
Text
---
|
|
title: "Permissions"
|
|
description: "Controlling which tools agents can use"
|
|
---
|
|
|
|
Permissions control which tools an agent can use without human approval. Fabro uses a three-tier permission model that balances agent autonomy with safety — read-only agents can explore the codebase freely, read-write agents can also edit files, and full-access agents can run arbitrary shell commands.
|
|
|
|
## Permission levels
|
|
|
|
| Level | Auto-approved tools | Prompted tools |
|
|
|---|---|---|
|
|
| `read-only` | `read_file`, `read_many_files`, `grep`, `glob`, `list_dir`, sub-agent tools | Everything else requires approval |
|
|
| `read-write` | All read tools + `write_file`, `edit_file`, `apply_patch`, sub-agent tools | `shell`, `web_search`, `web_fetch`, MCP tools |
|
|
| `full` | All tools including `shell`, `web_search`, `web_fetch`, MCP tools | None |
|
|
|
|
The default permission level is `read-write`.
|
|
|
|
## Tool categories
|
|
|
|
Every tool is classified into one of four categories that determine which permission level auto-approves it:
|
|
|
|
| Category | Tools | Minimum level |
|
|
|---|---|---|
|
|
| read | `read_file`, `read_many_files`, `grep`, `glob`, `list_dir` | `read-only` |
|
|
| write | `write_file`, `edit_file`, `apply_patch` | `read-write` |
|
|
| subagent | `spawn_agent`, `send_input`, `wait`, `close_agent` | `read-only` |
|
|
| shell | `shell`, `web_search`, `web_fetch`, MCP tools, unknown tools | `full` |
|
|
|
|
Unknown tools (including MCP tools) default to the `shell` category, requiring `full` permission for auto-approval.
|
|
|
|
## Setting permissions
|
|
|
|
### CLI flag
|
|
|
|
```bash
|
|
fabro exec --permissions read-only
|
|
fabro exec --permissions read-write
|
|
fabro exec --permissions full
|
|
```
|
|
|
|
### Non-interactive mode
|
|
|
|
When running non-interactively (no TTY or `--auto-approve` flag), tools outside the permission level are denied outright:
|
|
|
|
```bash
|
|
# In CI: only allow read and write tools, deny shell
|
|
fabro exec --permissions read-write --auto-approve
|
|
```
|
|
|
|
### Interactive escalation
|
|
|
|
In interactive mode, when an agent calls a tool outside its current permission level, Fabro prompts the user:
|
|
|
|
```
|
|
Agent wants to run: shell(command="cargo test")
|
|
Allow? [y]es / [a]lways / [n]o:
|
|
```
|
|
|
|
- **yes** -- allow this one call
|
|
- **always** -- upgrade the permission level for the rest of the session
|
|
- **no** -- deny the call (the agent receives an error and can try a different approach)
|
|
|
|
Choosing "always" on a write tool upgrades to `read-write`. Choosing "always" on a shell tool upgrades to `full`.
|
|
|
|
## How permissions interact with tools
|
|
|
|
### Read tools are always available
|
|
|
|
Regardless of permission level, agents can always read files, search with grep, and find files with glob. This means even a `read-only` agent can fully explore a codebase.
|
|
|
|
### Write tools require read-write or higher
|
|
|
|
The `write_file`, `edit_file`, and `apply_patch` tools are auto-approved at `read-write` and above. At `read-only`, these tools are either prompted (interactive) or denied (non-interactive).
|
|
|
|
### Shell requires full
|
|
|
|
The `shell` tool and web tools (`web_search`, `web_fetch`) are only auto-approved at the `full` level. This is the most permissive setting since shell commands can do anything the sandbox allows.
|
|
|
|
### Sub-agent tools are always allowed
|
|
|
|
Sub-agent management tools (`spawn_agent`, `send_input`, `wait`, `close_agent`) are auto-approved at all permission levels. Sub-agents inherit the parent's permission level, so a `read-only` parent spawns `read-only` children.
|
|
|
|
## Read-before-write guardrail
|
|
|
|
Independent of the permission system, Fabro enforces a **read-before-write guardrail** that applies to all permission levels. Even with `full` permissions, an agent must read an existing file before modifying or deleting it. See [Tools: Read-before-write guardrail](/agents/tools#read-before-write-guardrail) for details.
|
|
|
|
This guardrail operates at the sandbox layer and works alongside (not instead of) the permission system. A tool call must pass **both** checks:
|
|
|
|
1. The tool's category must be allowed by the current permission level
|
|
2. If writing to an existing file, the file must have been previously read
|
|
|
|
## Permission flow
|
|
|
|
The following sequence shows how Fabro decides whether to execute a tool call:
|
|
|
|
<img src="/images/permission-flow.svg" alt="Permission flow: tool call is checked against current permission level; if auto-approved it executes, otherwise in interactive mode the user is prompted, in non-interactive mode the tool is denied" />
|
|
|
|
## Workflow-level permissions
|
|
|
|
When agents run inside Fabro workflows, the workflow engine manages tool approval. Workflow agents typically run with full auto-approval since the workflow itself defines the trust boundary -- the sandbox provider (local, Docker, or Daytona) controls what the agent can actually access.
|
|
|
|
For CLI-backed workflow agents, each provider handles auto-approval differently:
|
|
- **Anthropic** (Claude Code) -- uses `--dangerously-skip-permissions` to bypass interactive prompts
|
|
- **OpenAI** (Codex) -- uses `--full-auto` mode
|
|
- **Gemini** -- uses `--yolo` flag
|
|
|
|
## Further reading
|
|
|
|
<Columns cols={2}>
|
|
<Card title="Tools" icon="wrench" href="/agents/tools">
|
|
Full reference for built-in tools and their parameters.
|
|
</Card>
|
|
<Card title="Environments" icon="server" href="/execution/environments">
|
|
Sandbox providers that control execution isolation.
|
|
</Card>
|
|
<Card title="MCP" icon="plug" href="/agents/mcp">
|
|
MCP tools follow the same permission model as built-in tools.
|
|
</Card>
|
|
<Card title="Sub-agents" icon="users" href="/agents/subagents">
|
|
Sub-agents inherit their parent's permission level.
|
|
</Card>
|
|
</Columns>
|