HustleOps/hustleops-n8n-plugin
GitHub: HustleOps/hustleops-n8n-plugin
为 HustleOps 事件响应平台提供 n8n 社区节点,支持告警、事件、可观测对象等核心资源的全生命周期操作与自动化工作流集成。
Stars: 0 | Forks: 0
# HustleOps n8n 社区节点
此包为 HustleOps 事件响应工作流提供了一个 n8n 社区节点。
当前包支持针对核心告警、事件、可观测对象、知识、评论、标签和自定义字段操作的实时 HustleOps API 请求。
## 支持的资源和操作
| 资源 | 操作 |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Alert | Search, Count, Get, Create, Update, Set Tags, Add Tags, Remove Tag |
| Incident | Search, Count, Get, Create, Update, Set Tags, Add Tags, Remove Tag |
| Observable | Search, Count, Get, Create, Update, Set Tags, Add Tags, Remove Tag |
| Knowledge | Search, Count, Get, Create, Update, Set Tags, Add Tags, Remove Tag |
| Comment | List, Search, Get Unread Count, Create, Mark Read, Update, Delete, Toggle Reaction, Toggle Pin |
| Tag | List, Search, Create, Update Color, Bulk Update Color, Delete, Bulk Delete |
| Custom Field | List Groups, Create Group, Update Group, Delete Group, List Definitions, Search Definitions, Create Definition, Update Definition, Bulk Update Definitions, Delete Definition, Bulk Delete Definitions, Get Values, Get Available, Batch Get Values, Replace Values, Update Selected Values Safely |
Payload 操作提供了一个 **Input Mode**(输入模式)选择器。
- **Individual Fields**(独立字段)是默认模式。节点会根据可见字段构建请求体,并在读取凭证或调用 HustleOps 之前对请求体进行验证。
- **JSON Object**(JSON 对象)会将 JSON 对象作为完整的请求体提交。JSON Object 模式是完全替换:隐藏在 Individual Fields 控件中的值将被忽略。
结构化枚举字段会渲染为下拉菜单。由列表选项支撑的字段(如告警类型/状态、事件状态/类别、可观测对象类型/威胁级别/严重性以及知识类型)会从 HustleOps `/picklists/:domain` endpoint 加载其下拉选项,并在创建或更新的 payload 中发送所选的 API 值。
仅将 `Additional JSON`(附加 JSON)用于高级受支持字段或有意覆盖。`Additional JSON` 会在结构化字段之后合并,因此 `Additional JSON` 中的重复键具有更高优先级。不受支持的字段在发送 API 请求之前仍会导致失败。
核心搜索路径为 `/alerts/search`、`/incidents/search`、`/observables/search` 和 `/knowledge/search`。启用 `Return All` 以持续获取分页,直到 API 响应达到 `totalPages`、`Max Items` 或 `Max Pages`。
必填的创建字段在 Individual Fields 模式下会显示为常规的 n8n 字段。可选的创建字段位于 `Additional Fields` 下,而更新的 payload 字段位于 `Fields to Update` 下。不受支持的字段在发送 API 请求之前仍会导致失败。
## 标签操作
核心资源直接在 Alert、Incident、Observable 和 Knowledge 下提供了 `Set Tags`、`Add Tags` 和 `Remove Tag` 操作。
- `Set Tags`:调用 `PUT //:id/tags` 并传入 `{ "values": [...] }`。空数组会清除所有标签。
- `Add Tags`:调用 `POST //:id/tags` 且至少需要一个值。
- `Remove Tag`:调用 `DELETE //:id/tags/:tagId`。
标签值在发送 API 请求之前会进行验证:每个实体最多 20 个标签,每个标签最多 30 个字符,并且仅允许字母、数字、空格以及 `* ! @ # $ : . - _ =`。
`Tag` 资源涵盖管理员标签管理:
- `List`:调用 `GET /tags`,可选择传入 `withCounts=true` 以获取仅供管理员查看的计数。
- `Search`:调用 `POST /tags/search` 并传入 SearchRequest 请求体。
- `Create`:调用 `POST /tags` 并传入 `{ "value": "vip", "color": "#0EA5E9" }`。
- `Update Color`:调用 `PATCH /tags/:id` 并传入 `{ "color": "#A855F7" }`。标签值是不可变的。
- `Bulk Update Color`:调用 `PATCH /tags/bulk` 并传入 `{ "ids": [...], "color": "#22C55E" }`。
- `Delete`:启用 Force 时调用 `DELETE /tags/:id?force=true`。
- `Bulk Delete`:调用 `POST /tags/bulk-delete` 并传入 `{ "ids": [...], "force": true }`。
标签 payload 操作支持 **Input Mode**。在 **Individual Fields** 模式下,使用 `Tag Value`、`Tag Color`、`Tag IDs` 和 `Force` 等字段。在 **JSON Object** 模式下,提交完整的标签 payload,例如:
```
{
"ids": ["11111111-1111-4111-8111-111111111111"],
"force": true
}
```
## 自定义字段操作
`Custom Field` 资源涵盖自定义字段组、定义和值。
组操作调用 `/custom-fields/groups`。定义操作调用 `/custom-fields/definitions`、`/custom-fields/definitions/search`、`/custom-fields/definitions/bulk` 和 `/custom-fields/definitions/bulk-delete`。定义更新会拒绝 `fieldType`,因为字段类型是不可变的。
值操作使用大写的实体类型:`ALERT`、`INCIDENT`、`OBSERVABLE` 和 `KNOWLEDGE`。
- `Get Values`:调用 `GET /custom-fields/values/:entityType/:entityId`。
- `Get Available`:调用 `GET /custom-fields/available/:entityType/:entityId`。
- `Batch Get Values`:调用 `POST /custom-fields/values/batch` 并传入 `{ "entityType": "ALERT", "entityIds": [...] }`,最多允许 100 个 ID。
- `Replace Values`:调用 `PATCH /custom-fields/values/:entityType/:entityId` 并传入需要保留的精确附加字段集。
- `Update Selected Values Safely`:首先读取现有值,合并所选字段的更改,然后对完整的附加字段集进行 patch 操作,从而保留被省略的附加字段。
自定义字段写入操作支持 **Input Mode**。在 **Individual Fields** 模式下,针对所选操作使用可见的组、定义、定义 ID、实体 ID 列表或附加字段行控件。在 **JSON Object** 模式下,提交完整的 payload,例如:
```
{
"entityType": "INCIDENT",
"entityIds": ["22222222-2222-4222-8222-222222222222"]
}
```
发送到 API 的自定义字段值必须是字符串或 `null`。`MULTI_SELECT` 数组输入会通过 `JSON.stringify` 进行序列化,因此 `["a", "b"]` 将作为 `"[\"a\",\"b\"]"` 发送。BOOLEAN 值必须为 `"true"` 或 `"false"`;NUMBER、DATE 和 URL 值在发送前会进行验证。
## 获取 API 密钥
API 密钥必须由 HustleOps 管理员或拥有 API 密钥管理权限的其他用户在 n8n 外部创建。
n8n 节点不会创建、轮换或撤销 HustleOps API 密钥。
API 密钥所有者需要具有所执行操作所需的 HustleOps 权限,例如 Search/Get 的查看权限以及写入操作的创建或更新权限。
## 身份验证
在 n8n 中创建 `HustleOps API` 凭证,包含以下内容:
- `Base URL`:您的 HustleOps 实例的完整 HTTPS URL。仅在 `localhost`、`127.0.0.1` 或 `::1` 上进行本地开发时使用 HTTP。
- `API Key`:您的 HustleOps API 密钥。
- `Ignore SSL Issues`:默认禁用。仅在使用自签名证书的本地或私有测试实例上启用。对于生产环境,请安装受信任的证书或将颁发 CA 添加到 n8n/Node 信任库中。
请求发送:
```
x-api-key: ho_sk_...
Accept: application/json
Content-Type: application/json
```
API 密钥代表拥有该密钥的用户进行操作,因此角色和权限检查仍然适用。
## 创建示例
当 **Input Mode** 设置为 **Individual Fields** 时,通过节点字段设置这些值。下方的 JSON 展示了由结构化字段生成的 API payload。
告警字段值:
| n8n 字段 | 值 |
| ------------- | -------------------------- |
| `Name` | `Suspicious login` |
| `Description` | `Okta anomaly` |
| `Severity` | `HIGH` |
| `TLP` | `AMBER` |
| `Source` | `okta` |
| `Type` | `identity` |
| `Source Ref` | `evt_12345` |
| `Detected At` | `2026-06-28T12:00:00.000Z` |
```
{
"name": "Suspicious login",
"description": "Okta anomaly",
"severity": "HIGH",
"tlp": "AMBER",
"source": "okta",
"type": "identity",
"sourceRef": "evt_12345",
"detectedAt": "2026-06-28T12:00:00.000Z"
}
```
事件字段值:
| n8n 字段 | 值 |
| ------------- | --------------------------------------------------- |
| `Name` | `Credential theft investigation` |
| `Description` | `Coordinated response for suspicious Okta activity` |
| `Severity` | `HIGH` |
| `TLP` | `AMBER` |
| `Category` | `identity` |
```
{
"name": "Credential theft investigation",
"description": "Coordinated response for suspicious Okta activity",
"severity": "HIGH",
"tlp": "AMBER",
"category": "identity"
}
```
可观测对象字段值:
| n8n 字段 | 值 |
| -------------- | -------------------------- |
| `Value` | `198.51.100.10` |
| `Type` | `ip` |
| `Threat Level` | `SUSPICIOUS` |
| `TLP` | `AMBER` |
| `First Seen` | `2026-06-28T11:30:00.000Z` |
| `Last Seen` | `2026-06-28T12:00:00.000Z` |
```
{
"value": "198.51.100.10",
"type": "ip",
"threatLevel": "SUSPICIOUS",
"tlp": "AMBER",
"firstSeen": "2026-06-28T11:30:00.000Z",
"lastSeen": "2026-06-28T12:00:00.000Z"
}
```
知识字段值:
| n8n 字段 | 值 |
| ------------- | ------------------------------------------- |
| `Value` | `Containment runbook` |
| `Type` | `runbook` |
| `TLP` | `AMBER` |
| `Description` | `Steps for disabling compromised accounts` |
```
{
"value": "Containment runbook",
"type": "runbook",
"tlp": "AMBER",
"description": "Steps for disabling compromised accounts"
}
```
## 更新字段
更新操作将 `ID` 保留为必填字段,并在 **Individual Fields** 模式下将可编辑的 payload 值放在 `Fields to Update` 下。
例如,更新 Observable 时可以在 `Fields to Update` 下设置 `Threat Level`、`Criticality` 和 `Version`。
要提交完整的更新主体或清除受支持的可为空字段,请使用 **JSON Object** 模式,例如 `{ "summary": null }`。空白的 Individual Fields 更新值将被忽略。
## 搜索分页
默认情况下,Search 会为 API 响应 `data` 数组中的每一行返回一个输出项。
启用 `Include Pagination Metadata` 可返回包含 `data`、`total`、`page`、`pageSize` 和 `totalPages` 的原始分页对象。
启用 `Return All` 以获取多个页面。`Max Items` 和 `Max Pages` 会限制请求,因此大型结果集不会无休止地运行。
## 评论操作
评论操作针对附加到核心实体的评论线程进行。选择 `Comment` 作为资源,然后选择以下操作之一:
- `List`:调用 `GET /comments`,并传入 `entityType`、`entityId`、可选的 `cursor` 和 `take`。
- `Search`:调用 `GET /comments/search`,并传入 `entityType`、`entityId` 和 `q`。
- `Get Unread Count`:调用 `GET /comments/unread-count` 并返回 `{ "unreadCount": number }`。
- `Create`:调用 `POST /comments`,并传入 content、parent ID、attachment IDs 或完整的 JSON Object payload。
- `Mark Read`:调用 `POST /comments/read`,并传入 `entityType` 和 `entityId`。
- `Update`:调用 `PATCH /comments/:id`,并传入 `{ "content": "Updated containment note" }`。
- `Delete`:调用 `DELETE /comments/:id`。
- `Toggle Reaction`:调用 `POST /comments/:id/reactions`,并传入 `{ "emoji": "\u2705" }`。
- `Toggle Pin`:调用 `PATCH /comments/:id/pin`。
评论的 `entityType` 必须是 `ALERT`、`INCIDENT`、`OBSERVABLE` 或 `KNOWLEDGE` 之一。
List 使用游标分页。`Take` 默认为 `50`,且必须介于 `1` 和 `100` 之间。启用 `Include Cursor Metadata` 将返回包含 `items` 和 `nextCursor` 的原始响应,而不是为每条评论返回一个输出项。
Search 为每条评论输出一个项,并使用 `Max Results` 限制输出的行数(默认为 `100`)。
### n8n 字段和输出
| 操作 | 必填的 n8n段 | 可选的 n8n 字段 | 输出 |
| ---------------- | ------------------------------------------ | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| List | `Entity Type`, `Entity ID` | `Take`, `Cursor`, `Include Cursor Metadata` | 每条评论一个项,或在启用游标元数据时返回包含 `items` 和 `nextCursor` 的原始响应项 |
| Search | `Entity Type`, `Entity ID`, `Search Query` | `Max Results` | 每个匹配的评论一个项,最多达到 `Max Results` |
| Get Unread Count | `Entity Type`, `Entity ID` | 无 | `{ "unreadCount": number }` |
| Create | `Entity Type`, `Entity ID`, `Input Mode` | `Content`, `Parent ID`, `Attachment IDs` 或 JSON Object | 创建的评论以及 `autoTransitioned` |
| Mark Read | `Entity Type`, `Entity ID` | 无 | `{ "success": true, "entityType": "INCIDENT", "entityId": "11111111-1111-4111-8111-111111111111" }` |
| Update | `Comment ID`, `Input Mode` | `Content` 或 JSON Object | 更新后的评论 |
| Delete | `Comment ID` | 无 | `{ "id": "22222222-2222-4222-8222-222222222222", "entityType": "ALERT", "entityId": "11111111-1111-4111-8111-111111111111" }` |
| Toggle Reaction | `Comment ID`, `Input Mode` | `Emoji` 或 JSON Object | 更新后的评论 |
| Toggle Pin | `Comment ID` | 无 | 更新后的评论 |
### 评论 Payload 示例
在 **Individual Fields** 模式下创建评论。在节点字段中设置 `Entity Type`、`Entity ID` 和 `Content`。请求体为:
```
{
"content": "Containment started"
}
```
在 **JSON Object** 模式下创建回复。在节点字段中设置 `Entity Type` 和 `Entity ID`,然后提交此完整的 JSON Object:
```
{
"content": "Adding timeline details",
"parentId": "22222222-2222-4222-8222-222222222222"
}
```
在 **JSON Object** 模式下创建带有暂存附件的评论。在节点字段中设置 `Entity Type` 和 `Entity ID`,然后提交此完整的 JSON Object:
```
{
"attachmentIds": ["33333333-3333-4333-8333-333333333333"]
}
```
在 **Individual Fields** 模式下通过设置 `Content` 来更新评论,或者在 **JSON Object** 模式下提交此完整的 JSON Object:
```
{
"content": "Updated containment note"
}
```
在 **Individual Fields** 模式下通过设置 `Emoji` 来切换表情回应,或者在 **JSON Object** 模式下提交此完整的 JSON Object:
```
{
"emoji": "\u2705"
}
```
标签:API集成, MITM代理, n8n集成, 可观测性, 自动化攻击, 自动化流程, 运维工具