Permissions and auto-approve
Decide which actions Hull runs on its own, which ones it asks about, and which ones it never runs.
Every tool call an agent makes, such as reading a file, editing code or running a shell command, goes through a permission check. Each check resolves to one of three actions:
| Action | What happens |
|---|---|
allow | Hull runs it without asking. |
ask | Hull pauses and asks you first. |
deny | Hull blocks it. |
The same rules apply in Hull Desktop, the CLI, the VS Code extension and the JetBrains plugin, because they all read the same config.
Allowing actions removes a safety check. An agent with broad shell or edit access can delete files or run harmful commands. Allow only what you trust, and prefer narrow patterns over "*": "allow".
Defaults
Out of the box, most tools are allowed. These ask first:
- Shell commands (
bash). Common read-only commands such asls,cat,grep,rgandgit status-style inspection run without asking. - Reading
.envfiles.*.envand*.env.*ask, while*.env.exampleis allowed. - Files outside the project (
external_directory). - Repeated failures (
doom_loop), when an agent keeps calling a tool the same way. - Saving and recalling project memory.
Edits to Hull's own config files (hull.json, hull.jsonc, opencode.json, AGENTS.md at the project root, and anything in .hull/) always ask, and you can't approve them permanently.
If no rule matches, Hull asks.
Answer a permission prompt
When an action needs approval, Hull shows a prompt. You can:
- Allow once: run this call only.
- Allow always: run it, and save an
allowrule in your global config so matching calls don't ask again. For shell commands, Hull offers patterns of different breadth (for examplegit *,git status *or the exact command), and saves only the one you pick. - Reject: block this call.
Turn on auto-approve
Auto-approve answers every permission prompt with yes. Rules set to deny still block.
| Surface | How |
|---|---|
| VS Code | Click the shield button under the prompt, or press Cmd+Alt+A (macOS) / Ctrl+Alt+A. To start with it on, set hull-code.new.autoApprove.enabled to true. |
| JetBrains | Click the auto-approve button under the prompt. |
| CLI | Run /auto-approve. For headless runs, pass --auto to hull run. |
Configure rules
Set rules under permission in hull.json, either globally (~/.config/hull/hull.json) or per project. In VS Code, the Settings > Auto-Approve tab edits the same rules with Allow, Ask and Deny menus.
A rule is either one action for the whole tool, or a map of patterns to actions:
{
"$schema": "https://app.withhull.com/config.json",
"permission": {
"read": "allow",
"edit": {
"*": "ask",
"docs/*": "allow"
},
"bash": {
"*": "ask",
"git status *": "allow",
"npm test *": "allow",
"rm *": "deny"
}
}
}Set "permission": "allow" or "ask" to apply one action to everything. Set a key to null to remove a rule you inherited from another config file.
Last match wins
When several rules match, the last one wins. Put broad fallbacks first and exceptions after them:
"bash": {
"*": "ask",
"uv *": "allow" // uv commands run without asking
}If you put "*" last, it overrides everything above it. The same applies to top-level keys: { "*": "ask", "bash": "allow" } allows shell commands, while { "bash": "allow", "*": "ask" } makes them ask.
Patterns
| Pattern | Matches |
|---|---|
* | Anything for that tool |
git * | git and any git command |
git status * | git status, with or without arguments |
src/* | Paths under src/ |
*.env | Files ending in .env, at any depth |
* matches any characters, including /. ? matches one character. Backslashes are treated as forward slashes, so write patterns with /. A leading ~ or $HOME expands to your home directory.
File tools check the path relative to your project, so use project-relative patterns like src/*.
Shell commands
Hull parses shell input into individual commands and checks each one. If any command is denied, the whole request is blocked. For example, with "git *": "deny", the input cd /project; git status is blocked.
Tools you can control
| Key | Controls |
|---|---|
read | Reading files |
edit | Creating, editing and patching files |
glob, grep, list | Finding files and searching their contents |
bash | Shell commands |
external_directory | Paths outside the project |
task | Starting subagents |
skill | Loading skills |
webfetch, websearch | Fetching URLs and searching the web |
lsp | Language server queries |
todowrite | Updating the task list |
question | Asking you questions |
doom_loop | Continuing after repeated identical tool calls |
agent_manager | Starting and prompting Agent Manager sessions (VS Code) |
Files outside the project
external_directory controls tool calls that touch paths outside the folder Hull started in:
"permission": {
"external_directory": { "~/projects/shared/*": "allow" },
"edit": { "~/projects/shared/*": "deny" }
}Allowed external paths inherit your other rules, so reads are allowed there by default. Add explicit rules, as above, to block edits.
MCP tools
MCP tools use the key <server>_<tool>, for example github_create_pull_request:
"permission": {
"github_*": "ask",
"github_get_file_contents": "allow",
"github_delete_file": "deny"
}See MCP for setting up servers.
Subagents
Use task to control which subagents an agent can start:
"permission": {
"task": { "*": "deny", "code-reviewer": "allow" }
}Rules for one agent
Give an agent its own rules under agent.<name>.permission. They're applied on top of your global rules:
{
"permission": { "bash": { "*": "ask" } },
"agent": {
"code": { "permission": { "bash": { "*": "ask", "git *": "allow" } } },
"plan": { "permission": { "bash": "deny" } }
}
}In an agent's Markdown file, write the same rules in YAML frontmatter:
---
description: Reviews code without changing it
mode: subagent
permission:
edit: deny
bash:
"*": deny
"git diff *": allow
"git log *": allow
---If you build a read-only agent, deny shell commands by default and allow only the ones you trust. See Custom agents.
Headless runs
hull run can't show prompts. Anything that would ask is rejected and the run fails, unless you pass --auto (approve every request) or --dangerously-skip-permissions (approve anything not denied). For CI, the safest option is to allow exactly what the job needs in the project's hull.json. See Run headlessly.
Troubleshooting
- A rule seems ignored. Check whether a later rule, such as a
"*"catch-all, also matches. - A broad allow doesn't cover
.envfiles. Reading.envfiles is treated as sensitive and still asks. - A shell command asks unexpectedly. It may contain several commands, or touch a path outside the project.
- Editing
hull.jsonalways asks. Config files are protected on purpose.