@vigil-guard/vge-cc-guard
v0.9.0-beta.11
Published
Security sidecar for Claude Code — gates tool calls, scans outputs via VGE
Maintainers
Readme
vge-cc-guard
vge-cc-guard is a local security sidecar for Claude Code. It installs Claude
Code hooks, gates tool calls before execution, sends configured prompt and tool
content to Vigil Guard Enterprise (VGE), manages user decisions for blocked
content, and writes a private local audit trail.
Current package version: 0.9.0-beta.11.
Current State
- Runtime is TypeScript on Node.js. The npm package declares
node >=20.10.0. - VGE is the only content detector. The sidecar is the hook broker, local policy engine, state machine, quarantine layer, and audit writer.
PostToolUsesupports VGE block handling, research-safe framing for web research tools, and safe fallback behavior when output scans cannot complete.- Parent
Agentresults receive a structured notice when a child subagent had one or more quarantined tool outputs, so Claude can treat the subagent answer as potentially incomplete without seeing the blocked content.
What It Protects
Claude Code can read files, run commands, fetch URLs, edit code, and spawn
subagents. vge-cc-guard wraps those paths with:
- PreTool gates from local tool policy.
- Hard credential path protection for
Read,Edit,Write, and prompt file attachments. - Local deterministic URL deny-list checks for
BashandWebFetchtargets. - VGE analysis for prompt text, prompt file attachments, and configured tool outputs.
- Session-scoped exact-resource allow/block decisions.
- Owner-aware decisions for parent sessions and subagents.
- Local audit JSONL and authenticated local decision metrics.
The sidecar does not run local prompt-injection heuristics. URL target checks are the local exception: they are deterministic target-control rules, not content detection.
Runtime Model
Claude Code hook
-> vge-cc-guard shim
-> Unix socket or Windows named pipe
-> vge-cc-guard daemon
-> local policy and session state
-> VGE scan when configured
-> allow, frame, quarantine, ask, or block
-> private audit/debug logsThe shim is a small per-hook process invoked by Claude Code. It lazy-starts one
daemon per config directory. PreToolUse fails closed if the daemon cannot be
reached. Non-critical events fail open unless the daemon already returned an
explicit enforcement response.
On macOS and Linux the daemon listens on a Unix socket. On Windows it listens on a named pipe. Private local files are hardened with POSIX modes on macOS/Linux and ACL tightening on Windows.
Hook Coverage
| Hook | Behavior |
|---|---|
| SessionStart | Initializes local session state. |
| UserPromptSubmit | Audits prompt receipt, resolves active control replies, scans prompt text and attachments, and blocks or asks before unsafe input reaches Claude. |
| PreToolUse | Applies credential path protection, URL deny-list rules, session decisions, tainted-session policy, and per-tool gates. |
| PostToolUse | Scans configured tool output, frames risky research content, quarantines blocked output, injects parent-visible subagent quarantine notices, and applies configured scan-failure handling. |
| SessionEnd | Flushes state and clears active in-memory decisions for the session. |
| SubagentStart / SubagentStop | Tracks subagent ownership for owner-scoped decisions and continuation prompts. |
PostTool Output Handling
Configured tool output is scanned before it is trusted by the session. Confirmed blocked output is never silently converted to an allow decision: the guard asks for an operator decision when a resolver is available, or fails closed when it cannot safely continue.
For web research tools, lower-confidence risk can be framed as untrusted research context so Claude can continue the task while treating retrieved content carefully.
Temporary scan failures follow the configured failure mode. The default posture is fail closed. Operators can enable availability-oriented behavior for specific PostTool failure cases, but the guard still keeps the original unverified output out of model context and audit records.
When no decision resolver is active, parent-session blocks still use
conversation HITL by default. Subagent-owned blocks stop cleanly by default
without creating a pending decision the subagent cannot resolve. Operators can
override both owner kinds on the Agent Gating configurator screen (or directly
in policy.posttool_degraded).
Check local health with:
vge-cc-guard doctor
vge-cc-guard daemon status
vge-cc-guard configThe daemon status and TUI report whether safe PostTool output handling is
healthy and provide the next recommended operator action. Unauthenticated
/health does not expose this metadata.
If safe PostTool output handling is degraded, run vge-cc-guard doctor
--cc-contract and follow the reported next action.
Blocking Decisions
Blocking decisions use stable dec_* IDs. Numeric shortcuts are accepted only
when they can be routed unambiguously.
Supported replies:
1
2
3
2 continue the task
3 continue the task
vge allow dec_<id> continue the task
vge allow-session dec_<id> continue the task
vge block dec_<id>
vge allow-visible batch_<id>
vge block-visible batch_<id>| Choice | Meaning |
|---|---|
| 1 / block | Keep the resource out of model context and record an exact-resource block. |
| 2 / allow once | Allow one exact-resource retry. |
| 3 / allow for session | Allow the exact resource until SessionEnd. |
When multiple PostTool decisions are already visible in one rendered batch,
allow-visible and block-visible apply only to that frozen list. They do not
approve future decisions, directories, categories, or "all remaining work."
HITL decisions do not auto-expire while waiting for a human. They are cleared
by a recorded decision, explicit reset, SessionEnd, daemon restart cleanup,
or capacity eviction.
Quick Start
Prerequisites:
- Node.js
>=20.10.0. - A reachable VGE instance.
- A VGE API key.
Install globally:
npm install -g @vigil-guard/vge-cc-guard # latest stable
npm install -g @vigil-guard/vge-cc-guard@beta # current beta
vge-cc-guard install --apply --scope=user
vge-cc-guard configInstall for one project:
cd /path/to/project
vge-cc-guard install --dry-run --scope=project
vge-cc-guard install --apply --scope=project
vge-cc-guard configRestart open Claude Code sessions after installing or changing hook settings.
The installer writes hooks to Claude Code settings and preserves existing
non-vge-cc-guard hooks.
| Scope | Settings file |
|---|---|
| User | ~/.claude/settings.json |
| Project | <project>/.claude/settings.json |
On Windows, user scope resolves under %USERPROFILE%\.claude\settings.json.
Configuration
Open the TUI:
vge-cc-guard configThe main config file is:
~/.vge-cc-guard/config.jsonThe TUI manages:
- VGE API URL, client identity source, and API keys.
- Per-tool
gateandanalyze_output. - Coarse MCP tool gate. MCP output analysis is disabled until VGE supports it.
- IDE compatibility toggles for prompt text, prompt attachments, and subagent output enforcement.
- Per-stage VGE scan failure mode:
fail_closedorfail_open. - Credential path protection.
- URL Access Baseline presets and custom deny rules.
- Read-only effective config export.
Key defaults:
| Area | Default |
|---|---|
| Credential protection | enabled |
| Prompt text analysis | enforce |
| Prompt attachment analysis | enforce |
| Subagent output analysis | enforce |
| VGE failure mode | fail closed for prompt text, attachments, and PostTool output |
| PostTool scan failure handling | fail closed by default |
| PostTool resolver missing | parent session HITL; subagent clean stop |
| URL baseline | enabled; blocks cloud metadata and unsafe URL shapes |
| Client identity | auto-detected OS username, sent as metadata.clientId |
The API Keys screen can set Client identity to Auto, Manual, or Disabled. Auto
detects the logged-in OS username once per daemon process and sends it to VGE as
metadata.clientId. Manual sends the stored vge.client_id. Disabled omits the
field entirely.
VGE Connectivity Verification
The API Keys screen verifies VGE connectivity through the local daemon control path, not from the TUI process directly:
TUI -> local daemon -> VGEThis matches the process that handles hook traffic. The daemon checks the input
key against /v1/guard/input and, when configured, the output key against
/v1/guard/analyze with source: "tool_output". If no output key is set, the
TUI reports that output scans use the input key.
Successful verification stores vge.verified_at plus endpoint and key
fingerprints. Raw API keys are never written to the verification metadata.
Changing the endpoint, input key, or output key makes the previous verification
stale.
vge-cc-guard doctor also prints VGE connectivity status and a next action
when degraded.
Use vge-cc-guard doctor --no-vge for a fast local-state check without a live
VGE round-trip.
Default Tool Policy
| Tool | Gate | Output analysis |
|---|---:|---:|
| Bash | allow | true |
| Read | allow | true |
| Grep | allow | true |
| Glob | allow | false |
| WebSearch | allow | true |
| WebFetch | allow | true |
| Write | block | false |
| Edit | block | false |
| Task | allow | false |
| * | ask | false |
| MCP tools (policy.mcp) | ask | false |
Task.analyze_output remains false by default. Subagent-owned tool output is
covered through owner metadata on the underlying tool hooks when
policy.subagent_output_analysis is enforce.
Tool names starting with mcp__ do not inherit tools["*"]. They use an exact
MCP tool gate override when present, otherwise policy.mcp.gate. MCP output
analysis remains off regardless of wildcard or exact tool analysis settings; an
analyze_output field on an exact MCP tool entry is ignored.
When a subagent output is quarantined, the parent Agent result can include a
[VGE_SUBAGENT_QUARANTINE_NOTICE] block. The notice contains safe metadata such
as session, agent ID, decision ID, tool, resource label, reason code, and
resolution status. It does not include raw blocked tool output, VGE scores,
classifier categories, or branch scores.
Credential And URL Protection
Credential path protection blocks sensitive local paths before content is read or sent to VGE. Examples include:
.envand*.env~/.ssh/*~/.aws/credentialsand~/.aws/config~/.kube/config~/.config/gcloud/*,~/.gcp/*, and Windows gcloud config paths- private key filenames such as
id_rsa*andid_ed25519* - filenames containing
credentialsorsecrets
URL Access Baseline checks are local and deterministic. Public URLs, localhost, loopback, and private LAN targets are allowed by default unless an enabled preset or custom deny rule matches. Cloud metadata endpoints, unsafe schemes, and URLs with embedded credentials are blocked by default.
Uninstall
vge-cc-guard uninstall --yes --scope=user
vge-cc-guard uninstall --yes --scope=project
vge-cc-guard uninstall --yes --project-dir /path/to/projectBy default, uninstall preserves the current Claude Code settings file and
removes only hook entries that invoke vge-cc-guard hook. Use --restore to
replace settings.json with the install-time backup. Global state under
~/.vge-cc-guard/ is removed only after the last install record is gone.
Commands
vge-cc-guard install --apply --scope=user
vge-cc-guard install --apply --scope=project
vge-cc-guard install --dry-run
vge-cc-guard uninstall --yes --scope=user
vge-cc-guard uninstall --yes --scope=project
vge-cc-guard uninstall --yes --scope=user --restore
vge-cc-guard config
vge-cc-guard reset-session
vge-cc-guard daemon
vge-cc-guard daemon status
vge-cc-guard daemon reload
vge-cc-guard daemon stop
vge-cc-guard doctor --cc-contract
vge-cc-guard hook <event>hook is called by Claude Code. Do not run it manually unless testing hook
payload handling.
Audit And Metrics
Audit records are written as private JSONL under:
~/.vge-cc-guard/audit.logAudit records include decision IDs, session IDs, owner metadata, stage, outcome, resolver source, synthesized source, latency, and VGE or local fallback metadata. Raw prompt text, raw tool output, full URLs with query strings, and API keys are not written to audit.
Subagent quarantine visibility adds audit events for ledger writes, notice injection/degradation/skips, ledger recovery, invalid ledger lines, and missing Agent-call correlation. These events are metadata-only and use the same private audit log.
The daemon also exposes an authenticated local metrics snapshot:
POST /v1/control/decision-metricsIDE Notes
Terminal Claude Code supports the full HITL loop. Native IDE panels, including VS Code Claude Code surfaces, may not reliably show prompt text or attachment decision prompts. For guarded prompt/attachment work, use terminal Claude Code.
For IDE-native usage, consider:
IDE Compatibility -> Prompt text -> off
IDE Compatibility -> Prompt file attachments -> offIn off mode, the guard still scans and audits those ingress paths, but it
does not create blocking decisions for them. Credential path protection still
applies.
Troubleshooting
| Symptom | Check |
|---|---|
| vge-cc-guard config prints permission denied after local build | Run pnpm build; local npm link needs dist/cli.js executable on POSIX. |
| Tool is always blocked | Open vge-cc-guard config and review Tools Policy. |
| Credential path is denied | Review policy.credential_protection; it is enabled by default. |
| No VGE events | Check API URL/key in vge-cc-guard config, then ~/.vge-cc-guard/debug.log. PreTool URL baseline decisions are local. |
| Daemon will not start | Run vge-cc-guard daemon in the foreground and check Node.js version. |
| install --apply warns about an older daemon build | A daemon from a prior install is still running. Run vge-cc-guard daemon stop then vge-cc-guard daemon. |
| daemon status shows sidecarEnabled=unknown | Running daemon predates the field. Restart it (daemon stop then daemon). |
| Claude Code GUI cannot find vge-cc-guard | GUI apps may not inherit shell PATH; install with an absolute hook command path. |
| Session state seems stuck | Run vge-cc-guard reset-session. |
| PostTool output handling is degraded | Run vge-cc-guard doctor --cc-contract. |
