Skip to content

PreToolUse hook only matches Bash — Read/Edit/etc. tools bypass validator on Claude Code #28

@rianbk

Description

@rianbk

Summary

The PreToolUse hook installed for Claude Code (./install.sh --agent claude-code) only registers a matcher: "Bash" entry in .claude/settings.json, and the canonical hook input schema is explicitly scoped to shell-execution events (per schemas/hook-input.schema.json: "Currently only 'command' (shell execution) is supported"). For Claude Code, which routes file inspection through non-Bash tools (Read, Edit, MultiEdit, NotebookEdit) by default, this means non-Bash tool calls don't get any config validation at all.

Filing as a feature request to expand validator coverage to non-Bash agent events.

What this affects (and what it doesn't)

The hook's documented value (per its own README) is catching misconfiguration — disabled destinations, missing FIFO files, path mismatches between environments.toml and the desktop app — and surfacing clear "go fix this in destinations tab" errors before execution. The hook is explicit that it "validates and verifies 1Password setup" and uses a "fail open" approach when 1Password is unavailable. It is not a security/secret-protection tool, and this issue isn't claiming it should be one.

The gap: that config-validation value only applies to Bash-mediated tool calls today. If a Claude Code user has a misconfigured mount (toggle off in the 1P app, FIFO missing, etc.) and they ask the agent to inspect .env via the Read tool, no validator runs — the user gets no guidance message. Bash-mediated commands in the same session would correctly surface the misconfiguration.

Reproducer

  1. Set up a 1Password Environment with a local .env mount.
  2. Run ./install.sh --agent claude-code --target-dir <workspace>.
  3. Open a Claude Code session in that workspace.
  4. Prompt: what's in .env.
  5. Claude Code uses its Read tool, opens the FIFO directly. The hook never fires (no entry in /tmp/1password-hooks.log).

Proposed direction (scope expansion, not a small patch)

  1. schemas/hook-input.schema.json: expand event and type enums beyond before_shell_execution / command (e.g., a before_file_read event with a path-typed input).
  2. adapters/claude-code.sh: parse tool_input.file_path for non-Bash file tools alongside tool_input.command for Bash.
  3. hooks/1password-validate-mounted-env-files/hook.sh: accept a file_path field on canonical input; if it doesn't match a known mount, allow; if it does, run the same enabled/exists/FIFO checks the Bash path runs today.
  4. .claude/settings.json template: register additional matchers (e.g., Read|Edit|MultiEdit|NotebookEdit) alongside Bash.

Happy to draft a PR if there's interest.

Related: a separate runtime read-blocker (different scope)

For projects that want to block Read/Edit/etc. tool calls against the FIFO at runtime — separate from config validation — one approach is to ship a companion PreToolUse hook with non-Bash matchers and path-based block logic. Example: rianbk/rianbk-plugins registers a companion script that denies any tool call whose target path is a named-pipe FIFO. Different concern from this issue (runtime read-blocking vs. config-validation coverage), but worth flagging as the practical workaround for users who care about both.

Environment

  • agent-hooks: 22c246013ccf52113c6151708a4140b31aa47a95
  • Claude Code: v2.1.119 (Opus 4.7, 1M context)
  • macOS 14 (Darwin 25.4.0)
  • 1Password Environments (beta)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions