Skip to content

feat: tool filter infrastructure, path scoping, and Gen glTFexport#32

Merged
yiwang merged 5 commits into
localgpt-app:mainfrom
TranscriptionFactory:feat/security-permissions
Feb 17, 2026
Merged

feat: tool filter infrastructure, path scoping, and Gen glTFexport#32
yiwang merged 5 commits into
localgpt-app:mainfrom
TranscriptionFactory:feat/security-permissions

Conversation

@TranscriptionFactory
Copy link
Copy Markdown
Contributor

  • Add tool filter infrastructure (ToolFilter/CompiledToolFilter) to core with deny/allow pattern matching, hardcoded defaults that config can extend but never remove, and merge_hardcoded() deduplication
  • Add path scoping utilities (resolve_real_path, check_path_allowed) with symlink resolution to prevent traversal bypasses
  • Apply hardcoded bash deny filters (sudo, pipe-to-shell, fork bomb, protected files) to CLI tools
  • Enforce security.allowed_directories on all file tools with PathDenied audit logging
  • Add glTF/GLB export tool to Gen mode

Note: xAI provider, Tavily/Perplexity search providers, hybrid native search, and SSRF hardcoded filters were removed from this PR as they already exist on main.

What gets blocked (defaults, no config needed)

Tool Blocked Why
bash sudo ..., curl | sh, rm -rf /, chmod 777 Hardcoded deny patterns
read_file Outside allowed_directories (if configured) Path scoping
write_file Outside allowed_directories (if configured) Path scoping
edit_file Outside allowed_directories (if configured) Path scoping
Symlink bypass ln -s /etc/passwd /tmp/x then read_file /tmp/x resolve_real_path() follows symlinks before checking

Config extension example

[security]
allowed_directories = ["/tmp", "~/projects"]

[tools.filters.bash]
deny_substrings = ["docker rm"]
deny_patterns = ["^npm\\s+publish"]

New files

File Purpose
crates/core/src/agent/tool_filters.rs ToolFilter/CompiledToolFilter — deny/allow pattern engine (278 lines, 11 tests)
crates/core/src/agent/path_utils.rs resolve_real_path, check_path_allowed — symlink-aware path validation (94 lines, 6 tests)
crates/core/src/agent/hardcoded_filters.rs Bash deny substrings/patterns constants (56 lines, 4 tests)

Test plan

  • cargo test --workspace — 152 tests pass (21 new: 11 tool_filters, 6 path_utils, 4 hardcoded_filters)
  • cargo clippy --workspace — no errors
  • cargo build --workspace — clean
  • Manual: set allowed_directories = ["/tmp"], attempt file read outside /tmp → should deny
  • Manual: cargo run -- ask "what is 2+2" smoke test

ToolFilter/CompiledToolFilter for deny/allow pattern matching on tool inputs,
hardcoded deny lists for bash (sudo, pipe-to-shell) and web_fetch (SSRF),
path resolution with symlink handling and directory scoping.

Also adds allowed_directories to SecurityConfig, per-tool filters to
ToolsConfig, and PathDenied audit action.
BashTool now checks commands against compiled deny/allow filters (with
hardcoded sudo, pipe-to-shell defaults) before execution. Strict mode
errors on protected file references instead of warning.

ReadFileTool, WriteFileTool, EditFileTool now resolve symlinks via
resolve_real_path(), enforce allowed_directories scoping, and audit
PathDenied violations. Filter checks run before existing sandbox and
protected-file checks.
WebFetchTool now checks URLs against compiled deny filters before
fetching. Hardcoded patterns block localhost, private IPs (10.x, 172.16-31.x,
192.168.x, 127.x), metadata endpoints, file:// and [::1].

User config under [tools.filters.web_fetch] can extend but never remove
these defaults via merge_hardcoded().
… main

These features already exist on the main branch:
- XaiProvider + grok alias + native search trait methods
- TavilyProvider + PerplexityProvider + SearchUsageStats
- SSRF hardcoded filters (validate_web_fetch_url, is_private_ip)
- Hybrid native search passthrough on Anthropic/xAI providers
- Web search session tracking + status display

Remaining in this branch: tool filter infrastructure, path scoping,
bash deny patterns, allowed_directories, PathDenied audit, Gen glTF export.
- Remove blank line between #[cfg] attr and struct (clippy)
- Run cargo fmt to fix line wrapping in tests (format)
- Add MIT-0 to deny.toml allow list for encase/Bevy deps (license)
@yiwang yiwang merged commit f6c017b into localgpt-app:main Feb 17, 2026
3 of 5 checks passed
yiwang added a commit that referenced this pull request Feb 17, 2026
yiwang added a commit that referenced this pull request Feb 17, 2026
validate_web_fetch_url() already provides strictly superior SSRF
protection via DNS resolution and IP checking. The regex patterns
in hardcoded_filters.rs were a subset of that coverage, added as
duplication during the PR #32 revert.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants