abuis78/skill_Claude_generate_SOAR_playbook

GitHub: abuis78/skill_Claude_generate_SOAR_playbook

一个将自然语言描述转化为 Splunk SOAR 8.5 可运行且 VPE 可编辑 playbook 的 Claude Code Skill,通过逆向工程真实导出 schema 并结合 MCP 实时自测实现端到端闭环生成。

Stars: 0 | Forks: 0

# skill_Claude_generate_SOAR_playbook 一个 **Claude Code skill** (`soar-playbook-builder`),它可以将自然语言描述转化为 **Splunk SOAR On-Prem 8.5** playbook —— 它不仅能**运行**,而且可以在 **Visual Playbook Editor (VPE)** 中保持**可编辑** —— 然后通过 SOAR MCP server **导入并对其进行实时自测**。 本仓库中的每一个 schema 都是**通过对真实的 8.5 版本导出文件进行逆向工程获得的**,并且**已通过真实的 REST import 验证** —— 没有任何猜测成分(参见 [来之不易的经验教训](#hard-won-lessons))。 ## 目录 - [存在的原因](#why-this-exists) - [核心原则:一个计划 → 两个生成器](#core-principle-one-plan--two-emitters) - [架构](#architecture) - [支持的 block 类型](#supported-block-types) - [工作流(阶段 0–4 + 自测)](#the-workflow) - [仓库结构](#repository-layout) - [快速开始](#quick-start) - [声明式计划 schema](#the-declarative-plan-schema) - [测试](#testing) - [已验证的端到端实现](#proven-end-to-end) - [来之不易的经验教训](#hard-won-lessons) - [依赖项(MCP server)](#dependencies-the-mcp-server) - [状态与未来工作](#status--future-work) ## 存在的原因 手动编写 SOAR playbook 非常缓慢,而天真地生成它们往往会失败:一个 VPE 能够编辑的 SOAR playbook **不仅仅**是 Python 代码 —— 它是一个可视化的 **`coa.data`** 图,并且这两者必须保持一致。这个 skill 会一致地生成这两者,通过**实时发现**将每个特定于 connector 的值落地(没有幻觉产生的 app 或 datapath),并通过导入和运行最终结果来形成闭环。 ## 核心原则:一个计划 → 两个生成器 一个 SOAR playbook 导出文件 (`.tgz`) 包含两个必须保持一致的部分: - **`coa.data`** —— VPE 渲染的可视化图:`nodes` (字典) + `edges` (列表)。(顶层的 `blockly` 字段只是一个布尔标志;图结构**并不**在那里。) 参见 [`references/coa-structure.md`](references/coa-structure.md)。 - **`.py`** —— 可执行的真相:每个 block 都是一个 `@phantom.playbook_block()` 函数, 边即为 `callback=` 或直接调用。参见 [`references/py-structure.md`](references/py-structure.md)。 该 skill 构建**一个**抽象的 `playbook_plan.Plan` 并在其上运行**两个生成器**,因此 可运行的逻辑和 VPE 渲染在**构建上**就是一致的 —— 绝不从两个独立的来源编写, 也绝不是凭空想象手写的(coa 的元数据继承自真实的**黄金模板**)。 ## 架构 ``` natural-language request │ (Claude, guided by SKILL.md + references/plan-schema.md) ▼ declarative plan (JSON) │ playbook_plan.plan_from_dict() ← validates structure, lists every problem at once ▼ playbook_plan.Plan ├───────────────────────────────┬───────────────────────────────┐ ▼ ▼ coa_assembly.build_coa_from_plan emit_python.emit → coa.data (visual graph) → .py (executable preview) └───────────────┬───────────────┘ ▼ build_playbook.build() → .json + .py ▼ pack_playbook.pack() → base64(gzip TAR) ← SOAR /rest/import_playbook format ▼ import_playbook (MCP, scm=) → a playbook that renders in the VPE ▼ self-test: create_container → create_artifact → run_playbook → get_playbook_run → assert effect ``` ## 支持的 block 类型 所有类型都基于真实的导出文件,并且**已通过实时 REST import 验证**(括号内为 playbook id): | Block | 作用 | 备注 | |---|---|---| | `start` / `end` | 入口 / 出口 | `on_start` / `on_finish`,无 functionId | | `action` | 运行 connector 操作 | 通过 `phantom.collect2` 获取 datapath 参数;受 asset 作用域限制 | | `decision` | 根据条件分支 | if/elif/else;通过 edge `branch` 扇出(基于 1 的键) | | `format` | 人类可读的文本 | `{0}..{n}` 模板 + datapath `format_params` | | `utility_note` | 原生 "add note" | 写入一个 container note | | `set_severity` (549/554) | 原生 "set severity" | `choices:"notableSeverity"` (一个 **字符串**),`refreshNotableData` | | `filter` (550) | 仅转发匹配的 artifacts | `phantom.condition`;基于 0 的条件键 | | `playbook` (551) | 调用子 playbook | `playbookName/Repo/Type/synchronous/inputs` | | `prompt` (553) | 人工干预审批 | `phantom.prompt2`;**线性** → 下游的 `decision` 读取 `…responses.0` | ## 工作流 由 Claude 遵循 [`SKILL.md`](SKILL.md) 执行: - **阶段 0 — 学习 (LEARN)**:一个黄金模板 (`samples/`) 提供真实的 `coa` 封装 (version/schema/python_version),并为 node/`.py` schema 提供基础。 - **阶段 1 — 发现 (DISCOVERY)** *(反幻觉)*:`list_apps` + `list_assets` + `get_action_schema` 解析真实的 app/asset 和确切的输出 datapath(例如,恶意计数路径)。如果缺少必需的 connector,则停止 —— 不要替换为其他供应商。 - **阶段 2 — 计划 (PLAN)**:将意图转化为一个声明式计划 JSON(参见 [计划 schema](#the-declarative-plan-schema));`plan_from_dict()` 会对它进行验证。 - **阶段 3 — 生成 (EMIT)**:`build_playbook.build()` 运行两个生成器并打包存档文件。 - **阶段 4 — 验证与导入 (VERIFY & IMPORT)**:先在本地运行 `coa_assembly.validate()` + `compile()`,然后执行 `import_playbook(scm=)`。使用 `get_playbook_coa_summary` 进行确认 (`passed_validation=True`,预期的 node/edge 数量)。 - **自测**:`create_container(label="events")` → `create_artifact` → `run_playbook` → `get_playbook_run` (轮询直到 `success`) → 断言效果(例如 `get_case` 的 severity,或是一个 note)。 ## 仓库结构 | 路径 | 用途 | |---|---| | [`SKILL.md`](SKILL.md) | Skill 定义 + 完整的阶段 0–4 / 自测工作流 | | `scripts/playbook_plan.py` | `Plan`/`Block` 模型 + `plan_from_dict()` (声明式 → 已验证的 Plan) | | `scripts/coa_assembly.py` | `build_coa_from_plan` + 基于类型的 node 构建器 (基于真实导出) | | `scripts/emit_python.py` | Plan → 可执行的 `.py` 预览 | | `scripts/build_playbook.py` | Plan → `{.py, .json}` (+ 打包) | | `scripts/pack_playbook.py` | 确定性 `base64(gzip TAR)` 编解码器 (SOAR import 格式) | | `scripts/test_*.py` | 离线测试套件 (47 个测试,不需要实时 SOAR) | | `references/coa-structure.md` | 已验证的 `coa.data` node/edge schema | | `references/py-structure.md` | 已验证的 `.py` block/function 模式 | | `references/plan-schema.md` | 声明式计划 schema + 实战示例 | | `samples/*.tgz` | 黄金模板导出 (结构真值)。`golden_full` 已脱敏 | | `docs/SOAR-MCP-Playbook-Tools-Instruction.md` | 该 skill 调用的 MCP-server 工具规范 | | `examples/` | 已生成的 playbook 存档 | | `SKILL-EXTENSION-NEEDS.md` | 哪些 MCP-server 能力解锁哪些 skill 功能 | ## 快速开始 **作为 Claude Code skill 使用** —— 连接 SOAR MCP server 后,只需询问: Claude 会运行整个工作流(发现 → 生成 → 导入 → 运行 → 断言)并报告结果。 **直接驱动生成器**(离线,无需 SOAR): ``` import sys; sys.path.insert(0, "scripts") from playbook_plan import plan_from_dict from build_playbook import build spec = { ... } # see references/plan-schema.md plan = plan_from_dict(spec) # validates; raises with every problem listed res = build(plan, "samples", "out", pack_archive=True) print(res["archive_b64"]) # base64(gzip TAR) → feed to import_playbook(scm=) ``` ## 声明式计划 schema 完整参考及示例:[`references/plan-schema.md`](references/plan-schema.md)。基本结构如下: ``` { "name": "URL_Reputation_SetSeverity", "playbook_type": "automation", "blocks": [ {"key": "on_start", "type": "start"}, {"key": "url_reputation_1", "type": "action", "action": "url reputation", "connector": "VirusTotal v3", "asset": "virustotal", "parameters": {"url": "artifact:*.cef.requestURL"}, "datapath_params": true}, {"key": "decision_1", "type": "decision", "conditions": [ {"kind": "if", "comparisons": [ {"param": "url_reputation_1:action_result.data.*.attributes.last_analysis_stats.malicious", "op": ">", "value": 0}]}]}, {"key": "set_severity_1", "type": "set_severity", "severity": "high"}, {"key": "on_finish", "type": "end"} ], "edges": [ {"src": "on_start", "dst": "url_reputation_1"}, {"src": "url_reputation_1", "dst": "decision_1"}, {"src": "decision_1", "dst": "set_severity_1", "branch": 0}, {"src": "decision_1", "dst": "on_finish", "branch": "else"}, {"src": "set_severity_1", "dst": "on_finish"} ] } ``` `plan_from_dict()` 会一次性报告**所有**结构问题(未知的 block 类型、悬空的 edge、 缺少必需字段、非线性的 `prompt`,等等),以便作者可以在一轮内完成自我修正。 ## 测试 ``` cd scripts python3 -m unittest discover -p 'test_*.py' # 47 tests, all offline ``` 测试会构建/验证 `coa.data`,对生成的 `.py` 执行 `compile()`,并对打包编解码器进行往返测试 —— 不需要 SOAR 实例。实时 REST-import 验证是单独针对一个 8.5 实例进行的。 ## 已验证的端到端实现 在实时 SOAR **8.5.0.248** 上,通过单个自然语言 (NL) prompt 实现的**自动化运行**: 1. **发现**解析了 VirusTotal v3 (app 334)、asset `virustotal`,以及真实的恶意 datapath `…attributes.last_analysis_stats.malicious`。 2. **生成** → coa 有效,`.py` 编译通过。 3. **导入** → playbook **554** (`scm=4`),`passed_validation=True`。 4. **自测** → 测试 container (severity 为 `low`) + URL artifact → `run_playbook` → 运行 `success` (VirusTotal 返回 **Malicious: 10**) → `get_case` → **Severity = high** ✅。 每种 block 类型都单独进行了 REST-import 验证:set_severity、filter (550)、子 playbook (551)、prompt (553)。 ## 来之不易的经验教训 这些经验已融入代码和 `SKILL.md` 中,以免再次发生: - **UI 导入很宽松;REST 导入很严格。** 一个 block schema 可能通过了 SOAR UI 导入,但 在 `/rest/import_playbook` 上仍然会报 `400` 错误。始终通过真实的 MCP 导入进行验证,而不是依赖 UI。(当初猜测的 `set_severity` schema 就是这样被发现的。) - **`scm:"local"` 会解析为只读的 `community` repo → 导致 403。** 应传入一个明确的**可写** repo id(例如 `4`;通过 `GET /rest/scm` 发现有效的 id)。 - **`set_severity`** 的 `choices` 字段是**字符串** `"notableSeverity"` (一个具名选项集合),而 不是列表,并且 `advanced` 和 utility 都带有 `refreshNotableData: true`。 - **functionName 规则:** `code` block 必须是 `code_`;类型化 block 必须是 `_` (后缀 == functionId);每个类型化 node 都需要一个 `functionId`。 - **Notes / set-severity 是原生的 `utility` block**,而不是代码块。 - **`prompt` 是线性的** —— 它从不进行分支;下游的 `decision` 读取 `:action_result.summary.responses.0`。 - **绝不要在 macOS 上使用 `tar czf`** —— 它会注入 AppleDouble `._*` 成员,破坏 SOAR 的 UTF-8 读取; 始终通过 `pack_playbook` (Python `tarfile`) 打包。 - **发现,而不是猜测:** 恶意的 datapath 因 connector 而异 (VirusTotal v3 使用 `…last_analysis_stats.malicious`,而不是 `…summary.malicious`) —— 通过 `get_action_schema` 解析它。 ## 依赖项(MCP server) 发现/导入/自测使用扩展版的 [`abuis78/soar_mcp_server`](https://github.com/abuis78/soar_mcp_server) 中的工具:`list_apps`、`list_assets`、 `get_action_schema`、`export_playbook`、`import_playbook`、`create_container`,以及分析师工具 `create_artifact`、`run_playbook`、`get_playbook_run`、`get_case`。写工具是受限的 (默认禁用;`create_container` 还需要 `enable_test_harness`)。规范: [`docs/SOAR-MCP-Playbook-Tools-Instruction.md`](docs/SOAR-MCP-Playbook-Tools-Instruction.md)。 ## 状态与未来工作 - ✅ 所有 block 类型均已构建,完成了离线测试 (47 个测试),并进行了实时 REST 验证。 - ✅ 完整的自动化闭环已验证 (NL → 发现 → 构建 → 导入 → 运行 → 断言)。 - 未来:通过发现机制从名称解析子 playbook 的 `repo_id`;扩展调色板 (task/pin/api 实用程序);更丰富的 prompt 响应类型 (目前仅验证了 `yes/no`)。参见 [`SKILL-EXTENSION-NEEDS.md`](SKILL-EXTENSION-NEEDS.md)。 *使用 [Claude Codehttps://claude.com/claude-code) 构建。配套的 MCP server: [abuis78/soar_mcp_server](https://github.com/abuis78/soar_mcp_server)。*
标签:AI辅助编程, Claude, CVE检测, SOAR, 安全运营, 扫描框架, 自动化剧本, 逆向工具