AI agent

Agent permission model

Tool calls have allow / ask / deny tiers; configurable per vault.

Why an agent needs permissions

The agent's ability to act is its value — and its risk. LLMs occasionally take you literally — "clean up the old stuff" might mean "rm a batch of files" to them. The permission model is the last guardrail.

Kition's design principle: reads are lenient (no nag), writes are tight (confirm), destructive ops default to deny (opt in explicitly). This is empirical, not theoretical.

Three tiers

  • allow — silent execute (good for Read)
  • ask — prompt for confirmation (good for Write / Bash)
  • deny — permanent block (sensitive vaults)

Where to set

Settings → Agent → Permissions is the GUI entry. Each vault can override via .kition/permissions.json. Vault wins over global.

Every permission decision is logged — see Settings → Agent → Audit log. Denied calls leave a record so you can later decide whether to allow them.

A layered permission config

{
  "tools": {
    "Read": { "default": "allow" },
    "grep": { "default": "allow" },
    "glob": { "default": "allow" },

    "Write": {
      "default": "ask",
      "rules": [
        { "path": "drafts/**", "decision": "allow" },
        { "path": ".env*", "decision": "deny" },
        { "path": "published/**", "decision": "ask" }
      ]
    },

    "Bash": {
      "default": "ask",
      "rules": [
        { "command_matches": "^git (status|diff|log)", "decision": "allow" },
        { "command_matches": "^rm\\s", "decision": "deny" },
        { "command_matches": "\\bsudo\\b", "decision": "deny" }
      ]
    },

    "browser_open": { "default": "ask" },
    "web_fetch": { "default": "allow" },

    "mcp:github:create_issue": { "default": "ask" },
    "mcp:postgres-readonly:*": { "default": "allow" }
  }
}

Path globs and command patterns

  • Path supports minimatch — drafts/, /*.md, !secrets/**
  • command_matches is a regex — JSON requires double backslash escaping
  • Multiple rules for one tool match top-down, first hit wins
  • No match falls back to default
  • deny always beats allow — exclusion rules cannot be overridden

Combine with hooks for finer control

Permissions answer "yes / no / ask". Hooks answer "under what condition, mutated how". Example: allow Bash, but a PreToolUse hook rewrites every rm to trash (move to trash instead of delete).

Permissions and hooks chain: permission check first, then allow / ask calls enter the PreToolUse hook, which can still block. Two layers of defense.

Related articles

Ready when you are.

Kition is a local-first AI workspace. Markdown documents, structured tables, and an AI agent — running on your own machine, against the model provider you choose.