Permissions Configuration Guide
This guide explains how to configure custom permission rules for Explore mode.
CLI-first workflow (recommended): Use
vorno-cli permission ...commands instead of editing JSON directly.
vorno-cli permission --help- Canonical command reference: vorno-cli.md
Overview
Section titled “Overview”Explore mode is a read-only mode that blocks potentially destructive operations. Custom permission rules let you allow specific operations that would otherwise be blocked.
Permission files are located at:
- Workspace:
~/.craft-agent/workspaces/{slug}/permissions.json - Source:
~/.craft-agent/workspaces/{slug}/sources/{source}/permissions.json
Auto-Scoping for Source Permissions
Section titled “Auto-Scoping for Source Permissions”Important: MCP patterns in a source’s permissions.json are automatically scoped to that source.
When you write:
{ "pattern": "list", "comment": "Allow list operations" }The system converts it to mcp__<sourceSlug>__.*list internally. This means:
- Simple patterns like
listonly affect tools from that source - No risk of accidentally allowing
listtools from other sources - Workspace-level patterns still apply globally (for intentional cross-source rules)
permissions.json Schema
Section titled “permissions.json Schema”{ "allowedMcpPatterns": [ { "pattern": "list", "comment": "Allow list operations" }, { "pattern": "get", "comment": "Allow get operations" }, { "pattern": "search", "comment": "Allow search operations" } ], "allowedApiEndpoints": [ { "method": "GET", "path": ".*", "comment": "All GET requests" }, { "method": "POST", "path": "^/search", "comment": "Search POST" } ], "allowedBashPatterns": [ { "pattern": "^ls\\s", "comment": "Allow ls commands" } ], "blockedTools": [ "dangerous_tool" ], "allowedWritePaths": [ "/tmp/**", "~/.craft-agent/**" ], "blockedCommandHints": [ { "command": "printf", "reason": "printf is not in the default Explore-mode allowlist.", "context": "Explore mode keeps a narrow read-only command set.", "tryInstead": [ "Use echo for simple output", "Switch to Ask mode for this command" ], "example": "echo '--- separator ---'" }, { "command": "sed", "reason": "Only print-only sed is allowed by default.", "whenNotMatching": "^sed\\s+-n\\b" } ]}Rule Types
Section titled “Rule Types”allowedMcpPatterns
Section titled “allowedMcpPatterns”Regex patterns for MCP tool names to allow in Explore mode.
For source-level permissions.json, use simple patterns (auto-scoped):
{ "allowedMcpPatterns": [ { "pattern": "list", "comment": "All list operations for this source" }, { "pattern": "get", "comment": "All get operations for this source" }, { "pattern": "search", "comment": "All search operations for this source" } ]}For workspace-level permissions.json (global rules), use full patterns:
{ "allowedMcpPatterns": [ { "pattern": "^mcp__.*__list", "comment": "List operations across all sources" } ]}allowedApiEndpoints
Section titled “allowedApiEndpoints”Fine-grained rules for API source requests.
{ "allowedApiEndpoints": [ { "method": "GET", "path": ".*", "comment": "All GET requests" }, { "method": "POST", "path": "^/search", "comment": "Search POST" }, { "method": "POST", "path": "^/v1/query$", "comment": "Query endpoint" } ]}allowedBashPatterns
Section titled “allowedBashPatterns”Regex patterns for bash commands to allow.
{ "allowedBashPatterns": [ { "pattern": "^ls\\s", "comment": "ls commands" }, { "pattern": "^git\\s+status", "comment": "git status" }, { "pattern": "^pwd$", "comment": "pwd command" } ]}blockedTools
Section titled “blockedTools”Additional tools to block (rarely needed).
{ "blockedTools": ["risky_tool_name"]}allowedWritePaths
Section titled “allowedWritePaths”Glob patterns for directories where writes are allowed.
{ "allowedWritePaths": [ "/tmp/**", "~/.craft-agent/**", "/path/to/project/output/**" ]}blockedCommandHints
Section titled “blockedCommandHints”Command-specific guidance shown when a Bash command is blocked in Explore mode. This provides deterministic explanations for known commands instead of relying only on closest-pattern heuristics.
{ "blockedCommandHints": [ { "command": "printf", "reason": "printf is not in the default Explore-mode allowlist.", "context": "Explore mode keeps a narrow read-only command set.", "tryInstead": [ "Use echo for simple output", "Switch to Ask mode for this command" ], "example": "echo '--- separator ---'" }, { "command": "sed", "reason": "Only print-only sed is allowed by default.", "whenNotMatching": "^sed\\s+-n\\b" } ]}Fields:
command(required): Base command name (e.g.printf,sed)reason(required): Primary explanation shown to the usercontext(optional): Additional policy/risk contexttryInstead(optional): Suggested alternativesexample(optional): Example commandwhenNotMatching(optional): Regex condition; hint applies only when command does not match this pattern
Default Behavior in Explore Mode
Section titled “Default Behavior in Explore Mode”Blocked by default:
- Bash commands (except read-only commands listed below)
- Write, Edit, MultiEdit tools
- MCP tools with write semantics (create, update, delete)
- API POST/PUT/DELETE requests
Allowed by default:
- Read, Glob, Grep
- WebFetch, WebSearch
- TodoWrite
- Browser tools (
browser_*andmcp__session__browser_*) - MCP tools with read semantics (list, get, search)
- Plans folder writes (session plans only)
Read-Only Bash Commands
Section titled “Read-Only Bash Commands”These commands are allowed in Explore mode without custom configuration:
| Category | Commands |
|---|---|
| File exploration | ls, tree, cat, head, tail, nl, file, stat, wc, du, df |
| Search | find, grep, rg, ag, fd, locate, which |
| Git (read-only) | git status, git log, git diff, git show, git branch, git blame, git reflog |
| GitHub CLI | gh pr view/list, gh issue view/list, gh repo view |
| Package managers | npm ls/list/outdated, yarn list, pip list, cargo tree |
| Quality checks (read-only) | bun run typecheck, bun run typecheck:all, bunx tsc --noEmit, tsc --noEmit, npm run typecheck, yarn typecheck, pnpm typecheck |
| Browser helper | bun run browser-tool --help, bun run browser-tool list, bun run browser-tool template ..., bun run browser-tool parse-url <url> |
| System info | pwd, whoami, env, ps, uname, hostname, date, echo |
| Text processing | awk/gawk/mawk/nawk (safe forms), jq, yq, sort, uniq, cut, column |
| Network diagnostics | ping, dig, nslookup, netstat |
| Version checks | node --version, python --version, etc. |
Notes:
echois allowed for literal output formatting (e.g.echo ---), but redirects and command substitution are still blocked.awkfamily commands are allowed for read-only text processing, but dangerous execution primitives (for examplesystem(...), command-pipegetline, orprint | "cmd") are blocked.
Compound Commands
Section titled “Compound Commands”Compound commands using &&, ||, and | are allowed when all parts are safe:
| Construct | Example | Behavior |
|---|---|---|
| Logical AND | git status && git log |
✅ Allowed if both commands are safe |
| Logical OR | git status || echo "failed" |
✅ Allowed if both commands are safe |
| Pipes | git log | head |
✅ Allowed if all commands are safe |
Each command is validated independently. If any command is not in the allowlist, the entire compound command is blocked.
Blocked Shell Constructs
Section titled “Blocked Shell Constructs”These constructs are always blocked, even if the base command is allowed:
| Construct | Examples | Why Blocked |
|---|---|---|
| Background execution | & |
Runs asynchronously, could hide activity |
| Redirects | >, >> |
Could overwrite files |
| Command substitution | $(), backticks, <(), >() |
Execute embedded commands |
| Control characters | newlines, carriage returns | Act as command separators |
Example: git status > file.txt is blocked because > could overwrite files.
Cascading Rules
Section titled “Cascading Rules”Rules cascade from workspace → source → agent:
- Workspace rules apply globally
- Source rules extend workspace rules for that source
- Agent rules extend both for that agent’s session
Rules are additive - they can only allow more operations, not restrict further.
Best Practices
Section titled “Best Practices”- Be specific with patterns - Use anchors (^, $) to avoid over-matching
- Add comments - Explain why each rule exists
- Test patterns - Verify regex matches expected tool names
- Minimal permissions - Only allow what’s needed
Examples
Section titled “Examples”Read-only Linear access:
Section titled “Read-only Linear access:”{ "allowedMcpPatterns": [ { "pattern": "^mcp__linear__(list|get|search)", "comment": "Read operations" } ]}Search-only API:
Section titled “Search-only API:”{ "allowedApiEndpoints": [ { "method": "GET", "path": ".*" }, { "method": "POST", "path": "^/search" } ]}Safe git commands:
Section titled “Safe git commands:”{ "allowedBashPatterns": [ { "pattern": "^git\\s+(status|log|diff|branch)", "comment": "Read-only git" } ]}Planning in Explore Mode
Section titled “Planning in Explore Mode”In Explore mode, you can create implementation plans that the user can accept to transition to execution.
When to Create Plans
Section titled “When to Create Plans”Create a plan when:
- The task has multiple complex steps
- You want user approval before making changes
- You’ve gathered enough context and are ready to implement
Creating a Plan
Section titled “Creating a Plan”- Write your plan to a markdown file in the session’s plans folder
- Call
SubmitPlanwith the file path - The user sees a formatted plan with an “Accept Plan” button
- Clicking “Accept Plan” exits Explore mode and begins implementation
Plan Format
Section titled “Plan Format”# Plan Title
## SummaryBrief description of what this plan accomplishes.
## Steps1. **Step description** - Details and approach2. **Another step** - More details3. ...Explore → Implementation Workflow
Section titled “Explore → Implementation Workflow”The recommended workflow:
- Explore - Read files, search code, understand the codebase
- Plan - Write a structured plan to the plans folder
- Submit - Call
SubmitPlanto present to user - Accept - User clicks “Accept Plan” to exit Explore mode
- Execute - Implement the plan with full permissions
This provides a smooth transition from exploration to implementation with user oversight.