Security & Sandboxing
OS sandbox (PTY mode)
Every KANNA_CLAUDE_DRIVER=pty spawn is wrapped with an OS-level sandbox.
- macOS:
/usr/bin/sandbox-exec -f <profile.sb>. Profile generated per spawn fromPOLICY_DEFAULT.readPathDeny+writePathDeny. Default on. - Linux:
/usr/bin/bwrapwith--tmpfs <path>per deny entry. Default on whenbwrapis installed (apt install bubblewrap/pacman -S bubblewrap/dnf install bubblewrap). Silently disables if absent — setKANNA_PTY_SANDBOX=offto suppress the gap. - Windows: PTY refused per spec.
To opt out: KANNA_PTY_SANDBOX=off. Loses defense-in-depth against built-in tool credential reads.
Allowlist preflight
When KANNA_CLAUDE_DRIVER=pty, every spawn passes through the preflight gate (claude-pty/preflight/gate.ts). The gate runs 8 directed probes against the disallowed built-ins (Bash, Edit, Write, Read, Glob, Grep, WebFetch, WebSearch). If any built-in is reachable, the spawn is refused.
Cache TTL: 24 hours, keyed on (binarySha256, tools-string, model). Override the probe model via KANNA_PTY_PREFLIGHT_MODEL (default claude-haiku-4-5-20251001).
Durable approval protocol
Setting KANNA_MCP_TOOL_CALLBACKS=1 routes AskUserQuestion and ExitPlanMode through Kanna’s durable approval protocol. Pending requests survive server restart (resolved as session_closed fail-closed on boot) and replay to the client on reconnect.
Under PTY mode the ask_user_question / exit_plan_mode shims are always registered regardless of this flag — PTY has no canUseTool hook so the durable protocol is the only host path.
Optional KANNA_SERVER_SECRET env var stabilises HMAC tool-request ids across the process lifetime.
OAuth-only PTY
PTY mode is OAuth-only and NEVER uses an API key. buildPtyEnv unconditionally strips ANTHROPIC_API_KEY from the spawned child env — a key left in the parent environment is harmless. It cannot block the spawn and cannot force API billing.
Password gate
KANNA_PASSWORD=<secret> enables an HTTP/WS/API password gate. Every browser session prompts on first connect; the password is stored in sessionStorage and replayed via WebSocket handshake and HTTP headers.
What Kanna does NOT do
- No telemetry to external services
- No remote control surface beyond Cloudflare tunnel (which you explicitly approve per
expose_portcall) - No persistent storage of OAuth tokens outside your
KANNA_HOMEdirectory