Securing an agent: safety, permissions, and trusted folders
On this page
Lesson rewritten on November 2, 2026. The previous version described the
safetyfield as a permission level. Vibe’s documentation is explicit: it is a visual indicator that colors the input border; it enforces nothing. Real protection comes from tool lists, per-tool permissions, and trusted folders. Sources: Safety, approvals, and permissions · Configuration reference.
What safety does (and doesn’t do)
The safety field in an agent file accepts five values: safe, neutral (the default), destructive, smart, and yolo. It changes the border color of the input area to give you an at-a-glance reminder of which agent you’re using. It does not remove tools or trigger approval prompts. An agent marked safe but equipped with unrestricted bash can still run destructive commands.
There is one exception: when an administrator disables auto-approval (enable_auto_approve = false), Vibe hides all agents marked yolo. Otherwise, safety is a label, not a lock. Always pair it with the real controls below.
First lever: available tools
enabled_tools (allowlist) and disabled_tools (denylist, applied afterward) decide what the agent can call. They accept exact names, glob patterns, and regular expressions prefixed with re:.
# Read-only audit agent
display_name = "Security Audit"
safety = "safe"
enabled_tools = ["read_file", "grep"]
If a tool isn’t on the list, it doesn’t exist for that agent. This is your strongest guarantee.
Second lever: per-tool permissions
For available tools, a [tools.<tool>] block sets the rule: "always" (no prompt), "ask" (prompt every time), or "never" (block).
display_name = "Refactoring"
safety = "neutral"
enabled_tools = ["read_file", "grep", "edit", "write_file", "bash"]
[tools.edit]
permission = "always"
[tools.write_file]
permission = "ask"
[tools.bash]
permission = "ask"
allowlist = ["git status", "git diff", "pnpm test"]
denylist = ["rm -rf", "git push"]
For bash, allowlist and denylist specify command prefixes that are always allowed or always denied. Vibe allows a few read-only commands by default (ls, pwd, cat, git status, etc.), but any list you write replaces the default list: include any default commands you want to keep. For read_file, write_file, and edit, these lists accept absolute path patterns. One prudent rule: a script run via bash can construct paths that Vibe doesn’t see in the command itself; keep bash set to "ask" whenever the stakes justify it.
Third lever: working directory scope
By default, Vibe prompts before a file or shell tool accesses a path outside the working directory, even via a symbolic link, and before reading or modifying .env and .envrc files. You can harden this behavior:
outside_workdir = "deny" # deny instead of prompting; the agent receives an error and continues
Fourth lever: trusted folders
A repository can bundle its own Vibe configuration (agents, skills, MCP servers, permissions) in a .vibe/ folder, or instructions in an AGENTS.md file. Since this configuration changes Vibe’s behavior, it loads only from a folder you have explicitly approved. On first launch, Vibe lists detected files and offers Trust folder, Trust full repo, or Don’t trust; your choices are saved in ~/.vibe/trusted_folders.toml. The dialog does not analyze these files: review them like any other code in the repo, especially MCP server definitions and permissions. In programmatic mode, Vibe never prompts: vibe --trust grants temporary trust for a single execution.
Responding to an approval prompt
When Vibe prompts, four keyboard responses are possible: 1 or y allows once, 2 for the rest of the session, 3 always, and 4, n, or Escape denies. The border color reminds you which agent is active.
Choosing the right balance
| Need | Setting |
|---|---|
| Analyze without touching anything | enabled_tools = ["read_file", "grep"] |
| Refactor with confidence | edit set to "always", bash set to "ask" with an allowlist of test commands |
| Clean up a project | bash set to "ask" and a denylist of irreversible commands |
| Unattended task in CI | Ephemeral container, vibe --prompt … --auto-approve, limits --max-turns and --time-limit |
The golden rule remains least privilege: give each agent the minimum necessary, start restrictive, and open up only as needed.
Key takeaways
safety(safe,neutral,destructive,smart,yolo) colors the border; it enforces no permissions- Real locks:
enabled_tools/disabled_tools, then[tools.<tool>](always,ask,never) - For
bash,allowlistanddenylistreplace default lists - Vibe prompts before leaving the working directory or touching
.envfiles - Project configuration loads only in a trusted folder; review it before approving