Permissions

Maki uses a permission system to decide what each tool is allowed to do and when to ask you first.

Rules come from three layers, checked in this order:

  1. Session rules, set during the current session (in-memory only)
  2. Config rules, loaded from TOML permission files
  3. Builtin rules, the hardcoded defaults

First match wins.

Check Flow

For every tool call, Maki resolves permission like this:

  1. If any deny rule matches, denied. Full stop.
  2. If YOLO is active, allowed.
  3. If all scopes match an allow rule, allowed.
  4. Fall back to default (per-tool, then global). Built-in default is "prompt".

Builtin Defaults

ToolScopeNotes
writeProject directoryFiles outside require permission
editProject directoryFiles outside require permission
multieditProject directoryFiles outside require permission
task* (all)Subagent spawning always allowed

These tools require explicit permission:

  • bash - Shell commands
  • websearch - Web search queries
  • webfetch - URL fetching

Container tools like batch and code_execution prompt for each inner tool individually.

TOML Configuration

There are two permission files:

  • Global: ~/.config/maki/permissions.toml
  • Project: .maki/permissions.toml (takes precedence over global)
default = "deny"

[bash]
allow = [
    "cargo *",
    "git *",
]
deny = [
    "rm -rf *",
    "sudo *",
]

[read]
allow = true

Each tool gets its own section with allow and deny arrays. Values are glob-like scope patterns, or true to match everything.

The default key

Controls what happens when no allow or deny rule matches. Can be "prompt" (built-in default), "deny", or "allow". Set it globally or per-tool:

default = "deny"

[bash]
default = "prompt"
allow = ["cargo *"]

Here everything is denied by default, except bash which still prompts, and cargo * commands which are allowed.

Note: default = "allow" only works in the global file. Projects cannot grant themselves full access.

Scope Patterns

PatternMatches
*Any single value
**Everything
prefix*Values starting with prefix
dir/**dir itself or anything under it
exactExact match only

Permission Prompts

When a tool needs permission, Maki asks you. Here are the keys:

KeyAction
yAllow once
sAllow for this session
aAlways allow (project, saved to .maki/permissions.toml)
AAlways allow (global, saved to ~/.config/maki/permissions.toml)
nDeny once
dDeny always (project)
DDeny always (global)

Scope Generalization

When you pick "always allow", the saved scope is generalized so it stays useful beyond just that one command:

  • bash: cargo test --all becomes cargo *
  • write/edit/multiedit: /path/to/file.rs becomes /path/to/**
  • MCP tools: always * (per-tool, so allowing mcp:fetch won't cover mcp:exec)
  • webfetch/websearch: always *

Deny rules are saved with the exact scope. You denied something specific, so it stays specific.

YOLO Mode

To skip all prompts, toggle YOLO with the /yolo command, or run with --yolo. Explicit deny rules still apply.

To start in YOLO mode every time:

-- ~/.config/maki/init.lua
maki.setup({
    always_yolo = true,
})

Bash Command Parsing

Bash commands get parsed with tree-sitter to extract individual commands. Something like cd /tmp && cargo test is checked as two separate commands.

Some constructs are too complex to analyze statically, so they always trigger a prompt:

  • Command substitution: $(...), backticks
  • Process substitution: <(...), >(...)
  • Subshells: (...), { ... }
  • Arithmetic expansion: $((...))

Session Persistence

When you save a session, its permission rules are saved too. Loading the session restores them.