代理治理技能Skill agent-governance

该技能用于通过钩子架构实现自定义代理的安全和治理控制,包括权限控制、危险操作拦截、审计日志记录等,适用于构建需要安全要求的代理。关键词:代理安全、钩子编程、权限治理、审计跟踪、安全控制、AI智能体、自定义代理开发。

AI智能体 0 次安装 0 次浏览 更新于 3/11/2026

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