HumboldtDocs
Use Hum

Sandbox and approvals

Commands and file edits run in a local sandbox. Leaving it asks first.

Sandbox

  • Writes: only under the working directory, temp and caches.
  • Network: none beyond this machine.
  • Read-only to the agent: .hum/, .claude/, .codex/, .git/hooks, .git/config.

macOS: Seatbelt. Linux: bubblewrap (apt install bubblewrap). Neither: /tools shows sandbox: none.

On Windows there is no sandbox, so ~/.hum/run/, which holds the token that opens a running engine's socket, stays readable by anything you can run.

!cmd runs as you, unconfined. MCP servers run with their own process's reach.

Credential-like variables (*KEY*, *PASSWORD*, *SECRET*, *TOKEN*, *CREDENTIAL*, HUM_*) are stripped from the model's commands.

[sandbox]
env_pass = ["GITHUB_TOKEN"]     # or HUM_ENV_PASS=A,B for one run

Approval panel

Shown when a command needs more than the sandbox allows.

Key Effect
enter Approve once
a Approve and allow this shape for the session
p Approve and write the rule to the project
Type a reason Refuse; the model reads it
esc Stop

/approve makes every change wait for you. Leaving the sandbox asks regardless.

Rules

~/.hum/config.toml (yours) or <repo>/.hum/config.toml (the project's):

[permissions]
allow = ["bash(git commit:*)"]   # never asks
ask   = ["bash(git push:*)"]     # always asks; refused unattended
deny  = ["bash(rm -rf:*)"]       # never runs

Chained commands (&&, ;, ||, |) need every part allowed. Substitutions, redirections and unclosed quotes are asked about.

/permissions          # rules in force and where they came from

Settings

[sandbox]
mode = "workspace"    # workspace | required | off
network = false
writable = ["~/go/pkg"]
env_pass = []

HUM_SANDBOX=off for one run. Even off, file tools never write .hum/, .claude/ or .codex/.

mode = "required" refuses to start a session on a machine with no sandbox. File tools never read through a symlink into what the sandbox hides (~/.ssh, ~/.hum/credentials.json, ~/.hum/run).