Guard hook

Examples

echo '{"command":"curl -X DELETE https://api.stripe.com/v1/refunds"}' | porticol-cli guard hook cursor
echo '{"tool_name":"Bash","tool_input":{"command":"curl -X POST https://api.stripe.com/v1/refunds"}}' | porticol-cli guard hook claude

Usage

porticol-cli guard hook <claude|codex|cursor> [--data-dir <path>]

Options

Option What it does
claude read a Claude Code PreToolUse hook and answer its hookSpecificOutput
codex read a Codex hook and answer with an exit code: 0 allows, 2 denies with the reason on standard error
cursor read a Cursor shell or MCP hook and answer { "permission": … }
--data-dir <path> the workspace holding the policy: PORTICOL_DATA_DIR, or the desktop's data folder

Guard hook

The hook reads one JSON event on standard input. Claude Code and Codex run their shell's network through Porticol's proxy, so their hooks leave every HTTP call to it and answer nothing for the command. They fail closed on a command that names a guarded host where Guard reads no plain call, or that changes how its calls reach the proxy: Claude Code asks, and Codex refuses with the reason. Cursor has no proxy, so its hook decides one plain call it reads: a denied call is refused, one the policy asks about waits 25 seconds for a person's approval in Porticol, and a command that names a guarded host or runs an HTTP tool in any other form asks. A command that runs no HTTP tool and names no policy host is left to the agent. Each decision is recorded in Agent activity.

Exit codes

Code Meaning
0 the command is allowed, or the agent's own question is left alone
2 Codex only: the command is denied, and the reason is on standard error

See also