← Back to Plugins
Tools

Dingtalk Isolation Kit

jiazi009 By jiazi009 👁 18 views ▲ 0 votes

OpenClaw/Hermes DingTalk DWS multi-user identity isolation kit with per-user auth state, audit logging, policy controls, and plugin scaffolds.

GitHub

Configuration Example

{"service":"drive","args":["file","list"],"confirmed":true}

README

# OpenClaw / Hermes 钉钉 DWS 多用户身份隔离套件

> 目标:在多人共用同一个 OpenClaw 或 Hermes 智能体容器时,避免所有钉钉能力共用同一个 `dws auth login` 登录账号。

## 1. 这套文件解决什么问题

如果 OpenClaw / Hermes 容器里只安装了一份 `dws`,并且只登录了某一个人的钉钉账号,那么默认所有用户调用钉钉能力时都会使用这个账号,风险包括:

- 普通用户间接访问登录账号可见的日程、文档、审批、邮箱、云盘等;
- 操作审计显示的是登录账号,而不是实际发起请求的人;
- Agent 可能越权读取或发送钉钉数据;
- 后续很难满足企业安全审查。

本套件用三层解决:

```text
OpenClaw / Hermes 当前对话用户
        ↓
插件自动读取 current_user_id,禁止模型伪造 user_id
        ↓
openclaw-dws wrapper 选择该用户独立的 DWS_CONFIG_DIR / DWS_CACHE_DIR / DWS_KEYCHAIN_DIR / DWS_AUTH_IDENTITY
        ↓
dws CLI 以该用户自己的配置、缓存和 keychain 授权执行
        ↓
SQLite 审计日志记录:谁、何时、调用了什么、是否成功
```

## 2. 目录结构

```text
openclaw-dingtalk-isolation-kit/
  bin/
    openclaw-dws.py                 # 核心 wrapper:按用户隔离 dws 认证目录
  plugins/
    dingtalk_identity_router.py      # OpenClaw / Hermes 插件/工具适配层示例
    openclaw-plugin.example.yaml     # 插件注册模板
    hermes-plugin.example.yaml       # Hermes 注册模板
  skills/
    dingtalk-multi-user-isolation/
      SKILL.md                       # Agent 行为规范:禁止裸 dws,必须走隔离工具
  config/
    policy.example.yaml              # Agent / service 白名单策略模板
    docker-compose.patch.example.yaml# 容器挂载与环境变量示例
  sql/
    schema.sql                       # 绑定表和审计表
  install.sh                         # 安装 wrapper 到 /usr/local/bin 的示例脚本
```

## 3. 推荐部署路径

容器内建议挂载:

```text
/data/openclaw/
  dws/
    users/
      user_xxx/config/
      user_xxx/cache/
      user_xxx/keychain/
    service/
  db/
    identity.db
  logs/
```

不要继续让所有人使用默认的:

```text
~/.dws
~/.dws/cache
```

## 4. 安装 wrapper

在容器里:

```bash
cd /path/to/openclaw-dingtalk-isolation-kit
bash install.sh
```

或者手动:

```bash
install -m 0755 bin/openclaw-dws.py /usr/local/bin/openclaw-dws
```

确认:

```bash
openclaw-dws --help
```

## 5. 配置环境变量

建议在 OpenClaw 容器环境里设置:

```bash
export OPENCLAW_DWS_BASE=/data/openclaw/dws
export OPENCLAW_DWS_DB=/data/openclaw/db/identity.db
export DWS_BIN=/usr/local/bin/dws
export DWS_TENANT=company_default
export DINGTALK_AGENT=openclaw
export OPENCLAW_DWS_ALLOWED_SERVICES=auth,calendar,chat,contact,doc,drive,minutes,oa,todo,wiki,report,mail,sheet,aitable,attendance,aisearch,ding
export DINGTALK_POLICY_PATH=/data/openclaw/config/dingtalk-policy.yaml
export OPENCLAW_DWS_REQUIRE_CONFIRMATION=chat,ding,mail,oa,attendance,drive,doc,minutes
```

Hermes 容器可以使用同一 wrapper,也可以用 Hermes 前缀别名:

```bash
export HERMES_DWS_BASE=/data/hermes/dws
export HERMES_DWS_DB=/data/hermes/db/identity.db
export HERMES_DWS_WRAPPER=/usr/local/bin/openclaw-dws
export DINGTALK_AGENT=hermes
export HERMES_DWS_ALLOWED_SERVICES=auth,calendar,chat,contact,doc,drive,minutes,oa,todo,wiki,report,mail,sheet,aitable,attendance,aisearch,ding
export DINGTALK_POLICY_PATH=/data/hermes/config/dingtalk-policy.yaml
export HERMES_DWS_REQUIRE_CONFIRMATION=chat,ding,mail,oa,attendance,drive,doc,minutes
```

如果你把原始 `dws` 移到了私有路径,例如 `/usr/local/lib/dws-bin/dws`,则设置:

```bash
export DWS_BIN=/usr/local/lib/dws-bin/dws
```

## 6. 首次用户绑定流程

假设当前 runtime 用户 ID 是 `oc_user_001` 或 `hm_user_001`。

### 6.1 检查绑定状态

```bash
openclaw-dws --user oc_user_001 --binding-status
```

### 6.2 用户扫码登录自己的钉钉

```bash
openclaw-dws --user oc_user_001 auth login --format json
```

智能体容器、SSH、CI 等无头环境建议用 device flow:

```bash
openclaw-dws --user oc_user_001 auth login --device --no-browser --format json
```

该命令会在容器终端输出钉钉授权链接或 user code。把链接发给当前用户,用户在自己的浏览器里完成授权,容器内的 CLI 会轮询并在授权成功后写入该 runtime 用户自己的隔离目录。

插件工具 `dingtalk_auth_login` 也是同一条链路:它后台启动 `dws auth login --device --no-browser`,先把 `authorization_url` / `user_code` 返回给 Agent,后台进程继续等待用户完成授权。若 OpenClaw 当前只有 `exec` 工具,Agent 直接执行上面的 `openclaw-dws` 命令并转发返回链接,不要求用户进入容器或终端。

登录成功后,wrapper 会把该 runtime 用户的绑定状态标记为 `bound`。

### 6.3 执行业务命令

```bash
openclaw-dws --user oc_user_001 calendar event list --format json
```

实际内部会注入:

```bash
DWS_CONFIG_DIR=/data/openclaw/dws/users/user_<hash>/config
DWS_CACHE_DIR=/data/openclaw/dws/users/user_<hash>/cache
DWS_KEYCHAIN_DIR=/data/openclaw/dws/users/user_<hash>/keychain
DWS_AUTH_IDENTITY=user_<hash>
```

不同 runtime 用户会得到不同的 `user_<hash>`,从而隔离 token、缓存和配置。

## 7. 插件接入 OpenClaw / Hermes

`plugins/dingtalk_identity_router.py` 是一个“适配层示例”,提供三个工具:

| 工具 | 说明 |
|---|---|
| `dingtalk_auth_status` | 通过 `dws auth status` 检查当前 runtime 用户钉钉认证 |
| `dingtalk_auth_login` | 后台启动 `dws auth login --device --no-browser`,返回授权链接给当前用户 |
| `dingtalk_run` | 以当前 runtime 用户身份执行白名单内的 dws 命令 |

关键原则:

> `user_id` 不应该由模型传入,而应该由 OpenClaw / Hermes runtime 从渠道事件里的真实发送人身份注入。

OpenClaw 的钉钉会话渠道应注入钉钉发送人 ID。Hermes 的飞书会话渠道应注入飞书发送人 ID;`conversation_id` / `chat_id` 只能用于审计关联,不能当个人身份绑定。

如果 OpenClaw 2026.6.5 的插件接口与本示例不同,请保留这个原则,把 `handle_tool_call()` 接到你们实际的 tool runtime 即可。

Hermes 默认识别这些 Feishu/Lark 上下文字段:

```text
用户:feishu_user_id/lark_user_id/hermes_user_id,也兼容 event.sender.sender_id.open_id/user_id/union_id
会话:conversation_id/thread_id/chat_id/hermes_session_id,也兼容 event.message.chat_id
消息:turn_id/message_id/request_id/event_id,也兼容 event.message.message_id
```

如果 Hermes 实际字段名不同,用环境变量覆盖即可:

```bash
export DINGTALK_CONTEXT_USER_KEYS=principal_id
export DINGTALK_CONTEXT_SESSION_KEYS=conversation_id
export DINGTALK_CONTEXT_MESSAGE_KEYS=turn_id
```

示例 CLI 调试:

```bash
python3 plugins/dingtalk_identity_router.py   --tool dingtalk_auth_status   --context-json '{"user_id":"oc_user_001","session_id":"s1","message_id":"m1"}'   --args-json '{}'
```

Hermes 调试:

```bash
python3 plugins/dingtalk_identity_router.py   --tool dingtalk_auth_status   --context-json '{"hermes_user_id":"hm_user_001","conversation_id":"c1","turn_id":"t1"}'   --args-json '{}'
```

执行业务命令:

```bash
python3 plugins/dingtalk_identity_router.py   --tool dingtalk_run   --context-json '{"user_id":"oc_user_001","session_id":"s1","message_id":"m1"}'   --args-json '{"service":"calendar","args":["event","list","--format","json"]}'
```

## 8. 安全要求

### 8.1 禁止 Agent 直接调用裸 `dws`

正确:

```bash
openclaw-dws --user <current_user_id> calendar event list --format json
```

错误:

```bash
dws calendar event list --format json
```

### 8.2 最好不要把原始 `dws` 暴露在 PATH

更安全的部署方式:

```text
/usr/local/lib/dws-bin/dws        # 原始 dws,只给 wrapper 用
/usr/local/bin/openclaw-dws       # 暴露给 OpenClaw / Hermes / Agent
```

### 8.3 最终权限模型

```text
最终权限 = OpenClaw / Hermes 当前用户身份
       ∩ 用户自己的钉钉授权
       ∩ Agent 工具白名单
       ∩ 当前任务授权范围
```

### 8.4 系统账号与个人账号分离

- 个人资源:必须用当前用户自己的钉钉授权。
- 系统通知:可以用 service account,但只能开放 `chat`、`ding` 等低风险服务。

### 8.5 服务白名单与二次确认

wrapper 优先读取统一命名:

```bash
OPENCLAW_DWS_ALLOWED_SERVICES=auth,calendar,chat,...
HERMES_DWS_ALLOWED_SERVICES=auth,calendar,chat,...
```

为兼容早期模板,也会接受 `OPENCLAW_DINGTALK_ALLOWED_SERVICES` / `HERMES_DINGTALK_ALLOWED_SERVICES`。

敏感服务或具体命令需要当前用户明确确认后才能执行。可通过环境变量设置:

```bash
OPENCLAW_DWS_REQUIRE_CONFIRMATION=chat,ding,mail,oa,attendance,drive,doc,minutes
# 或
HERMES_DWS_REQUIRE_CONFIRMATION=chat,ding,mail,oa,attendance,drive,doc,minutes
```

也可以通过 `DINGTALK_POLICY_PATH` 指向类似 `config/policy.example.yaml` 的策略文件。当前内置解析支持 `sensitive_services: [...]` 和 `require_confirmation: [...]` 这种行内列表。

确认后的插件调用应传:

```json
{"service":"drive","args":["file","list"],"confirmed":true}
```

wrapper 侧会收到 `DINGTALK_CONFIRMED=1`。没有确认时,敏感服务会返回 `dws command requires explicit confirmation`。

### 8.6 `--mark-bound` 安全边界

`--mark-bound` 不再无条件标记绑定。它必须满足其中之一:

1. 当前隔离身份的 `dws auth status --format json` 成功;
2. 受控迁移时显式设置 `OPENCLAW_DWS_ADMIN_OVERRIDE=1` 或 `HERMES_DWS_ADMIN_OVERRIDE=1`。

普通生产流程应让用户通过 `auth login --device --no-browser` 完成自己的钉钉授权,而不是手动 mark。

## 9. Skill 使用

把 `skills/dingtalk-multi-user-isolation/SKILL.md` 安装到 OpenClaw / Hermes 的技能目录中,让 Agent 在涉及钉钉能力时加载。

但要注意:

> Skill 是行为规范,不是安全边界。真正的隔离必须靠 wrapper / 插件强制实现。

## 10. MVP 验收清单

- [ ] 用户 A 登录后,`/data/openclaw/dws/users/user_A_hash/` 下有独立配置与缓存;
- [ ] 用户 B 登录后,目录不同;
- [ ] 用户 A 查日程不会返回用户 B 的日程;
- [ ] 未绑定用户调用非 `auth` 服务会被拒绝;
- [ ] `identity.db` 中有绑定记录;
- [ ] 每次调用 `dingtalk_audit_logs` 都有审计记录;
- [ ] Agent 无法直接执行裸 `dws`;
- [ ] 写操作仍需要二次确认。

## 11. 后续增强建议

1. 在 wrapper 中加入更细粒度策略:哪些 Agent 可以调用哪些 dws 服务;
2. 对 `mail`、`oa`、`attendance`、`drive`、`doc` 等敏感服务增加二次确认;
3. 把审计日志接入企业日志系统;
4. 增加管理员后台,管理用户绑定和解绑;
5. 增加 token 过期提醒和重新授权流程;
6. 增加“代表当前用户,但禁止永久保存敏感结果”的数据治理规则。
tools

Comments

Sign in to leave a comment

Loading comments...