Permissions
Every tool call goes through a permission check before it runs. The default is "ask each time"; you can pre-grant categories or paths to cut down on prompts without giving up auditability.
The categories
| Category | Covers |
|---|---|
| Filesystem read | read_file, list_dir, path_complete, MCP filesystem reads |
| Filesystem write | write_file, MCP filesystem writes |
| Shell | bash and any MCP server that exposes a command-execution tool |
| Network | web_search, web_fetch, MCP servers that talk to external HTTP |
| Specific MCP servers | Per-server grants (e.g. "GitHub: enabled", "Slack: ask each time") |
A tool call must clear both the category and any path-specific rules.
Granularity
Three levels, from most to least restrictive:
- Ask each time (default) — modal pops up showing the exact arguments. Approve / deny / approve-all-for-session.
- Approved for session — the tool runs without prompting until the session ends, then resets.
- Always allowed (with scope) — never prompts. Most useful for filesystem reads scoped to a project root.
You can also explicitly Deny a category — Kenaz will not prompt and the tool will fail closed.
Scoping filesystem grants
For Filesystem read/write, grants can be scoped:
- Anywhere — risky, only do this knowingly.
- Within these paths — e.g.
/Users/you/code/project-aplus/tmp/project-a-work. The check is a strict prefix match after symlink resolution. - Project root — the path attached to the active project. Switches automatically when you switch projects.
A tool call against a path outside the granted scope falls back to "Ask each time" — you can approve the one-off without widening the scope.
The deny-list
Some paths are denied unconditionally and can't be grant-overridden:
/ /etc /private/etc
/System /Library /private
/Applications /usr/bin /usr/sbin
/sbin /bin /proc
/sys /boot /dev
/tmp, /private/tmp, /var/folders, and /private/var/folders are explicit re-allows so test- and harness-workspace dirs work on macOS.
If you legitimately need to read e.g. /etc/hostname, the ask-each-time prompt still works — the deny-list only blocks blanket grants from covering those roots, not one-shot approvals.
Per-MCP grants
Each MCP server gets its own grant configuration. Permissions view → MCP servers tab. For a server like notion-mcp:
- Always ask (default for newly-added)
- Approved for session
- Trusted — never prompts; tools fire silently. Use only for servers you wrote or audited.
Safe-by-default writes
Filesystem write grants come with two extra guards Kenaz applies independently of the model:
- No overwrite without confirmation — even with a path-scoped write grant, an existing file triggers an "overwrite?" check. You can pre-grant overwrite per-file, but the default is the safe one.
- Atomic writes — Kenaz writes to a
.tmpsibling and atomically renames. If the tool crashes mid-write, the original file is intact.
Audit trail
Every permission decision lands in the audit log — the prompt, the arguments, what you decided, and the timestamp. So even when you've pre-granted a category, the record of every individual call is still there.
Open the Audit view → filter kind = "permission.decided" to review.
Suggested starter setup
For most users, after the first day:
- Filesystem read — Always allowed → Project root only. The model can read code files without pinging you.
- Filesystem write — Always allowed → Project root only. Same idea.
- Shell — Ask each time. This is the dangerous one; don't pre-grant.
- Network — Approved for session. Web search is rarely problematic.
- All MCPs — Always ask until you've used them enough to know what they call. Then promote individually.
You can change any of this any time from the Permissions view; nothing is sticky beyond what you set.