Skip to content

BlastShield is in beta and may contain bugs. Validate it in a non-production environment before relying on it for safety-critical workflows.

Getting Started

[!WARNING] BlastShield is still in beta and may contain bugs. Validate it in a non-production environment before depending on it for safety-critical workflows.

Sandbox AI coding agents with kernel-level protection against destructive cloud CLI commands.

Uses macOS sandbox-exec (Apple Seatbelt) to enforce filesystem restrictions that prevent AI agents from executing destructive operations — terraform destroy, gcloud compute instances delete, aws s3 rb, az group delete, kubectl delete namespace — even when running with --dangerously-skip-permissions or equivalent unrestricted modes.

Existing macOS sandbox tools for AI agents (sandvault, agent-safehouse, agent-seatbelt) focus on protecting secrets and dotfiles. None of them address cloud CLI destructive commands. An agent with access to your cloud credentials can delete your infrastructure in seconds. BlastShield fills that gap.

Built-in agent sandboxes (Claude’s /sandbox, Codex’s approval policies) only gate their own tools. An agent that shells out via Bash or Python bypasses all of it. OS-level enforcement can’t be bypassed — the kernel doesn’t care what the agent thinks it’s allowed to do.

Layer 1: blastshield — Filesystem/Process Sandbox (sandbox-exec)

Section titled “Layer 1: blastshield — Filesystem/Process Sandbox (sandbox-exec)”

Kernel-level. Blocks access to credential files, state files, and protected paths. The agent process physically cannot read or write the files it would need to authenticate destructive operations.

Terminal window
# Run Claude Code with all auto-detected cloud protections
blastshield claude --dangerously-skip-permissions
# Run Codex with full auto-approve
blastshield codex --full-auto
# Run OpenCode with explicit profiles
blastshield -p terraform -p aws opencode
# Run any command
blastshield -p kubectl bash

Layer 2: blastshield-guard — Command-Argument Filter

Section titled “Layer 2: blastshield-guard — Command-Argument Filter”

sandbox-exec operates at file/process level and cannot filter by command arguments. BlastShield Guard wraps cloud CLIs and blocks destructive subcommands. When launched through blastshield, temporary runtime wrappers are injected automatically ahead of your current PATH, including repo-local and Hermit shims invoked by command name.

Persistent wrappers are also available for regular shell use outside BlastShield:

Terminal window
# Install guard wrappers
blastshield-guard install
# Add to PATH (before real CLIs)
export PATH="$HOME/.blastshield/guard:$PATH"

Persistent wrappers prompt for Touch ID. Runtime wrappers hard-block mutating commands inside the agent sandbox. terraform plan passes through immediately.

Terminal window
brew install cdrxyz/tap/blastshield
Terminal window
# Clone
git clone https://github.com/cdrxyz/blastshield.git
cd blastshield
# Add to PATH
export PATH="$PWD:$PATH"
Terminal window
# Auto-detect cloud profiles from project directory
blastshield claude --dangerously-skip-permissions
# Or with Codex
blastshield codex --full-auto
# Or with OpenCode
blastshield opencode
# Explicit profiles
blastshield -p terraform codex
blastshield -p gcloud -p aws opencode
# Clean environment (strip API keys from env vars)
blastshield -c claude --dangerously-skip-permissions
blastshield -c codex --full-auto
blastshield -c opencode
# Disable auto-detection
blastshield --no-detect claude
blastshield --no-detect codex
blastshield --no-detect opencode

BlastShield composes with existing tools — layer them for defense in depth:

Terminal window
# blastshield (cloud CLI policy) → safehouse (file policy) → agent's sandbox
blastshield -p terraform -- safehouse claude --dangerously-skip-permissions
blastshield -p aws -- safehouse codex --full-auto
blastshield -p kubectl -- safehouse opencode

With GUI Agent Apps (Conductor, Cursor, IntelliJ, VSCode)

Section titled “With GUI Agent Apps (Conductor, Cursor, IntelliJ, VSCode)”

Many AI agent IDEs and launcher apps run as GUI applications but still spawn agent CLIs as child processes. BlastShield can protect those sessions by wrapping the app’s process using the macOS open command.

General pattern for any GUI app:

Terminal window
blastshield open /Applications/AppName.app

Note: For GUI agent apps, add the gui-app profile to grant the additional filesystem and IPC permissions they need:

Terminal window
blastshield -p gui-app open /Applications/Conductor.app

When BlastShield detects a .app launch, it skips project profile auto-detection so app startup checks can use normal CLI auth configuration such as GitHub CLI’s hosts.yml. Runtime guards still stay on the app’s PATH. Add explicit profiles with -p terraform, -p gh, or similar if you want those profile-level credential restrictions for a GUI app.

This works for:

  • Conductor (/Applications/Conductor.app)
  • Cursor (/Applications/Cursor.app)
  • IntelliJ IDEA (/Applications/IntelliJ\ IDEA.app)
  • VSCode (/Applications/Visual\ Studio\ Code.app)

Why this works: open launches the app, and BlastShield’s sandbox applies to the app process and all its children. When the app spawns codex, claude, or other agent CLIs, those child processes inherit the sandbox restrictions and runtime guards.

Alternate pattern (if the app supports custom agent commands):

Configure the app to run the BlastShield-wrapped CLI directly:

Terminal window
blastshield codex --full-auto
blastshield claude --dangerously-skip-permissions
blastshield opencode

What matters is the process tree: The sandbox applies to the process and child processes started inside BlastShield. If the app launches agent processes inside that tree, both the filesystem sandbox and command-argument guards protect the session. If the app hands work off to an already-running service outside that process tree, BlastShield cannot protect it.

Conductor-specific example:

Terminal window
# Wrap Conductor itself (the GUI app) with GUI app permissions
blastshield -p gui-app open /Applications/Conductor.app
# OR: if Conductor lets you customize the agent command, point it to BlastShield
# Example agent command in Conductor settings:
blastshield -p gui-app codex --full-auto
blastshield -p gui-app claude --dangerously-skip-permissions

Runtime guards are enabled automatically by blastshield. Use --no-guard to disable them for a launch.

Terminal window
# Install to default location
blastshield-guard install
# Install to custom location
blastshield-guard install ~/bin/guard
# List guarded CLIs
blastshield-guard list
# Check if a command would be blocked
blastshield-guard check terraform destroy # exit 1 = blocked
blastshield-guard check terraform plan # exit 0 = allowed
# Uninstall
blastshield-guard uninstall
Terminal window
# Show detected CLIs and auto-detected profiles
blastshield --status
# Show recent sandbox violations from system log
blastshield --violations
BlockedAllowed
terraform applyterraform plan
terraform destroyterraform init, fmt, validate
terraform import, taint, untaintterraform show, output, console
terraform refreshstate list, state show
terraform state rm/mvworkspace list, workspace select
ALL tfstate writesterraform providers, version, graph
BlockedAllowed
gcloud * delete/create/deploy/updategcloud * list/describe/get
gcloud * add/remove/patch/setgcloud auth status
gcloud * enable/disable/submitgcloud config list/get
gcloud builds submitgcloud version, help
gcloud app deploy
Service account key reads
BlockedAllowed
aws * delete/create/put/updateaws * describe-/list-/get-
aws * deploy/terminate/run-aws s3 ls, cp (download), presign
aws * start-/stop-/rebootaws sts get-caller-identity
aws * authorize/revoke/sendaws logs describe-/get-/filter-
Credential readsaws dynamodb scan/query/get-item
SSO token cache readsaws iam list-/get-
CDK/SAM state writesaws lambda list-, invoke
BlockedAllowed
az * delete/create/update/deployaz * list/show
az * set/remove/add/lock/unlockaz account show/list
az * scale/restartaz version, help
ALL ~/.azure access
BlockedAllowed
kubectl apply/create/deletekubectl get/describe/logs
kubectl patch/scale/execkubectl top, events
kubectl taint/cordon/uncordon/drainkubectl api-resources/versions/explain
kubectl rollout restart/undokubectl auth can-i
kubectl label/annotate/setkubectl config view/get-contexts
kubectl expose/run/cp/debugkubectl rollout status/history
Kubeconfig writeskubectl version
Helm install/upgrade/deleteHelm list/status/show/search
BlockedAllowed
gh repo delete/edit/renamegh repo list/view/clone/fork
gh pr merge/closegh pr list/view/diff/checkout
gh release deletegh release create/list/view/download
gh workflow disable/enablegh workflow list/view
gh run cancelgh issue create/list/view/comment
gh api -X DELETE/PUT/PATCHgh pr create
Workflow file writesgh auth status
CODEOWNERS writesgh secret set

Blocks AI agents from installing new dependencies without human review. Protects both the command-argument level (via guard) and the filesystem level (via sandbox profile).

BlockedAllowed
npm install / ci / addnpm list / ls / view / info / outdated
yarn add / install / removeyarn list / info / why / outdated
pnpm add / install / removepnpm list / info / why / outdated
pip install / uninstall / buildpip list / show / freeze / check
brew install / reinstall / uninstallbrew list / info / search / outdated
gem install / uninstall / buildgem list / search / spec / query
cargo install / add / rmcargo search / tree / list / metadata
hermit install / uninstall / upgradehermit list / search / help / info
apt install / remove / purgeapt list / search / show / cache
dnf install / remove / upgradednf list / search / info / check
Global package directories (writes)Global package directories (reads)
Lockfile writesLockfile reads
┌─────────────────────────────────────────────────┐
│ AI Agent │
│ (Claude Code, Codex, OpenCode, Cursor, Gemini, etc.) │
└──────────────────┬──────────────────────────────┘
┌──────────────┼──────────────────┐
│ ▼ │
│ Layer 2: blastshield-guard │
│ (command-argument filter) │
│ • Intercepts destructive │
│ subcommands via PATH wrappers │
│ • Requires Touch ID / password │
│ • Passes safe commands through │
└──────────────┬──────────────────┘
┌──────────────┼──────────────────┐
│ ▼ │
│ Layer 1: blastshield │
│ (sandbox-exec profiles) │
│ • Kernel-enforced file policy │
│ • Blocks credential reads │
│ • Blocks state file writes │
│ • Protects backend configs │
└──────────────┬──────────────────┘
┌──────────────┼──────────────────┐
│ ▼ │
│ Layer 0: agent's built-in │
│ sandbox (Claude /sandbox, │
│ Codex approval policies) │
│ • Tool-level gating │
│ • Network filtering │
└──────────────┬──────────────────┘
macOS Kernel

Each layer handles what the layer above cannot:

  • Layer 0 handles tool-level permissions (agent’s own sandbox)
  • Layer 1 handles filesystem/process-level restrictions (kernel-enforced, cannot be bypassed)
  • Layer 2 handles command-argument filtering (what sandbox-exec cannot see)

Profiles are SBPL (Seatbelt Profile Language) files in profiles/. They compose by intersection — every deny rule from every profile is enforced.

ProfileAlways LoadedPurpose
baseMinimum viable sandbox: deny-all default, project writes, system reads
secretsProtect SSH keys, cloud creds, browser data, shell init files
terraformAutoState file protection, backend config locks, credential denial
gcloudAutoGCP credential protection, SA key denial, ADC protection
awsAutoAWS credential protection, SSO cache denial, state locks
azureAutoAzure credential protection, MSAL cache denial, ARM protection
kubectlAutoKubeconfig write protection, SA token denial, Helm lock protection
ghAutoGitHub auth protection, workflow file protection, CODEOWNERS locks
installAutoPackage manager install blocking, lockfile protection, global dir protection

Create profiles in ~/.config/blastshield/profiles/:

;; ~/.config/blastshield/profiles/custom.sb
;; Deny access to internal API keys directory
(deny file-read* (subpath "/Users/you/secrets"))
(deny file-write* (subpath "/Users/you/secrets"))

Load with -p:

Terminal window
blastshield -p custom claude

BlastShield scans your project directory for indicator files:

ProfileTriggers
terraform*.tf files
gcloud.gcloudignore, cloudbuild.yaml, app.yaml
awsserverless.yml, template.yaml, cdk.json, samconfig.toml
azureazure-pipelines.yml, local.settings.json
kubectlkustomization.yaml, Chart.yaml, skaffold.yaml
gh.github/ directory
installpackage.json, requirements.txt, Pipfile, pyproject.toml, Gemfile, Cargo.toml, go.mod, .hermit
  • macOS only. sandbox-exec is Apple-specific. For Linux, use bubblewrap.
  • sandbox-exec is deprecated by Apple (since 10.15). Still works on Sequoia. No replacement exists for ad-hoc CLI sandboxing.
  • Network is open by default. If a secret enters the process (env var without -c, or fetched via credential helper), it can be exfiltrated. The sandbox operates at file paths, not content.
  • Keychain access is allowed so credential helpers work. An agent can perform authenticated actions (e.g., git push) but cannot read raw tokens from files.
  • Layer 2 (guard) is a speed bump, not a hard boundary. A determined agent that specifies full paths to CLIs bypasses PATH wrappers. Runtime guards cover Hermit and repo-local shims when invoked by command name. Layer 1 (sandbox) is the hard boundary.
  • No nested sandboxes. macOS doesn’t support recursive sandbox-exec. If an app already runs in a sandbox, use --no-sandbox equivalent.
ProjectApproachCloud CLI Protection?
sandvaultSeparate macOS user account + sandbox-exec❌ File/secrets only
agent-safehouseComposable profiles, Homebrew, website❌ File/secrets only
agent-seatbeltTwo-file minimal wrapper❌ File/secrets only
BlastShieldsandbox-exec + command-argument guard✅ Cloud CLI focus

BlastShield composes with all of the above. Use sandvault for user isolation, safehouse for file policy, and BlastShield for cloud CLI protection.

Apache License 2.0