Skip to content

Feat/tool script safety guard 90#167

Open
wzxsdf wants to merge 5 commits into
trpc-group:mainfrom
wzxsdf:feat/tool-script-safety-guard-90
Open

Feat/tool script safety guard 90#167
wzxsdf wants to merge 5 commits into
trpc-group:mainfrom
wzxsdf:feat/tool-script-safety-guard-90

Conversation

@wzxsdf

@wzxsdf wzxsdf commented Jul 12, 2026

Copy link
Copy Markdown

Description | 描述

构建 Tool Script Safety Guard,在 Tool / Skill / CodeExecutor 真正执行脚本前做静态安全扫描,输出 ALLOW / NEEDS_REVIEW / DENY 三级决策,拦截高危脚本并产出可审计事件与 OpenTelemetry 埋点。Decision / RiskLevel 对齐 trpc-agent-go/tool/safety

Closes #90

Change Type | 修改类型

  • New feature | 新功能

Features | 功能

  • 双语言静态扫描 — Python(AST + import-as 别名追踪,import os as x; x.system(...) 也能识别)/ Bash(shlex + 引号状态机),纯静态分析,不执行代码
  • 三态决策 — 规则级判定 + policy 阈值兜底,不确定情况不放行
  • 7 大风险域 / 20 条规则 — 危险文件操作、网络外连、进程命令、依赖安装、资源滥用、敏感信息泄漏、代码执行
  • 两种接入方式ToolSafetyFilter(Tool/Skill 前置拦截)/ SafetyGuardedCodeExecutor(包装任意 CodeExecutor)
  • 策略可配置 — 编辑 tool_safety_policy.yaml 改变白名单域名 / 禁止路径 / 允许命令 / 阈值,无需改代码
  • 可观测 — 每次扫描写一条 JSON Lines 审计记录;启用 OTel 时注入 tool.safety.* span 属性

接入方式

# 方式一:Filter 模式(Tool/Skill 执行前拦截)
from trpc_agent_sdk.tools.safety import ToolSafetyFilter
class MyTool(BaseTool):
    filters_name = ["tool_safety"]

# 方式二:Wrapper 模式(包装 CodeExecutor)
from trpc_agent_sdk.tools.safety import SafetyGuardedCodeExecutor
guarded = SafetyGuardedCodeExecutor(delegate=UnsafeLocalCodeExecutor())

Files Changed | 文件变更

  • trpc_agent_sdk/tools/safety/ — 新包(_types / _rules / _policy / _scanner / _python_scanner / _bash_scanner / _shell_parse / _decision / _safety_filter / _code_executor_guard / _audit
  • trpc_agent_sdk/tools/safety/tool_safety_policy.yaml — 默认策略
  • trpc_agent_sdk/tools/safety/examples/tool_safety_report.json / tool_safety_audit.jsonl 示例
  • scripts/tool_safety_check.py — 独立扫描 CLI
  • scripts/tool_safety_eval.py — 检出率 / 误报率评测
  • tests/tools/safety/ — 11 个测试文件 + 16 条样本
  • docs/mkdocs/zh|en/tool_safety.md — 中英文档

Validation | 验证

  • 73 个 safety 测试全部通过
  • 16 条公开样本全部可扫描并输出结构化报告
  • 检出率 100% / 安全样本误报率 0%(tool_safety_eval.py
  • 读取密钥 / 危险删除 / 非白名单外连 100% 检出
  • 500 行脚本扫描 < 1s
  • 报告含 decision / risk_level / rule_id / evidence / recommendation
  • 策略文件修改后不改代码即可生效
  • Filter / Wrapper 执行前拒绝高危脚本并记录审计事件
  • 文档说明与沙箱 / Filter / Telemetry / CodeExecutor 关系及为何不替代沙箱
  • 纯新增模块,无 breaking change,不影响现有代码

Known Limitations | 已知限制

  • 静态分析固有边界:base64 -d | shgetattr(os,"system")(...)、运行时反射等可绕过
  • Bash 解析为启发式(shlex + 状态机),非完整 POSIX parser
  • Python AST 解析失败时降级为字符串启发式(不阻塞)
  • 资源类规则(超时 / 输出大小)为信息性,实际强制由 executor 运行时执行

以上限制正是本机制不能替代沙箱隔离的原因,需与运行时沙箱互补使用。

wzxsdf added 4 commits July 10, 2026 00:20
)

Static pre-execution scanner for Tool/Skill/CodeExecutor scripts. Mirrors
the Go reference (trpc-agent-go/tool/safety) for rule_id prefixes and
Decision/RiskLevel types, extended to issue trpc-group#90's 6 risk classes.

- Python scanner: ast + import-as alias tracking (prevents rename bypass)
- Bash scanner: shlex + quote-aware state machine
- Conservative 3-state decision (any DENY>deny; else REVIEW>review; else ALLOW)
  with policy risk-threshold fallback
- Two zero-core-change integrations: ToolSafetyFilter (registered tool
  filter) + SafetyGuardedCodeExecutor (delegating wrapper)
- YAML policy (editable without code), structured report, CLI
- 59 tests incl. 12 acceptance manifest samples + performance (500 lines <1s)
- zh/en docs
…kflow

examples/quickstart/.env was tracked at base with a placeholder. Untrack it
(secrets must never be version-controlled) and ignore .env / .spec-workflow.
…c-group#90 gaps

Closes the gaps flagged in the issue trpc-group#90 compliance audit:
- _audit.py: JSON Lines audit record (tool_name, decision, risk_level,
  rule_ids, scan_duration_ms, sanitized, intercepted, timestamp,
  recommendation) + write_audit(); emit_otel() sets tool.safety.* span
  attributes when OTel is active.
- ToolSafetyFilter + SafetyGuardedCodeExecutor now call record_safety_decision
  on every scan (allowed summarized, blocked reasoned + intercepted flag).
- New resource rules tool-res-large-write (huge write / dd / truncate /
  head -c) and tool-res-concurrent-flood (large ThreadPool/ProcessPool);
  python + bash detection; 2 new manifest samples (14 total).
- Example deliverables: examples/tool_safety_report.json (real CLI output),
  examples/tool_safety_audit.jsonl (deny/review/allow records).
- zh/en docs updated (20 rules, telemetry section now describes implemented
  audit + OTel instead of 'reserved').
- Wire tool-fs-system-dir-write (open(...,'w') into system dirs) and
  tool-secret-private-key (embedded PEM literal anywhere in source) in the
  python scanner; these rule ids were previously defined but never fired
- Add `from typing import Optional` to _shell_parse (it was referenced only
  inside a non-evaluated local annotation, but keep it correct/explicit)
- Add manifest samples 15/16 covering the two newly wired rules
- Add scripts/tool_safety_eval.py: detection / false-positive rate eval for
  issue trpc-group#90 acceptance trpc-group#2 (>=90% detection, <=10% FP) -> 100% / 0% on manifest

All 73 safety tests pass.
@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@codecov

codecov Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.74090% with 43 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@099b571). Learn more about missing BASE report.

Files with missing lines Patch % Lines
trpc_agent_sdk/tools/safety/_python_scanner.py 91.42857% 15 Missing ⚠️
trpc_agent_sdk/tools/safety/_audit.py 81.53846% 12 Missing ⚠️
trpc_agent_sdk/tools/safety/_policy.py 94.31818% 5 Missing ⚠️
trpc_agent_sdk/tools/safety/_shell_parse.py 92.30769% 5 Missing ⚠️
trpc_agent_sdk/tools/safety/_safety_filter.py 96.36364% 2 Missing ⚠️
trpc_agent_sdk/tools/safety/_scanner.py 92.30769% 2 Missing ⚠️
...rpc_agent_sdk/tools/safety/_code_executor_guard.py 98.11321% 1 Missing ⚠️
trpc_agent_sdk/tools/safety/_decision.py 96.66667% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main        #167   +/-   ##
==========================================
  Coverage        ?   87.63787%           
==========================================
  Files           ?         479           
  Lines           ?       44790           
  Branches        ?           0           
==========================================
  Hits            ?       39253           
  Misses          ?        5537           
  Partials        ?           0           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wzxsdf

wzxsdf commented Jul 12, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

CI lint job (YAPF + flake8) failed on the safety package. Fixes:
- Remove unused Decision/RiskLevel imports and unused `norm` local
- Reformat the package with yapf (column_limit=120,
  split_before_logical_operator) to match CI style exactly
- Wrap an over-long ValueError message in _policy._decision

flake8 + yapf now clean on all changed trpc_agent_sdk/*.py; 73 tests pass.
Rook1ex added a commit to trpc-group/cla-database that referenced this pull request Jul 12, 2026
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.

构建 Tool 执行脚本安全扫描、Filter 拦截与监控机制

1 participant