Skip to main content

Sandbox & approval: auto / full-auto / never

Pick the right sandbox mode (auto / full-auto / never), read an approval card, understand the fail-closed design, and how sandbox sits orthogonal to plugin permission boundaries.

8 min read

What you'll learn

  • Understand DSH sandbox's three modes (auto / full-auto / never)
  • How approval requests render in the UI
  • Pick the right mode for your workflow (dev debugging vs unattended long tasks vs strict review)

Version

Compatible with: dsh 0.1.1-rc.2 (compiled from official apps/cli/README + docs/user/guide/)

Three sandbox modes

Every DSH tool call flows through the sandbox. The sandbox.mode setting in your profile config picks the default:

ModeTrigger conditionUI behaviorBest for
autoAllows calls that match "inferred-safe" rules, otherwise promptsoccasional cardseveryday users
full-autoallows everything, no promptscompletely silentunattended long tasks / CI
neverevery call promptsalways promptsstrict review / learning

The mode can be set as the default in profile config or switched live in Web GUI via the "Sandbox" dropdown in the top bar.

Approval card anatomy

When a command needs human approval, the UI renders a card with:

  • Tool name + arguments (e.g. bash("curl -I https://api.example.com"))
  • File / network / process impact inference
  • Three buttons: "Allow once", "Allow for session", "Deny"
  • Triggering plugin name

See dsh-approve-for-me for the "approve-for-me / strict-review" GUI presets — the former delegates approvals to a lightweight model, the latter forces per-step human review.

Fail-closed by design

DSH sandbox defaults to fail-closed: approval decision fails, model timeout, parse error → always deny. This prevents the disaster scenario where a broken approval subsystem silently frees the model to run any command.

Practical implications:

  • Don't set the approval-decision model with a very short timeout (e.g. 3s); network jitter would break every tool call
  • When the approval subsystem (lightweight model) is unavailable, switch to never mode for manual review — don't try to "bypass" the sandbox

How sandbox relates to permission boundaries

Sandbox decides "do we ask?" — it doesn't decide "is this plugin allowed to do this?". Permission boundaries come from bundle declarations + Cordis service injection. The two are orthogonal:

  • allowed + plugin has permission → command runs
  • allowed + plugin lacks permission → error (plugin doesn't have service X)
  • denied + plugin has permission → card rejected
  • denied + plugin lacks permission → card rejected (missing permission is moot)

Troubleshooting

  • "full-auto ran a command that shouldn't be approved": usually a plugin hooked the approval pipeline; check dsh --profile X --dump-patches for patches injecting approve service
  • "never mode freezes the whole session": a single card can pick "Allow for session" to approve a whole category of similar commands
  • "auto mode blocks obviously safe commands": relax the rule set in profile config; rule names live at cordis.services.config.sandbox.rules

FAQ

Does the sandbox recognize npm install?

Yes. auto mode defaults npm install to "inferred-safe" (only modifies project node_modules + package.json); when there's no lockfile it escalates to "requires review".

Can it block curl?

Yes, and it does by default. Under full-auto, even curl requires a whitelist (configurable by the user). DSH is intentionally stricter than traditional agents here.