Where does the bug appear (feature/product)?
Cursor IDE
Describe the Bug
I am currently experimenting with Cursor hooks to enforce a strict security rule:
the agent should never read files outside of the current workspace root.
My intention was to implement this as a hard guardrail via hooks. As a first step, I created a minimal test that simply returns {"decision":"deny"} for every read attempt.
However, the read operation still proceeds, even though the hook clearly executes and returns deny.
This surprised me quite a bit, because it suggests that hook decisions might not actually be enforced.
Hook log output (excerpt)
The logs clearly show that:
- the hook is executed
- the response is parsed successfully
- the decision returned is deny
Example:
Hook step requested: preToolUse
Found 1 hook(s) to execute for step: preToolUse
Executing hook 1/1 from project config
INPUT:
{
"tool_name": "Read",
"tool_input": {
"file_path": "/projects/another-project/pom.xml"
},
"workspace_roots": [
"/projects/my-project"
]
}
OUTPUT:
{
"decision": "deny"
}
Hook 1 executed successfully and returned valid response
Merged 1 valid response(s) for step preToolUse
The same happens for beforeReadFile, which also returns:
{
"decision": "deny"
}
Despite this, the read still proceeds.
Why this seems problematic
My expectation was that hooks could be used to enforce hard restrictions, especially for security-related policies like preventing access outside the workspace.
If a deny decision is ignored even in such a minimal setup, it raises some concerns about whether hooks can actually be relied upon to enforce security boundaries.
This matters in practice because:
- LLM agents can be misled or manipulated via prompts
- accidental tool usage can happen
- organizations may want to enforce strict access policies
In such environments, hooks appear to be the natural mechanism for enforcing guardrails.
Questions
- Is this the expected behavior?
- Are hook decisions currently advisory rather than enforced?
- Is there any reliable way to prevent the agent from reading files outside the workspace?
Steps to Reproduce
.cursor/hooks/block-external-reads.sh
echo '{"decision":"deny"}'
.cursor/hooks/hooks.json
{
"version": 1,
"hooks": {
"beforeReadFile": [
{
"command": "bash .cursor/hooks/block-external-reads.sh"
}
],
"preToolUse": [
{
"matcher": "Read",
"command": "bash .cursor/hooks/block-external-reads.sh"
}
]
}
}
Prompt something like
read "../another-project/pom.xml". Name the projects current version.
Expected Behavior
Access should be prevented
Operating System
MacOS
Version Information
Version: 2.6.18
VSCode Version: 1.105.1
Commit: 68fbec5aed9da587d1c6a64172792f505bafa250
Date: 2026-03-10T02:01:17.430Z
Build Type: Stable
Release Track: Default
Electron: 39.6.0
Chromium: 142.0.7444.265
Node.js: 22.22.0
V8: 14.2.231.22-electron.0
OS: Darwin arm64 25.3.0
Does this stop you from using Cursor
Yes - Cursor is unusable