In the ancient mythology of computing, Vannevar was Claude's advisor. Part mentor, part overseer, Vannevar guided Claude to move boldly when safe and be cautious when warranted.
In plain English: Use Vannevar to fine-tune which Claude Code actions should be auto-approved and which actions require your approval. Vannevar lets you specify individual bash command patterns and file system scopes to trust. For example, allow commands starting with git commit but not those starting with git reset --hard. A bash parser enables true command enforcement.
The default config provides Claude Code wide latitude to automatically take on-machine actions that read files and machine state and to mutate version-controlled files in the active project, but requires permission for other actions. While this will never be a rigorous approach to security and safety (please use isolated containers and real security for that sort of thing), this provides moderately good safety for casual use cases when running Claude in an environment you'd still like to protect.
Status
The capability works well and is well tested. Install and documentation are not as clean as they should be. Feel free to message me for support if you're interested.
MIT license.
Again, if you'd like help on documentation, feel free to message me for support.
What follows is pretty good as AI slop goes, but that's inherently still what it is. (Okay fine, I wrote some of it. But still.)
Intelligent permission hooks for Claude Code that automatically allow safe operations.
Vannevar is a safety layer for Claude Code that intercepts potentially dangerous operations before they execute. It automatically allows safe operations while requiring explicit approval for risky ones, giving you confidence when working with Claude Code.
Vannevar provides two main hooks:
- Bash Command Validation (
validate-bash) - Analyzes bash commands before execution to automatically allow safe ones - File Operation Validation (
validate-file-read-write-edit) - Controls which files Claude can read, write, or edit
Instead of approving every single bash command or file operation, Vannevar intelligently understands which operations are safe and handles them automatically.
- AST-based parsing: Uses
bashlexto deeply analyze bash commands, including pipes, redirects, and command substitutions - Path safety: Automatically allows commands that only access files within your project directory
- Command patterns: Configurable whitelist of approved command patterns (e.g.,
ls:*,git status:*) - Additional paths: Support for approved paths outside the project (e.g.,
/tmp,/dev/null) - Multi-level configuration: Global settings plus project-specific overrides
What it blocks:
- Commands not in the approved list
- File access outside project directory (unless in approved paths)
- Git metadata tampering (
.git,.gitignore) - Backgrounded processes (
&) - Variable expansion (
$VAR,${VAR}) - Dangerous flags (
-exec,--eval,--command)
What it allows:
- Approved commands within project directory
- Complex command combinations (pipes, redirects, command chaining)
- Commands accessing approved paths like
/tmp
- Project-scoped access: Automatically allows file operations within your project
- Dotfile protection: Requires approval for accessing configuration files
- Additional paths support: Allow access to specific directories outside the project
- Cross-directory support:
allowAllChildPathsflag for working in monorepos
- Python 3.6 or higher
- bashlex library (for bash validation)
pip3 install bashlex- Clone or download Vannevar to
~/.claude/vannevar/:
cd ~/.claude
git clone <your-vannevar-repo> vannevar
# Or copy the vannevar directory to ~/.claude/- Configure Claude Code hooks in
~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "~/.claude/vannevar/validate-bash/run.sh"
}
]
},
{
"matcher": "Read|Write|Edit",
"hooks": [
{
"type": "command",
"command": "~/.claude/vannevar/validate-file-read-write-edit/run.sh"
}
]
}
]
}
}- Verify installation:
# Test bash validation
cd ~/.claude/vannevar/validate-bash
python3 test.py
# Test file validation
cd ~/.claude/vannevar/validate-file-read-write-edit
python3 test.pyGlobal settings are stored in ~/.claude/vannevar/vannevar-settings.json:
{
"bashCommands": [
"ls:*",
"cat:*",
"git status:*",
"npm install:*"
],
"additionalPaths": [
"/tmp",
"/dev/null"
]
}Command Pattern Syntax:
command:*- Command with any arguments (e.g.,ls:*matchesls,ls -la, etc.)command- Command with no arguments onlycommand subcommand:*- Command with specific subcommand (e.g.,npm install:*)
Projects can define additional patterns in .claude/vannevar-settings.local.json:
{
"bashCommands": [
"python:*",
"./run-tests.sh:*"
],
"additionalPaths": [
"/opt/project-data"
],
"allowAllChildPaths": true
}Settings:
bashCommands- Additional approved bash command patterns (merged with global)additionalPaths- Additional approved absolute paths (merged with global)allowAllChildPaths- Whentrue, allows file access anywhere within the project directory tree, even when working from subdirectories. Useful for monorepos and multi-directory projects.
- Claude Code attempts to run a bash command
- Vannevar intercepts the command via PreToolUse hook
- Command is parsed using
bashlexinto an AST - Each command and path is validated against:
- Approved command patterns
- Path restrictions (project directory + approved paths)
- Dangerous patterns (background processes, variable expansion, etc.)
- If all checks pass → command runs automatically
- If any check fails → user is prompted for approval
- Claude Code attempts a file operation (Read/Write/Edit)
- Vannevar intercepts the operation via PreToolUse hook
- File path is validated against:
- Is it within the project directory (or approved additional paths)?
- Is it a dotfile?
- If checks pass → operation runs automatically
- If checks fail → user is prompted for approval
Enable allowAllChildPaths in your project's .claude/vannevar-settings.local.json:
{
"allowAllChildPaths": true
}This allows Claude to navigate between packages and access files anywhere in the project tree.
Add project-specific commands to .claude/vannevar-settings.local.json:
{
"bashCommands": [
"docker-compose:*",
"./scripts/deploy.sh:*",
"pytest:*"
]
}Add system directories to additionalPaths:
{
"additionalPaths": [
"/tmp",
"/opt/myapp/data"
]
}- Accidental file modifications outside your project
- Unintended access to system files
- Background processes that continue running
- Git metadata tampering
- Variable expansion that could reference sensitive paths
- Symlinks: A symlink within the project could point outside
- Malicious binaries: Executables within the project directory are allowed
- Approved command vulnerabilities: Commands in your approved list could be misused
- Explicit user approval: If you approve a dangerous operation, Vannevar won't prevent it
Best Practice: Only use Vannevar in projects you trust, and carefully review bash commands before adding them to your approved patterns.
# Bash validation tests
cd ~/.claude/vannevar/validate-bash
python3 test.py
# File validation tests
cd ~/.claude/vannevar/validate-file-read-write-edit
python3 test.py
# Utility tests
cd ~/.claude/vannevar/util
python3 hook_utils_test.py~/.claude/vannevar/
├── vannevar-settings.json # Global configuration
├── validate-bash/ # Bash command validation hook
│ ├── run.sh # Hook entry point
│ ├── run.py # Main validation logic
│ ├── test.py # Test suite
│ └── README.md # Implementation details
├── validate-file-read-write-edit/ # File operation validation hook
│ ├── run.sh # Hook entry point
│ ├── run.py # Main validation logic
│ ├── test.py # Test suite
│ └── README.md # Implementation details
└── util/ # Shared utilities
├── hook_utils.py # Common hook functions
├── hook_utils_test.py # Utility tests
└── README.md # API documentation