Add files via upload

This commit is contained in:
公明
2026-07-10 21:35:49 +08:00
committed by GitHub
parent 0251230654
commit c33e5f2026
9 changed files with 1032 additions and 43 deletions
+1
View File
@@ -8,6 +8,7 @@
- [贡献规范](contributing-guide.md):新增 API、配置、工具、前端、数据库、高风险能力和文档的 checklist。
- [配置参考](configuration.md)`config.yaml` 字段、热应用边界、参数建议和源码锚点。
- [安全模型](security-model.md):信任边界、HITL、工具执行、C2/WebShell 与数据安全。
- [RBAC 权限管理](rbac.md):平台用户、系统/自定义角色、权限目录、逐权限 Scope、资源授权、Agent/MCP/机器人边界与 API 示例。
- [架构说明](architecture.md):请求路径、模块关系、复杂度热点和设计取舍。
- [API 参考](api-reference.md):认证、OpenAPI、SSE、稳定性分层和常用接口。
- [排错指南](troubleshooting.md):诊断顺序、最小命令、常见误判和故障模板。
+386
View File
@@ -0,0 +1,386 @@
# CyberStrikeAI RBAC 使用与管理指南
[English](../en-US/rbac.md)
CyberStrikeAI 是可执行 Agent、MCP、WebShell、C2 和批量任务的安全自动化平台。RBAC 不仅控制页面是否可见,还会贯穿 HTTP API、资源查询、Agent 上下文、内置/外部 MCP 工具、后台任务和机器人执行链路。
---
## 一、先区分两种“角色”
| 概念 | 管理入口 | 作用 |
|------|----------|------|
| **平台角色(RBAC Role** | 左侧 **平台权限** | 决定用户能调用哪些功能、能访问哪些资源 |
| **AI 测试角色(Agent Role** | 左侧 **角色** / `roles/*.yaml` | 决定 Agent 的提示词、测试方法和可选工具集合 |
AI 测试角色不是安全授权边界。即使选择了“渗透测试”角色,用户仍必须拥有对应的平台权限;反过来,RBAC 有权限也不会自动改变 Agent 提示词。
---
## 二、授权模型
一次访问同时满足以下条件才会放行:
```text
有效账号
+ 路由/工具所需 permission
+ 该 permission 对应的 scope
+ 目标资源 owner / 显式授权 / 父资源继承
+ 全局操作的额外限制
```
处理链路:
1. 登录后签发 Bearer Token,会话包含用户、角色、权限和逐权限 Scope。
2. HTTP 中间件把路由映射为权限,例如 `GET /api/projects``project:read`
3. 对带资源 ID 的请求继续校验 owner、显式资源授权或父资源继承。
4. Agent 启动时把不可变 Principal 写入 `context.Context`
5. 内置 MCP 工具根据工具和参数再次检查权限与资源;外部 MCP 也有独立限制。
6. 拒绝事件写入 RBAC/审计日志。
前端隐藏按钮只用于改善体验,不构成安全边界;真正的拒绝发生在服务端。
---
## 三、内置平台角色
| 角色 | Scope | 默认能力 |
|------|-------|----------|
| **管理员 `admin`** | `all` | 所有已知权限,包括 RBAC、配置、终端、审计删除和全局定义管理 |
| **操作员 `operator`** | `assigned` | 日常读写与执行能力;不含 RBAC、核心配置、终端、审计管理、外部 MCP 执行和部分全局定义写权限 |
| **审计员 `auditor`** | `all` | 各模块只读权限和 `audit:read`,不执行写操作 |
| **只读用户 `viewer`** | `assigned` | 各模块只读权限,仅查看被授权范围 |
系统角色不可修改或删除,升级时会按当前版本的权限目录重新构建授权,避免旧版本残留权限。需要不同组合时创建自定义角色。
没有分配任何角色的账号仍可登录,但基本没有业务权限;不要依赖“无角色”作为完整岗位配置。
---
## 四、权限命名与目录
权限使用 `模块:动作` 命名。常见动作:
- `read`:查看、列表、查询、导出。
- `write`:创建、更新、执行或管理。
- `delete`:删除。
- `execute`:执行 Agent、终端、工作流或特定能力。
当前权限按模块分组如下;运行版本的权威目录以“平台权限”页面或 `GET /api/rbac/metadata` 为准。
| 模块 | 权限 |
|------|------|
| 账号 | `auth:self` |
| 仪表盘 | `dashboard:read` |
| 对话 | `chat:read``chat:write``chat:delete` |
| Agent | `agent:execute``agent:local-execute` |
| HITL | `hitl:read``hitl:write` |
| 任务 | `tasks:read``tasks:write``tasks:delete` |
| 项目 | `project:read``project:write``project:delete` |
| 漏洞 | `vulnerability:read``vulnerability:write``vulnerability:delete` |
| WebShell | `webshell:read``webshell:write``webshell:delete` |
| C2 | `c2:read``c2:write``c2:delete` |
| MCP | `mcp:read``mcp:execute``mcp:write``mcp:external:execute` |
| 知识库 | `knowledge:read``knowledge:write``knowledge:delete` |
| Skills | `skills:read``skills:write``skills:delete` |
| Markdown Agents | `agents:read``agents:write``agents:delete` |
| AI 测试角色 | `roles:read``roles:write``roles:delete` |
| 工作流 | `workflow:read``workflow:execute``workflow:write``workflow:delete` |
| 系统配置 | `config:read``config:write` |
| 终端 | `terminal:execute` |
| 审计 | `audit:read``audit:delete` |
| RBAC | `rbac:read``rbac:write` |
| 通知 | `notification:read``notification:write` |
| 机器人 | `robot:read``robot:write` |
| 文件 | `files:read``files:write``files:delete` |
| 攻击链 | `attackchain:read``attackchain:write` |
| FOFA | `fofa:execute` |
| OpenAPI | `openapi:read` |
| 对话分组 | `group:read``group:write``group:delete` |
| 执行监控 | `monitor:read``monitor:write``monitor:delete` |
特殊权限说明:
- `agent:execute` 允许运行 Agent,但不自动允许本地文件系统、Shell 或任意配置命令。
- `agent:local-execute` 是本地执行兜底权限,应仅授予可信操作员。
- `mcp:execute` 用于访问认证后的 MCP HTTP 入口。
- `mcp:external:execute` 用于 Agent 调用外部 MCP 工具,当前还要求该权限的 Scope 为 `all`
- 管理外部 MCP 配置使用 `mcp:write`,与执行外部工具是两项权限。
- `robot:write` 管理机器人配置和测试入口;机器人聊天本身使用绑定用户或服务账号的业务权限。
---
## 五、资源 Scope
每个角色包含一个 Scope
| Scope | 含义 | 适合场景 |
|-------|------|----------|
| `all` | 访问该权限覆盖的所有资源 | 管理员、全局审计员 |
| `assigned` | 访问管理员指定的资源及系统支持的父资源继承范围 | 项目成员、指定资产操作员 |
| `own` | 以本人创建/归属资源为主;部分资源仍可通过显式授权或父资源关系访问 | 个人工作区、机器人独立身份 |
权限和 Scope 是绑定在一起计算的。一个用户可拥有多个角色,权限取并集;**同一个权限**的 Scope 取最宽值:
```text
all > assigned > own
```
示例:
- “全局审计”角色:`project:read` + `all`
- “个人项目编辑”角色:`project:write` + `own`
最终结果是:
```text
project:read → all
project:write → own
```
全局读取不会把无关的写权限扩大为全局写入。服务端授权必须使用 `ScopeFor(permission)`,不能使用用户的最宽总 Scope。
### 全局对象限制
部分对象是进程级共享定义,没有 owner。即使用户拥有 `write`,若该权限 Scope 不是 `all`,服务端仍拒绝修改。例如:
- AI 测试角色、Skills、Markdown Agents。
- 外部 MCP 配置。
- 机器人配置。
- 工作流定义。
- 知识库写操作(搜索除外)。
- HITL 全局白名单、默认审核方和审计策略。
- C2 Profile 写操作。
- 部分全局监控统计。
---
## 六、资源归属、显式授权与继承
可在“平台权限 → 成员详情 → 资源授权”中给用户分配资源。当前可直接选择的主要类型:
- 项目 `project`
- 对话 `conversation`
- 漏洞 `vulnerability`
- WebShell `webshell`
- 批量任务队列 `batch_task`
- C2 Listener `c2_listener`
一次批量授权最多 100 个资源。重复授权会跳过,不会创建重复记录。
部分子资源会继承父资源访问能力:
| 子资源 | 可继承的父资源 |
|--------|----------------|
| 对话 | 所属项目 |
| 漏洞 | 所属项目或关联对话 |
| 消息、过程详情、攻击链 | 所属对话 |
| C2 Session | Listener |
| C2 Task / 文件 /事件 | Session、Task 或 Listener 链路 |
因此,给用户授权一个项目,通常不需要再逐个授权该项目中的每条对话和漏洞。仍应以具体页面/API 的服务端检查结果为准。
---
## 七、Web 管理流程
### 7.1 创建用户
1. 使用管理员进入左侧 **平台权限**
2. 创建平台用户,设置用户名、显示名称、至少 8 位密码和启用状态。
3. 分配一个或多个平台角色。
4. 若角色 Scope 为 `assigned`,继续配置资源授权。
5. 让用户重新登录并在右上角用户菜单确认角色、权限数量和 Scope。
### 7.2 创建自定义角色
1. 新建平台角色并填写清晰的岗位名称与说明。
2. 选择 `all``assigned``own`
3. 只勾选岗位实际需要的权限。
4. 先用测试账号验证列表、详情、写操作、删除和 Agent 工具调用。
5. 再批量分配给正式用户。
系统角色不可编辑;复制其思路创建自定义角色即可。
### 7.3 权限变更何时生效
- 更新用户、密码、启用状态或角色后,该用户现有会话会被撤销,需要重新登录。
- 更新或删除自定义角色后,平台会撤销全部现有会话,所有用户需重新登录。
- 机器人每条消息实时解析绑定用户/服务账号权限;用户禁用或角色调整会立即影响下一条消息。
- 后台批量任务会根据任务 owner 重新解析 Principal,不应依赖创建任务时的前端状态。
---
## 八、推荐角色模板
以下是起点,不是固定策略。
### 只读项目成员
```text
Scope: assigned
dashboard:read
chat:read
project:read
vulnerability:read
files:read
attackchain:read
```
### 日常安全操作员
```text
Scope: assigned
agent:execute
chat:read / chat:write
project:read / project:write
vulnerability:read / vulnerability:write
tasks:read / tasks:write
files:read / files:write
hitl:read / hitl:write
```
只有确实需要本机命令时才增加 `agent:local-execute``terminal:execute`;需要删除时再增加对应 `:delete`
### 机器人专用账号
```text
Scope: own(独立工作区)或 assigned(指定项目)
agent:execute
chat:read / chat:write
按需增加 project、vulnerability、knowledge 等权限
```
也可使用 `admin` 作为机器人服务账号,但发送者仍需精确白名单;白名单内每个人都会获得完整权限并共享 admin 数据。详见[机器人指南](robot.md)。
---
## 九、Agent、MCP 与机器人边界
### Agent
HTTP 登录用户会被转换为不可变 Principal,传入单 Agent、多 Agent、工作流和工具执行上下文。长任务脱离 SSE 连接后仍保留身份,但不会因为前端按钮可见而绕过服务端权限。
### 内置 MCP
每个内置工具必须有显式授权策略。例如 WebShell 工具会同时检查 `webshell:read/write/delete``connection_id` 的资源访问;漏洞、项目、任务与 C2 工具也会检查参数指向的资源。
未登记授权策略的内置工具默认拒绝。普通本地/配置工具需要 `agent:local-execute`
### 外部 MCP
Agent 调用外部 MCP 工具需要 `mcp:external:execute`,且当前要求 Scope 为 `all`。这是因为外部服务的资源模型通常不受本地 owner/assignment 约束。
### 机器人
- `user_binding`:平台发送者绑定自己的 RBAC 用户。
- `service_account`:精确白名单发送者统一使用一个 RBAC 用户。
- 平台验签只做来源认证,不代替业务授权。
- 发送 `身份` / `whoami` 可检查实际 Principal。
---
## 十、RBAC API
所有接口使用:
```http
Authorization: Bearer <token>
```
管理接口需要 `rbac:read``rbac:write`,资源选择器需要 `rbac:write`
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/rbac/me` | 当前用户、角色、权限、总 Scope 与逐权限 Scope |
| GET | `/api/rbac/metadata` | 权限目录、角色、角色权限和 Scope 列表 |
| GET/POST | `/api/rbac/users` | 列出/创建用户 |
| PUT/DELETE | `/api/rbac/users/:id` | 更新/删除用户 |
| GET/POST | `/api/rbac/roles` | 列出/创建角色 |
| PUT/DELETE | `/api/rbac/roles/:id` | 更新/删除自定义角色 |
| GET | `/api/rbac/resources?type=project&q=...` | 分页搜索可授权资源 |
| GET/POST | `/api/rbac/resource-assignments` | 列出/创建资源授权 |
| DELETE | `/api/rbac/resource-assignments/:id` | 撤销资源授权 |
创建用户示例:
```bash
curl -X POST http://localhost:8080/api/rbac/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "operator01",
"display_name": "安全操作员 01",
"password": "change-me-123",
"enabled": true,
"roles": ["operator"]
}'
```
创建自定义角色示例:
```bash
curl -X POST http://localhost:8080/api/rbac/roles \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "项目审计员",
"description": "只读查看指定项目",
"scope": "assigned",
"permissions": ["chat:read", "project:read", "vulnerability:read"]
}'
```
批量授权项目示例:
```bash
curl -X POST http://localhost:8080/api/rbac/resource-assignments \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"user_id": "USER_ID",
"resource_type": "project",
"resource_ids": ["PROJECT_ID_1", "PROJECT_ID_2"]
}'
```
---
## 十一、审计与运维建议
- 使用个人账号管理平台,避免多人共享管理员密码。
- 自定义角色按岗位命名,描述中写明用途和负责人。
- 高风险权限单独审批:`terminal:execute``agent:local-execute``c2:write/delete``webshell:write/delete``rbac:write``config:write`
- 定期检查 `all` Scope 角色、服务账号、机器人白名单和长期未使用用户。
- 用户离职时先禁用账号,再撤销机器人绑定、资源授权和会话。
- 在日志审计中关注 `rbac/access_denied`、角色/用户变更、资源授权、机器人服务账号执行。
- 配合 HITL 控制高风险工具;RBAC 允许调用不等于可以跳过审批。
---
## 十二、常见问题
### 页面按钮看不到
检查用户是否有对应权限;前端会根据 `/api/rbac/me` 隐藏无权操作。直接调用 API 仍会由服务端拒绝。
### 有权限但返回“无权访问该资源”
检查该权限的 Scope,而不是只看用户总 Scope;再检查资源 owner、显式授权和父资源授权。
### 角色改了但用户仍是旧权限
角色变更会撤销会话。让用户重新登录;机器人下一条消息会重新解析权限。
### `write` 权限存在但全局配置仍被拒绝
全局对象写操作要求对应权限的 Scope 为 `all`。创建一个 `all` Scope 的专用管理角色,而不是扩大无关权限。
### Agent 能对话但不能运行命令
`agent:execute``agent:local-execute` 分离。按需授予本地执行权限,并结合 HITL、工具白名单和审计。
### 外部 MCP 提示需要 global scope
`mcp:external:execute` 外,该权限的 Scope 还必须为 `all`。外部 MCP 的数据边界不由本地资源授权自动保护。
+134 -19
View File
@@ -2,7 +2,7 @@
[English](../en-US/robot.md)
本文档说明如何通过**个人微信**、**钉钉**、**飞书**与 **企业微信** 与 CyberStrikeAI 对话(长连接 / 回调模式),在手机端即可使用,无需在服务器上打开网页。按下面步骤操作可避免常见弯路
本文档说明如何通过**个人微信、企业微信、钉钉、飞书、Telegram、Slack、Discord 和 QQ 机器人**使用 CyberStrikeAI,包括平台接入、RBAC 身份绑定、服务账号白名单、命令、验证与故障排查
---
@@ -15,10 +15,18 @@
- **个人微信**:点击「微信 / iLink」→「生成二维码并绑定」,用微信扫码确认(见 [3.4 个人微信](#34-个人微信-wechat--ilink)
- **钉钉**:勾选并填写 Client ID / Client Secret
- **飞书**:勾选并填写 App ID / App Secret
5. 点击 **应用配置** 保存微信扫码绑定成功后会**自动保存并启用**,一般无需再点
6. **重启 CyberStrikeAI 应用**(钉钉/飞书:只保存不重启,长连接不会建立;微信绑定成功后会自动重启连接,通常无需手动重启)
5. 点击 **应用配置** 保存;程序会自动重启对应机器人连接。微信扫码绑定成功后会自动保存并启用,一般无需再点
配置会写入 `config.yaml``robots` 段,也可在配置文件中直接编辑。**修改钉钉/飞书配置后必须重启,长连接才会生效。** 个人微信绑定成功后程序会自动写入 `robots.wechat` 并重启 iLink 长轮询。
配置会写入 `config.yaml``robots` 段,也可在配置文件中直接编辑。通过 Web 点击“应用配置”会自动重启对应连接;直接手工修改 `config.yaml` 时,需要重启 CyberStrikeAI 进程。个人微信绑定成功后程序会自动写入 `robots.wechat` 并重启 iLink 长轮询。
### 最短使用路径
平台连接成功后,不要直接开始普通对话,先完成业务身份配置:
- **多人使用**:机器人设置选择“逐用户绑定” → 每位用户在 Web 右上角头像生成绑定码 → 在机器人中发送绑定命令 → 发送 `身份` 验证。
- **只有自己使用**:先在机器人中发送 `身份` 复制发送者 ID → 机器人设置选择“专用服务账号” → User ID 填 `admin` 或其他 RBAC 用户 → 粘贴发送者白名单 → 应用配置 → 再次发送 `身份` 验证。
看到“鉴权状态:已授权”且“实际身份”正确后,即可直接发送普通文本与 AI 对话。
---
@@ -300,12 +308,88 @@
---
## 四、机器人命令
## 四、RBAC 鉴权与机器人命令
平台 Token、签名或长连接凭证只负责证明“消息来自该平台”;真正能执行哪些操作,由 CyberStrikeAI 的 RBAC 决定。每个机器人实例都必须选择一种业务鉴权模式。
### 4.1 应该选择哪种模式
| 使用场景 | 推荐模式 | 身份与数据范围 |
|----------|----------|----------------|
| 企业微信、飞书、钉钉、Slack 等多人共享机器人 | `user_binding` | 每个发送者绑定自己的 Web 用户,权限和数据互相隔离 |
| 个人微信、单人专属机器人、固定自动化入口 | `service_account` | 白名单发送者统一使用配置的 RBAC 用户,并共享该账号的数据 |
两种模式都会在**每条消息**执行前重新读取用户状态、角色、逐权限 Scope 和资源授权。用户被禁用或权限被收回后,下一条消息立即失效。
机器人执行普通 AI 对话至少需要以下权限:
```text
agent:execute
chat:read
chat:write
```
使用项目、角色、本地命令、WebShell、C2 或外部 MCP 时,还需按功能增加对应权限。删除对话需要 `chat:delete`
### 4.2 逐用户绑定模式(默认)
管理员操作:
1. 系统设置 → 机器人设置 → 选择平台。
2. 在“业务鉴权策略”中选择“逐用户绑定(`user_binding`)”。
3. 点击“应用配置”。
每位使用者操作:
1. 登录 CyberStrikeAI Web,点击右上角头像 → **绑定机器人账号**
2. 点击 **生成绑定码**,页面开始 5 分钟倒计时。
3. 在目标机器人中发送页面给出的完整命令,例如 `绑定 7C6E-BD4C`
4. 发送 `身份``whoami`,确认“鉴权状态:已授权”且“实际身份”是自己的 Web 用户。
绑定码仅保存哈希、只能使用一次。倒计时结束后前端会标记失效、禁用复制并刷新绑定列表;服务端也会拒绝过期码。重新生成会让此前尚未使用的旧码立即失效。用户可发送 `解绑`,或在 Web 绑定窗口中撤销绑定。
### 4.3 专用服务账号模式
1. 先让机器人正常连接平台。
2. 目标使用者向机器人发送 `身份` / `whoami`,复制返回的完整“发送者 ID”。个人微信的 ID 通常形如 `xxxx@im.wechat`;必须以命令返回值为准,不能用 `ilink_bot_id` 或配置中的 `ilink_user_id` 代替。
3. 系统设置 → 机器人设置 → 选择平台 → 业务鉴权策略选择“专用服务账号(`service_account`)”。
4. 填写服务账号的 **RBAC User ID**,不是显示名称。可以填写 `admin`;此时白名单发送者拥有完整平台权限,界面会显示红色风险提示。
5. 在“允许的平台发送者 ID”中每行填写一个完整 ID。必须精确匹配、区分大小写,不允许 `*` 通配符。
6. 点击“应用配置”,再发送 `身份` 确认“实际身份”和角色正确。
示例:
```yaml
robots:
wechat:
auth:
mode: service_account
service_user_id: admin
allowed_external_users:
- "o9cq806s32Sm2_kyOmkyaV7Rn1lU@im.wechat"
```
服务账号模式不接受 `绑定` / `解绑` 命令。多个白名单发送者会共享服务账号创建的对话、项目和其他 `own` 范围资源;若不希望共享,请使用逐用户绑定。
### 4.4 如何检查当前身份
发送:
```text
身份
```
返回内容包含:平台、真实发送者 ID、鉴权模式、鉴权状态、实际 RBAC 用户、RBAC User ID、平台角色、资源范围和有效权限数量。不在服务账号白名单中的发送者只会看到拒绝状态,不会看到服务账号详情。
### 4.5 命令列表
在任一已接入平台(钉钉/飞书/微信/Telegram/Slack/Discord/QQ 等)向机器人发送以下**文本命令**(仅支持文本):
| 命令 | 说明 |
|------|------|
| **绑定 \<绑定码\>** | 将当前平台发送者绑定到生成绑定码的 RBAC 用户 |
| **解绑** | 解除当前平台账号绑定;也可在 Web 端的绑定列表中撤销 |
| **身份****whoami** | 显示平台发送者 ID、鉴权模式、绑定状态及当前实际 RBAC 用户、角色和资源范围 |
| **帮助** | 显示命令帮助与说明 |
| **列表****对话列表** | 列出所有对话的标题与对话 ID |
| **切换 \<对话ID\>****继续 \<对话ID\>** | 指定对话 ID,后续消息在该对话中继续 |
@@ -320,6 +404,8 @@
除以上命令外,**直接输入任意文字**会作为用户消息发给 AI,与 Web 端对话逻辑一致(渗透测试/安全分析等)。
群聊消息按实际发送者鉴权,不使用群 ID 作为业务身份。服务账号模式除外:白名单发送者会明确共享配置的服务账号权限和资源。
---
## 五、如何使用(要 @ 机器人吗?)
@@ -338,14 +424,17 @@
1. CyberStrikeAI Web 端 → 系统设置 → 机器人设置 → **微信 / iLink****生成二维码并绑定**
2. 手机微信扫码确认(如需配对数字则在 Web 页填写)。
3. 绑定成功后,在手机微信私聊中发「帮助」测试。
3. 在手机微信私聊中发`身份`,复制发送者 ID。
4. 回到机器人设置选择 `user_binding`,或选择 `service_account` 并填写服务账号与发送者白名单。
5. 点击应用配置,在微信中再次发送 `身份`,确认实际 RBAC 身份后再发送普通消息。
**钉钉 / 飞书**
1. **在开放平台**:按第三节完成应用创建、凭证复制、机器人开通(钉钉务必选 **Stream 模式**)、权限与发布。
2. **在 CyberStrikeAI**:系统设置 → 机器人设置 → 勾选对应平台,粘贴 Client ID/App ID、Client Secret/App Secret → 点击 **应用配置**
3. **重启 CyberStrikeAI 进程**(否则长连接不会建立)
4. **在手机钉钉/飞书**:找到该机器人(单聊直接发,群聊需 @机器人),发「帮助」或任意内容测试。
3. **选择鉴权模式**:多人使用建议 `user_binding`;专用机器人配置服务账号与发送者白名单
4. **应用配置**Web 会自动重启对应连接。
5. **在手机钉钉/飞书**:找到机器人(单聊直接发,群聊需 @),先发 `身份` 检查鉴权,再发普通内容测试。
若发消息没反应,先看 **第九节排查****第十节常见弯路**
@@ -359,6 +448,11 @@
robots:
wechat: # 个人微信 iLink(扫码绑定后自动写入,一般无需手填)
enabled: true
auth:
mode: service_account
service_user_id: admin
allowed_external_users:
- "从身份命令复制的完整发送者 ID"
bot_token: "your_bot_token@im.bot:..."
ilink_bot_id: "your_bot_id@im.bot"
ilink_user_id: "your_user_id@im.wechat"
@@ -367,10 +461,14 @@ robots:
bot_agent: "CyberStrikeAI/1.0"
dingtalk:
enabled: true
auth:
mode: user_binding
client_id: "your_dingtalk_app_key"
client_secret: "your_dingtalk_app_secret"
lark:
enabled: true
auth:
mode: user_binding
app_id: "your_lark_app_id"
app_secret: "your_lark_app_secret"
verify_token: ""
@@ -400,7 +498,7 @@ robots:
sandbox: true
```
修改钉钉/飞书/企业微信/Telegram/Slack/Discord/QQ 配置后,点击 **应用配置** 会自动重启对应连接。个人微信扫码绑定成功后会自动写入并重启 iLink 连接。
每个平台的 `auth` 独立配置;省略时默认为 `user_binding`。修改配置后,在 Web 点击 **应用配置** 会自动重启对应连接;手工编辑 YAML 则需重启进程。个人微信扫码绑定成功后会自动写入并重启 iLink 连接。
---
@@ -408,20 +506,24 @@ robots:
在未安装钉钉或飞书时,可用**测试接口**验证机器人逻辑是否正常:
1. 先登录 CyberStrikeAI Web 端(保证有登录态)
2. 使用 curl 调用测试接口(需携带登录后的 Cookie
1. 使用具有全局 `robot:write` 权限的账号登录并获取 Bearer Token
2. 使用 curl 调用测试接口:
```bash
# 将 YOUR_COOKIE 替换为登录后获得的 Cookie(浏览器 F12 → 网络 → 任意请求 → 请求头中的 Cookie)
# 先登录;请按实际地址、用户名和密码修改
TOKEN=$(curl -s -X POST "http://localhost:8080/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"YOUR_PASSWORD"}' | jq -r '.token')
curl -X POST "http://localhost:8080/api/robot/test" \
-H "Content-Type: application/json" \
-H "Cookie: YOUR_COOKIE" \
-H "Authorization: Bearer $TOKEN" \
-d '{"platform":"dingtalk","user_id":"test_user","text":"帮助"}'
```
若返回 JSON 中含有 `"reply":"【CyberStrikeAI 机器人命令】..."`,说明命令处理正常。可再试 `"text":"列表"``"text":"当前"`
若返回 JSON 中含有 `"reply":"【CyberStrikeAI 机器人命令】..."`,说明命令处理正常。`帮助``版本``身份` 可在未绑定时执行;`列表``当前` 和普通 AI 消息会走真实 RBAC,测试用 `platform + user_id` 必须已经绑定,或与服务账号模式的发送者白名单精确匹配
接口说明:`POST /api/robot/test`(需登录),请求体 `{"platform":"可选","user_id":"可选","text":"必填"}`,响应 `{"reply":"回复内容"}`
接口说明:`POST /api/robot/test`(需全局 `robot:write`),请求体 `{"platform":"可选","user_id":"可选","text":"必填"}`,响应 `{"reply":"回复内容"}`该接口仅模拟机器人业务逻辑,不验证第三方平台签名或长连接。
---
@@ -458,8 +560,8 @@ curl -X POST "http://localhost:8080/api/robot/test" \
1. **Client ID / Client Secret 是否与开放平台完全一致**
从「凭证与基础信息」里**复制粘贴**,不要手打。注意数字 **0** 与字母 **o**、数字 **1** 与字母 **l**(例如 `ding9gf9tiozuc504aer` 中间是 **504** 不是 5o4)。
2. **是否在保存配置后重启了应用**
机器人长连接在**应用启动时**建立。在 Web 端点击应用配置」只写入配置文件,**必须重启 CyberStrikeAI 进程**后钉钉连接才会生效
2. **配置是否已应用**
在 Web 端修改后必须点击应用配置”,程序会自动重启对应连接。若直接手工编辑 `config.yaml`,则需重启 CyberStrikeAI 进程。
3. **看程序日志**
- 启动后应看到:`钉钉 Stream 正在连接…``钉钉 Stream 已启动(无需公网),等待收消息`
@@ -469,6 +571,15 @@ curl -X POST "http://localhost:8080/api/robot/test" \
4. **开放平台侧**
应用需已**发布**;在「机器人」能力中需开启**流式接入(Stream)** 用于接收消息(仅 HTTP 回调不够);权限管理里需有机器人接收、发送消息等权限。
### 9.3 收到回复但提示未绑定、白名单拒绝或权限不足
1. 先发送 `身份`,查看“鉴权模式”和“鉴权状态”。
2. `user_binding` 显示未绑定:在 Web 右上角头像中生成绑定码,并在同一个平台账号中发送完整绑定命令。绑定码过期或已经使用时需重新生成。
3. `service_account` 显示白名单拒绝:把 `身份` 返回的完整发送者 ID 原样加入当前平台的白名单,注意大小写、租户前缀和 `@im.wechat` 等后缀。
4. 显示实际身份但提示缺少权限:在“平台权限”检查该 RBAC 用户的角色。普通 AI 对话至少需要 `agent:execute``chat:read``chat:write`
5. 服务账号不存在或被禁用:应用配置会拒绝保存;恢复用户或选择其他已启用 RBAC 用户。
6. 使用 `admin` 时仍被拒绝:通常是发送者不在精确白名单中,而不是 admin 权限不足。
---
## 十、常见弯路(避免踩坑)
@@ -476,7 +587,11 @@ curl -X POST "http://localhost:8080/api/robot/test" \
- **个人微信与企业微信混淆**:个人微信走 `robots.wechat` + Web 扫码绑定;企业微信走 `robots.wecom` + 管理后台回调 URL,二者完全不同。
- **个人微信二维码过期**:二维码约 5 分钟有效,过期需重新生成,不要一直扫旧码。
- **用错了机器人类型**:在钉钉**群里**添加的「自定义」机器人(Webhook + 加签)**不能**用来做对话,本程序只支持**开放平台「企业内部应用」**里的机器人。
- **只保存没重启**:钉钉/飞书改完配置后必须**重启应用**,否则长连接不会建立(个人微信扫码绑定会自动重启连接)
- **改完没有点应用配置**:Web 中修改机器人配置后要点击“应用配置”;程序会自动重启对应连接。只有手工编辑 YAML 时才需要重启进程
- **把 Bot ID 当成发送者 ID**:服务账号白名单必须填写 `身份` 命令返回的“发送者 ID”,不要填 `ilink_bot_id``ilink_user_id`、群 ID 或显示昵称。
- **绑定码过期后继续使用**:绑定码 5 分钟有效且只能使用一次;新生成的码会让旧码立即失效。
- **服务账号误以为数据隔离**:同一服务账号白名单中的发送者共享该账号的对话和 `own` 范围资源;需要隔离时应使用 `user_binding`
- **admin 配置后任意人都能用**:不会。即使服务账号是 `admin`,发送者仍必须与白名单精确匹配;但白名单中的人将拥有完整权限。
- **Client ID 抄错**:开放平台是 `504` 就填 `504`,不要填成 `5o4`;尽量用复制粘贴。
- **钉钉只开了 HTTP 回调没开 Stream**:本程序通过 **Stream 长连接**收消息,开放平台里机器人的消息接收方式必须选 **Stream 模式**
- **应用没发布**:开放平台里修改了机器人或权限后,要在「版本管理与发布」里**发布新版本**,否则不生效。
@@ -487,5 +602,5 @@ curl -X POST "http://localhost:8080/api/robot/test" \
- 各平台均**仅处理文本消息**;其他类型(如图片、语音)会提示暂不支持或忽略。
- 个人微信仅支持**私聊**,不支持群聊 @ 机器人。
- 会话与 Web 端共用同一套对话数据:在机器人里创建的对话会在 Web 端「对话」列表中看到,反之亦然
- 会话与 Web 端共用同一套数据:`user_binding` 下归属于绑定用户;`service_account` 下归属于服务账号,并由白名单发送者共享
- 机器人执行与 **Eino 单/多代理** 相同逻辑(`ProcessMessageForRobot`,含进度回调与过程详情入库),仅不向客户端推送 SSE,最后一次性回复个人微信/钉钉/飞书/企业微信。默认 `robot_default_agent_mode: eino_single`