Skip to Content

Bash control

Shell command policy for IDE coding agents. Allowlist or deny the commands agents may run in the terminal—package scripts yes, destructive or exfil patterns no.

Part of Control rules with path, MCP, and prompt. Session patterns (retry storms, destructive bursts) are covered by Behavior Guards.

Why it matters

Cursor, Claude Code, Codex, and OpenCode can invoke arbitrary shell from a laptop. Without a shared control channel, each engineer’s agent is a private toolchain—and security only finds out after something leaks or lands on main.

How it works

When an agent proposes a shell action, Relay evaluates bash rules on the decide path before the command runs.

Matchcontains on the command string (or *)
Verdictallow / ask / deny per rule + org Enforcement
HooksClaude/Codex PreToolUse (Bash) · Cursor beforeShellExecution / preToolUse · OpenCode tool.execute.before

Denied calls return a structured reason and land in audit. Pair with path control when the risk is which files a script touches, not only the command text.

Real-world examples

CI and package scripts stay fast

Scene: Engineers ask the agent to “run the test suite and fix failures.” The agent issues npm test, pnpm lint, pytest -q, and scoped git status / git diff.

Policy: Allow rules matching npm test, pnpm , pytest, git status, git diff, git log. Soft ask (or deny) for git push, git commit --no-verify.

Outcome: Day-to-day coding velocity stays high; force-push and hook-bypass commits do not silently ship.

Exfil and wipe patterns stop at the hook

Scene: A prompt says “debug why staging is broken—pull whatever you need from the box.” The agent tries curl https://… | sh, scp, aws s3 cp, or rm -rf /.

Policy: Deny (or Soft ask) on curl |, | sh, wget , scp , rm -rf, mkfs, dd if=. Prefer deny on Cursor if you need a hard stop—Cursor does not reliably prompt on hook ask.

Outcome: Live wire shows the blocked command and rule; the engineer sees a clear deny reason instead of a silent leak.

Also common

  • Secrets in the shell: printenv, cat ~/.aws/credentials, echo $OPENAI_API_KEY — deny contains patterns; still add path for file reads.
  • Infra foot-guns: kubectl delete, terraform destroy, helm uninstall — ask/deny while allowing kubectl get / terraform plan.
  • Behavior Guards: Identical failing npm test retries are Failure Loop; rm -rf bursts are also Destructive Burst. Bash rules catch the first call; Guards catch the pattern.

Allow and deny starters

Allow (examples)

  • npm test, npm run , pnpm , yarn
  • pytest, go test, cargo test
  • git status, git diff, git log, git branch

Deny or ask (examples)

  • curl |, | bash, | sh, wget
  • rm -rf, git push --force, git commit --no-verify
  • kubectl delete, terraform destroy
  • chmod 777, chown (also see Privilege Streak)

Author in Relay → Rulebook with resource_kind=bash. Matching badge: contains.

Connect hooks under Relay → Connect. Related: Path control, Behavior Guards, Seats and policy, Getting started.

Last updated on