Skip to content

Permissions & sandbox

Every mutating tool call passes through the permission engine before it runs. You control it with modes (how permissive the session is), rules (per-tool allow/deny/ask patterns), and optionally an OS-level sandbox underneath everything.

Where settings live (keep them lean)

FileRole
~/.hipmmcode/settings.jsonPreferred home for permissions.defaultMode and long-lived allow / deny / ask rules (Claude-compatible layered settings)
Project .hipmmcode/settings.json / .hipmmcode/settings.local.jsonProject shared vs local (gitignored) rules
~/.hipmmcode/config.jsonModels, API keys, MCP, UI — not a dump of hundreds of one-shot allow rules

From v0.14.1, a first run seeds a minimal user settings file when none exists:

json
{
  "permissions": {
    "defaultMode": "auto"
  }
}

Prefer this Claude-simple shape. Do not copy huge historical allow lists from other tools — use Auto mode for low-risk calls, and only add allow entries you deliberately “always allow”.

Upgrading the binary does not overwrite your settings; it also does not re-inject old one-shot grants from the package. Dirty allow lists only come from local files you (or past “don’t ask again” clicks) wrote.

Permission modes

ModeBehavior
autoDefault for new installs (v0.14.1+). Classifier auto-allows lower-risk tool calls; blocks or asks on riskier ones. Aligns with Claude Code’s Auto default
defaultManual: read-only tools free; mutating calls prompt (or follow your rules)
acceptEditsFile edits auto-approved; risky shell still prompts
planRead-only planning — no mutations until you approve the plan (EnterPlanMode / /plan)
bypassPermissionsEverything allowed except explicit deny rules
dontAskRestrictive mode (not in the casual Shift+Tab cycle)

Switch anytime:

  • Shift+Tab cycles modes mid-session (status bar shows the active mode). Typical cycle: default → acceptEdits → plan → (auto when available) → …
  • /permissions mode auto
  • CLI: --permission-mode auto|plan|…, or --dangerously-skip-permissions (= bypass).

A disableAutoMode managed-settings killswitch can ban Auto org-wide.

The approval prompt

When a gated tool call needs your decision, an in-terminal dialog appears — the streaming pauses until you answer:

hipmmcode
Bash command

  npm install

 Allow once
  Allow always  — persist an allow rule for this command
  Deny          (Esc)

↑/↓ move · Enter confirm · Shift+Tab switch mode

Allow always records a permanent allow rule into a settings layer you pick (user / project / local), so the same command never prompts again. Prefer short, intentional rules — not a long dump of one-off commands. The dialog header names the tool ("Bash command", "Edit file", "Fetch", …) and the body shows exactly what will run.

While a /workflows monitor panel is open, a pending tool approval preempts the panel (permission focus outranks the monitor) so you are not surprised only after Esc-closing the panel.

A policy killswitch (disableBypassPermissionsMode) can disable bypass org-wide.

Rules

Rules live in config (permissions) and standard settings files, and are also editable live:

/permissions allow  Bash(git push:*)
/permissions deny   Bash(rm -rf:*)
/permissions ask    FileWrite(src/**)
/permissions                # view current rules + mode

JSON shape:

json
{
  "permissions": {
    "allow": ["Bash(git status:*)", "FileEdit(src/**)"],
    "deny":  ["Bash(sudo:*)", "WebFetch"],
    "ask":   ["Bash(git push:*)"]
  }
}

Rule syntax: Tool (whole tool) or Tool(specifier) — command prefix patterns for Bash (Bash(git push:*)), glob paths for file tools (FileEdit(src/**)), mcp__server or mcp__server__tool for MCP. Precedence: deny > ask > allow, and the more specific rule wins. During a session you can answer a prompt with "always allow", which records a session-scoped grant.

Built-in guardrails

Independent of your rules:

  • Bash read-only classifierls, git status, grep, … run without prompts; state-changing commands prompt (bashPromptForWrites, default on).
  • Destructive-command hard block — catastrophic patterns (rm -rf /, disk-wiping, protected-branch force-push) are refused outright, in every mode.
  • Protected-path write confirmation — writes to sensitive paths (shell rc files, credentials) always confirm.
  • Workspace boundary — file access outside cwd + --add-dir roots asks first (confirmOutsideWorkspace, default on).
  • Trust dialog — first time you run hipmmcode in a directory, it asks whether to trust it (trustedDirs).

Unattended runs

With no human present, ask decisions fail closed (denied). For automation, choose deliberately:

OptionUse
--permission-mode acceptEditsCI that edits files but must not run risky shell
--dangerously-skip-permissionsFully trusted sandboxed environments only
--permission-webhook <url>Your service decides: receives each request, replies allow / deny / allow_always
--permission-prompt-tool <mcp-tool>Delegate decisions to an MCP tool

The same fail-closed rule applies to the server task queue and hooks-driven runs.

Auto mode (default) & classifier config

Session mode auto (the v0.14.1 default) routes ask-bucket tool calls through a classifier: lower-risk actions run without a human prompt; high-risk or unclear actions are blocked or fall back carefully (never open a silent hole when the classifier is unavailable).

Optional autoMode config (in settings / config) tunes the classifier with natural-language intents:

json
{
  "autoMode": {
    "allow": ["push to the feature branch", "delete files under .cache/"],
    "hard_deny": ["never destroy production databases"],
    "classifierModel": "claude-haiku-4-5",
    "classifyAllShell": false
  }
}
FieldMeaning
allow / soft_deny / hard_deny / environmentNatural-language policy buckets for the classifier (not shell globs)
classifierModelCheap model for yes/no classification (defaults per provider when unset)
classifyAllShellWhen true, suspend positive Bash allow rules and classify every shell call

A disableAutoMode policy killswitch exists for org-managed setups.

OS sandbox

For real OS-level isolation of shell commands (beyond permission prompts), hipmmcode ships a sandbox backend: bubblewrap on Linux, Seatbelt on macOS. Off by default.

Config keyEnvEffect
sandbox.enabledHIPMMCODE_SANDBOX=1Master switch — Bash runs inside the sandbox
sandbox.allowNetworkHIPMMCODE_SANDBOX_NETWORK=1Allow outbound network inside the sandbox
sandbox.writableRootsHIPMMCODE_SANDBOX_WRITABLE=/a:/bExtra writable roots (default: cwd, HOME, tmp)
sandbox.hideRootsHIPMMCODE_SANDBOX_HIDE=/secretPaths masked entirely (multi-tenant isolation)
sandbox.failIfUnavailableHIPMMCODE_SANDBOX_FAIL=1Refuse to run commands if no sandbox backend exists

With the sandbox on, even an allow-ed command physically cannot write outside its writable roots or reach hidden paths.

Worktree isolation

Orthogonal to permissions: run risky work in a git worktree so the main checkout stays clean — /worktree <name> for the session, Agent(isolation: "worktree") per teammate, /worktree exit keep|remove when done. worktreeBaseRef picks the base (head or fresh).