Sandbox Unblock logo

Sandbox Unblock

CommunityPopular
FlorianBruniaux
sandbox-unblock

Diagnostic protocol to run before reporting a sandbox blocker or asking for a configuration change. Eight checks that eliminate false positives, then a report template the person holding the settings can act on. On one measured day, six of eight reported blockers turned out to be false, all from the same handful of method errors.

Overview

PublisherFlorianBruniaux
Repositoryclaude-code-ultimate-guide
Skill namesandbox-unblock
Stars
6.1K
Forks
807
Bundled files
Instructions only
LicenseCC-BY-SA-4.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by FlorianBruniaux on GitHub. Read the source before you install it.

Installation

Install the Sandbox Unblock AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/FlorianBruniaux/claude-code-ultimate-guide/tree/main/examples/skills/sandbox-unblock
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/FlorianBruniaux/claude-code-ultimate-guide.git /tmp/claude-code-ultimate-guide
mkdir -p .claude/skills
cp -r /tmp/claude-code-ultimate-guide/examples/skills/sandbox-unblock .claude/skills/sandbox-unblock
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Sandbox Unblock in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Sandbox Unblock on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Sandbox Unblock is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Unblock a session slowed by the sandbox

A blocker report is cheap to write and expensive to act on. This skill front-loads the verification so the report that reaches a maintainer is worth their time.

The measurements quoted below come from a single macOS machine on Claude Code 2.1.220, July 2026. Treat the numbers as illustrative and the method as the point.

Self-diagnosis, all eight checks, before you complain

Run these in order. Each step says what to run, what to read, and what the result lets you conclude. Steps 5b and 5c pay for themselves fastest.

1. Do not trust the sandbox description in your system prompt.

It lists the permissions.deny Read(...) patterns under read.denyOnly, things like **/*.pem or **/.env*. Those patterns govern the Read tool and nothing else. A subprocess launched from Bash reads those files without obstacle. One session concluded an entire Python pipeline was unrunnable on that basis; every step of it worked when measured. Never infer a Bash restriction from that list.

2. Confirm the command you are testing actually ran sandboxed.

bash
echo $TMPDIR

A path under the sandbox temp root means the measurement counts. The system temp directory means the invocation escaped, and nothing that follows it proves anything about sandboxed behavior.

3. Put the cd and the command in the same call.

The shell working directory resets between Bash calls. A cd in one call does not survive into the next, so the command you meant to test in a project ran somewhere else entirely. Two independent audits declared a package manager broken this way; the binary was simply absent from the directory they landed in.

bash
# wrong: two calls, the cd does not carry over
cd /path/to/project
pnpm exec prisma migrate status

# right: one call
cd /path/to/project && pnpm exec prisma migrate status

4. Check the binary exists before blaming the sandbox.

Wrappers that compress output often replace a clear message with a bare errno. A missing binary and a security refusal then look identical on screen.

bash
command -v <binary>
./node_modules/.bin/<binary> --version

Nothing returned means you have an installation problem, not a policy problem.

5. Read the real exit code, not a pipe's.

cmd | head returns the exit status of head, never of cmd. A refused read earlier in the session also emits a warning on every later command, including the ones that succeed, so read the last message rather than the first.

bash
cmd > "$TMPDIR/out.log" 2>&1
echo "exit: $?"
cat "$TMPDIR/out.log"

5b. Check whether a command rewriter sits between you and the matcher.

This one explained most of the blockers on the day it was found. If a PreToolUse hook rewrites Bash commands, for example a token-compression proxy that turns pnpm exec tsx x.ts into proxy pnpm exec tsx x.ts, then an excludedCommands entry written as pnpm exec * no longer matches anything. Only the rewritten form matches.

The tell is an inconsistency: some excluded commands escape the sandbox and others do not, with no obvious pattern. Look at whether the ones that work happen to have a prefixed entry in the list.

Proof shape, three measurements. A throwaway entry for an otherwise-sandboxed binary flips a Unix socket bind() from failure to success, which shows the mechanism works at all. The same command under an unprefixed entry stays sandboxed. Adding the prefixed form releases it immediately.

Any entry you request should be asked for in both forms, bare and prefixed.

5c. An entry matches the command exactly as written.

git fetch origin matches git fetch *. git -C /path fetch origin does not. pnpm --dir /path exec tsx x.ts does not match pnpm exec *. A trailing star requires at least one argument, so bare git fetch does not match git fetch * either and stays sandboxed. Rewrite your command in its canonical form before concluding anything.

6. If the configuration changed after your session opened, restart first.

The OS sandbox profile is compiled at session start. Exit and relaunch before measuring anything on a session that predates a settings change.

Two keys were measured as hot-reloaded, credentials.files and excludedCommands, along with the network allowlist. The rest were not tested that way, so keep the restart as your default.

If all eight checks pass and the blocker holds, move to the report template.

Network: blocked host or nonexistent host

The domain allowlist filters even when strict mode is off. Do not assume a permissive default means no filtering; measure with a host you know is outside both your list and the product's built-in defaults.

Duration tells you which failure you hit. A refusal by the allowlist hangs for roughly 5 to 7 seconds. A hostname that does not resolve fails in under 30 milliseconds, including when a wildcard in the list already covers it. On one run, two hosts named in a blocker report failed in about 25 ms while covered by their wildcards: neither host existed. Verify the apex answers before asking for a domain to be added.

Raw TCP to an external host is a separate matter. When the sandbox routes HTTP through a local proxy and cuts direct DNS, anything that is not HTTP has no path out. Cloud Postgres, MySQL, Redis and raw SSH all fail, and no domain entry can fix that. The command has to be excluded, or run outside the sandbox.

Report template

Fill this literally. Do not paraphrase the error: a reworded message cost a full day of misdirected work on the chantier this skill came from.

Exact command typed: <literal copy-paste, every argument included>
Raw error received: <literal copy-paste, not summarized>
$TMPDIR at test time: <exact value>
Sandboxed: <yes if under the sandbox temp root, no otherwise>
Session opened before or after the last config change: <before / after / unknown>
Protocol steps already run: <1, 2, 3, 4, 5, 5b, 5c, 6, with each result>
Workarounds already tried: <list, or "none">
Real impact: <which task is blocked, since when>

Escalation

Hand the filled template to whoever can edit the settings file. Do not edit it yourself from Bash: writes to it are refused from a sandboxed command, and only the Edit tool goes through.

The keys worth knowing under sandbox are excludedCommands, credentials.files, credentials.envVars, filesystem.allowWrite, network.allowedDomains and network.strictAllowlist. Two of them mislead.

credentials.envVars in deny mode does not remove the variable from Bash subprocesses. A listed key stays readable in full. Only credentials.files blocks a read, and only for absolute paths, never for a **/ glob. Moving a secret out of a denied file and into a denied environment variable therefore weakens it.

allowUnsandboxedCommands: false does not neutralize excludedCommands. They are independent: the first closes the per-invocation escape hatch, the second excludes named commands regardless of the first.

Limits with no fix

Verified. Do not reopen an investigation on these.

LimitFindingKnown workaround
Setuid binariesps, top, su, login cannot execlsof -nP -iTCP -sTCP:LISTEN
AF_UNIX socketsbind() refused everywhere, local-binding settings cover TCP onlyrun the loader directly, or bundle then run plain node
Direct DNScut for everyone, all HTTP goes through the local proxyexclude the tool if it needs raw sockets
.idea/ and .vscode/creating the directory works, writing a file inside is refused, in the current project onlyexclude the install command, in both forms

On DNS, never propose adding a generic diagnostic tool such as dig to the excluded list. It would return correct resolutions while the rest of the session stays cut off, which manufactures exactly the kind of false diagnosis this skill exists to prevent.

The .idea scoping matters more than it looks. The refusal applies to the current project, so an audit run from a neighbouring repository will report that nothing is blocked, and be wrong.

See also

Frequently asked questions

What does the Sandbox Unblock AI skill do?

Diagnostic protocol to run before reporting a sandbox blocker or asking for a configuration change. Eight checks that eliminate false positives, then a report template the person holding the settings can act on. On one measured day, six of eight reported blockers turned out to be false, all from the same handful of method errors.

Why use Sandbox Unblock on TypingMind?

Because you install it once and use it with any model. Sandbox Unblock is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Sandbox Unblock in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/FlorianBruniaux/claude-code-ultimate-guide/tree/main/examples/skills/sandbox-unblock. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Sandbox Unblock?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Sandbox Unblock?

As many as you like. As long as a model supports skills, you can use Sandbox Unblock with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Sandbox Unblock AI skill free?

Yes. It is published on GitHub by FlorianBruniaux under the CC-BY-SA-4.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇