Skip to content

Permissions

Luna uses a multi-layered permission system: permission modes (global), per-mode rulesets (fine-grained), danger detection (regex-based), and an optional AI classifier (LLM-based).

Permission Modes

Five modes control which tools the agent can use. Set via CLI flag, config file, or TUI.

ModeDescription
defaultStandard mode. Per-mode rulesets determine allow/deny/ask per tool.
allow-allNo restrictions. All operations proceed without checks.
deny-allAgent can only reason -- no tool execution at all.
read-onlyOnly read-category tools allowed (read_file, glob_search, grep_search, etc.).
autoAI classifier evaluates "ask" decisions automatically when confidence >= 0.85.

Setting Permission Mode

bash
luajit client/main.lua --permission-mode default
luajit client/main.lua -p auto
luajit client/main.lua -p allow-all

Config file (~/.luna/config.json):

json
{
  "permission_mode": "auto"
}

TUI slash command:

/auto

Per-Mode Rulesets

Each agent mode has a built-in permission ruleset that maps tool names to allow, deny, or ask.

Build Mode

ToolDecisionNotes
read_file, glob_search, grep_search, list_directory, web_fetch, lsp, web_search, todo, fuzzy_editallowRead/search always allowed
bashaskUser approval required
write_fileask (except *.md -> allow)File pattern matching supported
edit_file, create_directory, undo_editaskUser approval required
delete_filedenyAlways blocked

Plan Mode

ToolDecision
Read/search/web toolsallow
* (default)deny

Explore Mode

ToolDecision
Read/search/lsp toolsallow
* (default)deny

Review Mode

ToolDecision
Read/search/lsp/web toolsallow
web_fetchask
* (default)deny

General Mode

ToolDecision
* (default)allow
bashask
delete_fileask

Coordinate Mode

ToolDecision
* (default)allow (orchestrator needs full access)

File Pattern Matching

Rulesets support file pattern matching for tools that take file paths:

json
{
  "write_file": {
    "default": "ask",
    "patterns": {
      "*.md": "allow",
      "*.env": "deny"
    }
  }
}

Patterns use glob syntax: *.ext, path/prefix*, etc.

Danger Detection

Before evaluating the ruleset, the danger detector scans bash commands against 41 regex patterns across 8 categories:

CategoryExampleDefault Severity
Destructive deleterm -rf /, rm -rf ~dangerous
Remote code executioncurl | bash, wget | shdangerous
System controlshutdown, halt, poweroffdangerous
Privilege escalationsudo, chmod 777caution
Network exfiltrationscp, rsync to remotecaution
File removalrm - with flagscaution

Override behavior:

  • dangerous overrides allow to deny
  • caution overrides allow to ask

Shell Quoting

All shell arguments are wrapped using cel.shell_quote (single-quote wrapping) to prevent injection from LLM-generated parameters. This blocks $(), backticks, $VAR expansion, and other shell metacharacters.

AI Classifier (Auto Mode)

When permission_mode is auto, an Ollama-hosted LLM classifies "ask" decisions:

Tool invocation -> Ruleset -> "ask"
    |
    +-- AI classifier available?
    |   +-- Yes -> Classify (5s timeout)
    |   |   +-- confidence >= 0.85 -> auto allow/deny
    |   |   +-- confidence < 0.85 -> TUI dialog
    |   +-- No -> TUI dialog
    +-- Not auto mode -> TUI dialog

Configuration

json
{
  "classifier": {
    "enabled": true,
    "model": "qwen2.5-coder:7b",
    "provider": "ollama",
    "base_url": "http://localhost:11434",
    "confidence_threshold": 0.85,
    "timeout": 5,
    "cache_size": 64
  }
}
SettingDefaultDescription
enabledfalseGlobal enable/disable
modelqwen2.5-coder:7bClassifier model (fast local recommended)
confidence_threshold0.85Minimum confidence for auto-decision
timeout5Seconds before fallback to dialog
cache_size64LRU cache entries for repeated invocations

Safety Guarantees

The classifier never blocks tool execution on failure:

ScenarioBehavior
Classifier model unavailableShow TUI dialog
Request timeout (>5s)Show TUI dialog
Response unparseableShow TUI dialog
Confidence below thresholdShow TUI dialog

Environment Overrides

VariableDescription
LUNA_CLASSIFIER_ENABLED"true" / "false"
LUNA_CLASSIFIER_MODELOverride classifier model
LUNA_CLASSIFIER_PROVIDEROverride classifier provider
LUNA_CLASSIFIER_THRESHOLDOverride confidence threshold (0.0--1.0)

Permission Evaluation Flow

1. Global mode check
   +-- allow-all -> execute immediately
   +-- deny-all -> block immediately
   +-- read-only -> only allow read-category tools

2. Mode ruleset evaluation
   +-- allow -> execute
   +-- deny -> block
   +-- ask -> danger analysis
       +-- dangerous -> deny (override)
       +-- caution + allow -> ask (upgrade)
       +-- ask -> permission_mode check
           +-- auto -> AI classifier
           +-- other -> TUI permission dialog

3. TUI dialog -> user approves/denies

Mutation Queue

Write operations (write_file, edit_file, delete_file) are serialized through a mutation queue. This prevents race conditions when the agent executes multiple concurrent tool calls that modify the same files.

Tool Restrictions

Tools can be restricted for sub-agents spawned via the task tool. Pass a tools array to limit the sub-agent to a subset of available tools:

json
{
  "prompt": "Read the README and summarize it",
  "tools": ["read_file", "glob_search"]
}

Teammate agents spawned via team_spawn run with restricted permissions (no sub-agent, no memory).

Released under the MIT License.