PreToolUse hook on the Bash tool, Gemini CLI uses a BeforeTool hook on run_shell_command, Copilot CLI uses a preToolUse hook, and Pi loads CC Safety Net as an in-process extension). See Integration Architecture for the per-agent details. Rather than maintaining a list of forbidden strings, CC Safety Net parses each command into its components and reasons about intent. This page walks through exactly what happens between the moment your agent builds a command and when (or whether) that command runs.
The Hook Pipeline
Agent prepares a Bash command
Your AI agent constructs a shell command to execute — for example,
git reset --hard — and passes it to the Bash tool.PreToolUse hook fires
Before the Bash tool executes anything, CC Safety Net intercepts the call. This happens at the hook layer, which runs before the permission system and before the OS ever sees the command.
Semantic analysis
CC Safety Net parses the command into its components — executable, subcommand, flags, and arguments — and analyzes the intent of the operation. See Semantic Analysis below for details.
Semantic Analysis
CC Safety Net uses semantic analysis rather than simple string matching. This distinction matters in practice. When a command arrives, it is parsed into its structural components:- Executable — the base program (
git,rm,find, etc.) - Subcommand — the operation being requested (
checkout,reset,push, etc.) - Flags — options that modify behavior (
--hard,-f,-r, etc.) - Arguments — the targets the command acts on (file paths, branch names, refs, etc.)
| Command | Intent | Outcome |
|---|---|---|
git checkout -b feature | Creates a new branch | Allowed |
git checkout -- file | Discards uncommitted changes in a file | Blocked |
git checkout. A pattern-matching approach either blocks both or neither. Semantic analysis distinguishes them and makes the right call in each case — protecting you from accidental data loss without blocking everyday workflows.
Shell Wrapper Detection
Wrapping a destructive command in a shell invocation doesn’t hide it from CC Safety Net. Shell wrappers likebash -c '...' are recursively unwrapped and the inner command is subjected to the same semantic analysis. This unwrapping goes up to 10 levels deep.
Interpreter One-Liner Detection
Destructive commands can also be hidden inside interpreter one-liners. By default, CC Safety Net extracts the code passed to an interpreter’s-c or -e flag — for python, python2, python3, node, ruby, and perl — and scans it for embedded destructive operations:
CC_SAFETY_NET_PARANOID_INTERPRETERS=1 to block all interpreter one-liners outright — regardless of their content.
Block Output Format
When CC Safety Net blocks a command, the agent receives a structured response as the tool result. A typical block message looks like this:Audit Logging
Blocked commands are written to a structured log file for later review:| Field | Description |
|---|---|
ts | ISO 8601 timestamp of when the command was handled |
decision | The decision CC Safety Net made: deny (blocked) or allow (permitted) |
command | The full command string as received, truncated to 300 characters |
segment | The specific segment that triggered the block, truncated to 300 characters (may differ for wrapped commands) |
reason | The human-readable reason for blocking |
cwd | The working directory at the time of the call |
- Denied commands are always logged when a session id is available; allowed commands are logged only when
CC_SAFETY_NET_DEBUG=1is set, to keep the log focused on interventions. - Commands blocked because the analyzer itself failed (the fail-closed safety net) are not written to the log.
- Nothing is written when there is no session id available.
- The
doctorcommand summarizes this log as its Recent Activity check (blocked commands from the last 7 days).
Secret Redaction
Block messages and log entries both go through automatic secret redaction before being surfaced to the agent or written to disk. This ensures that if a destructive command happens to include a token, credential, or API key in its arguments, that sensitive data is never exposed in agent responses or audit logs.Known Limitations
CC Safety Net analyzes the command string your agent attempts to run. A few cases are out of scope or not yet handled:- Transparent command proxies — A tool that rewrites or proxies a shell command before it runs (for example
rtk git reset --hard) can bypass analysis, because CC Safety Net sees the proxy executable (rtk) rather than the underlying command. Some top-level proxied commands are caught by the fallback dangerous-text scan, but this is incomplete, and custom rules do not yet apply through proxies. Work is tracked to add a transparent-proxy normalization layer. - Behavior inside binaries — If a command does not visibly contain a destructive operation (for example
some-tool --task destructive-cleanup), command-string analysis cannot infer it. CC Safety Net does not and cannot inspect what arbitrary binaries do at runtime — use sandboxing for that threat. - Reads and network — CC Safety Net has no read-protection or network layer. It does not stop an agent from reading sensitive files or exfiltrating data. See vs Sandboxing.
npx cc-safety-net explain "<command>" to see the analysis, and report genuine bypasses as described in the security policy.