name: 代理治理技能 description: 为自定义代理实现权限控制和安全的钩子。在添加安全控制、拦截危险操作、实施审计跟踪或设计权限治理时使用。 allowed-tools: Read, Grep, Glob
代理治理技能
使用钩子为自定义代理实现安全和治理控制。
目的
设计和实现基于钩子的治理,控制代理权限、拦截危险操作并提供审计跟踪。
何时使用
- 构建具有安全要求的代理
- 需要阻止对敏感文件/操作的访问
- 要求审计记录代理操作
- 实施权限策略
钩子架构
钩子类型
文档验证: 钩子事件类型(PreToolUse、PostToolUse等)是Claude Code内部类型。有关权威的当前类型,请通过
hook-management技能→docs-management验证。
| 钩子 | 何时 | 用例 |
|---|---|---|
PreToolUse |
工具执行前 | 拦截、验证、记录 |
PostToolUse |
工具执行后 | 记录结果、审计 |
钩子函数签名
async def hook_function(
input_data: dict, # 工具调用信息
tool_use_id: str, # 唯一工具调用ID
context: HookContext # 会话上下文
) -> dict:
# 返回空字典以允许
# 返回带有permissionDecision以拦截
pass
设计过程
步骤1:识别安全要求
需要回答的问题:
- 应阻止哪些文件?(例如:.env、凭证)
- 应阻止哪些命令?(例如:rm -rf)
- 哪些操作需要记录?
- 哪些工具访问需要验证?
步骤2:设计钩子匹配器
from claude_agent_sdk import HookMatcher
hooks = {
"PreToolUse": [
# 匹配特定工具
HookMatcher(matcher="Read", hooks=[block_sensitive_files]),
# 匹配所有工具
HookMatcher(hooks=[log_all_tool_usage]),
],
"PostToolUse": [
HookMatcher(hooks=[audit_tool_results]),
],
}
步骤3:实现钩子函数
安全钩子(拦截模式):
BLOCKED_PATTERNS = [".env", "credentials", "secrets", ".pem", ".key"]
async def block_sensitive_files(
input_data: dict,
tool_use_id: str,
context: HookContext
) -> dict:
tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
# 仅检查文件操作
if tool_name not in ["Read", "Write", "Edit"]:
return {}
file_path = tool_input.get("file_path", "")
# 检查拦截模式
for pattern in BLOCKED_PATTERNS:
if pattern in file_path.lower():
return {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": f"安全:访问{pattern}文件被拦截",
}
}
return {} # 允许
审计钩子(记录模式):
async def log_all_tool_usage(
input_data: dict,
tool_use_id: str,
context: HookContext
) -> dict:
tool_name = input_data.get("tool_name", "")
tool_input = input_data.get("tool_input", {})
session_id = input_data.get("session_id", "unknown")
log_entry = {
"timestamp": datetime.now().isoformat(),
"session_id": session_id,
"tool": tool_name,
"input": tool_input,
}
# 写入审计日志
log_file = Path("audit_logs") / f"{session_id}.jsonl"
log_file.parent.mkdir(exist_ok=True)
with open(log_file, "a") as f:
f.write(json.dumps(log_entry) + "
")
return {} # 始终允许(仅记录)
验证钩子(条件模式):
async def validate_bash_commands(
input_data: dict,
tool_use_id: str,
context: HookContext
) -> dict:
tool_name = input_data.get("tool_name", "")
if tool_name != "Bash":
return {}
command = input_data.get("tool_input", {}).get("command", "")
DANGEROUS_PATTERNS = [
r"rm\s+-rf\s+/",
r"sudo\s+rm",
r":(){ :|:& };:", # 分叉炸弹
]
for pattern in DANGEROUS_PATTERNS:
if re.search(pattern, command):
return {
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": f"安全:危险命令被拦截",
}
}
return {}
步骤4:用钩子配置代理
hooks = {
"PreToolUse": [
HookMatcher(matcher="Read", hooks=[block_sensitive_files]),
HookMatcher(matcher="Bash", hooks=[validate_bash_commands]),
HookMatcher(hooks=[log_all_tool_usage]),
],
"PostToolUse": [
HookMatcher(hooks=[audit_tool_results]),
],
}
options = ClaudeAgentOptions(
system_prompt=system_prompt,
model="opus",
hooks=hooks,
)
常见治理模式
文件访问控制
ALLOWED_DIRECTORIES = ["src/", "docs/", "tests/"]
async def restrict_file_access(input_data, tool_use_id, context) -> dict:
file_path = input_data.get("tool_input", {}).get("file_path", "")
if not any(file_path.startswith(d) for d in ALLOWED_DIRECTORIES):
return deny_response("访问限制到允许的目录")
return {}
速率限制
tool_call_counts = defaultdict(int)
RATE_LIMITS = {"WebFetch": 10, "Bash": 50}
async def rate_limit_tools(input_data, tool_use_id, context) -> dict:
tool_name = input_data.get("tool_name", "")
if tool_name in RATE_LIMITS:
tool_call_counts[tool_name] += 1
if tool_call_counts[tool_name] > RATE_LIMITS[tool_name]:
return deny_response(f"{tool_name}的速率限制已超出")
return {}
内容过滤
BLOCKED_CONTENT = ["api_key", "password", "secret"]
async def filter_output_content(input_data, tool_use_id, context) -> dict:
tool_output = input_data.get("tool_output", "")
for blocked in BLOCKED_CONTENT:
if blocked.lower() in tool_output.lower():
return deny_response("输出包含敏感内容")
return {}
输出格式
设计治理时:
## 治理设计
**代理:** [代理名称]
**安全级别:** [低/中/高]
### 要求
- [ ] 要求1
- [ ] 要求2
### 钩子
**PreToolUse:**
| 匹配器 | 钩子 | 目的 |
| --- | --- | --- |
| Read | block_sensitive_files | 拦截.env、凭证文件 |
| Bash | validate_commands | 拦截危险命令 |
| * | log_usage | 审计所有工具调用 |
**PostToolUse:**
| 匹配器 | 钩子 | 目的 |
| --- | --- | --- |
| * | audit_results | 记录工具输出 |
### 实现
[钩子函数实现]
### 测试场景
| 场景 | 预期 | 实际 |
| --- | --- | --- |
| 读取.env文件 | 拦截 | |
| 读取src/main.py | 允许 | |
| rm -rf / | 拦截 | |
设计检查清单
- [ ] 安全要求已识别
- [ ] 文件访问控制已定义
- [ ] 命令验证规则已定义
- [ ] 审计日志记录已实现
- [ ] 钩子匹配器已配置
- [ ] 测试场景已记录
- [ ] 错误消息有帮助
关键见解
“钩子使自定义代理能够实现治理和权限检查。”
钩子适用于主代理和通过Task工具生成的子代理。
交叉引用
- @custom-agent-design技能 - 代理设计工作流
- @core-four-custom.md - 核心四中的治理
- @hook-management技能 - 钩子管理模式
版本历史
- v1.0.0 (2025-12-26):初始发布
最后更新
日期: 2025-12-26 模型: claude-opus-4-5-20251101