资源归属:未形成的统一模型¶
证据等级:F(源码直接证明)
分析基线:4f843556
一句话¶
8/13 资源模型缺少 tenant_id,凭证散落 5+ 处存储位置,产出物 4 种持久化方式——系统没有统一的"谁拥有什么"的答案。
1. 资源模型审计¶
Clawith 有 13 个核心资源模型。以下列出每个模型是否包含 tenant_id:
| 模型 | 表名 | 有 tenant_id? |
|---|---|---|
| Agent | agents | ✅ |
| AgentRun | agent_runs | ❌ |
| AgentRunCommand | agent_run_commands | ❌ |
| ChannelConfig | channel_configs | ❌ |
| AgentTool | agent_tools | ❌ |
| ChatSession | chat_sessions | ❌ |
| ChatMessage | chat_messages | ❌ |
| Task | tasks | ❌ |
| Workspace | workspaces | ❌ |
| FocusItem | focus_items | ❌ |
| AgentRelationship | agent_relationships | ❌ |
| AgentAgentRelationship | agent_agent_relationships | ❌ |
| OrgMember | org_members | ✅ |
8/13 模型没有 tenant_id。 这意味着多租户隔离在这些表上不生效——租户 A 的 Agent 的 run 记录和租户 B 的 Agent 的 run 记录在同一张表里,没有物理隔离,也没有数据库级过滤。
2. 凭证存储位置¶
系统中的敏感凭证分散在至少 5 个位置:
| 位置 | 存储内容 |
|---|---|
agents.api_key_hash |
Gateway API Key(SHA256 哈希) |
channel_configs.app_secret |
飞书/企业微信/WhatsApp App Secret |
channel_configs.encrypt_key |
飞书/企业微信 EncodingAESKey |
channel_configs.verification_token |
飞书/企业微信 Verification Token |
agent_tools.config(JSON) |
沙箱类型/URL/Key、MCP 凭证、自定义工具配置 |
agent_tools.config 是自由格式 JSON 字典——任何工具的任何凭证都可以塞进去,无结构约束。
3. 产出物持久化¶
Agent 产生的文件/内容通过至少 4 种路径持久化:
| 路径 | 文件类型 |
|---|---|
| 本地文件系统 | Agent 工具直接写入 |
| S3 兼容存储 | 沙箱输出 |
chat_messages 表 |
消息记录 |
focus_items 表 |
工作项 |
没有统一的"Agent 产出物"抽象——每种产出物有自己独立的存储、权限和生命周期。
4. 与 AI Coding 的关系¶
每增加一个资源模型,AI 只需要满足"当前任务"的需求——不需要考虑这个模型是否应该纳入统一的租户隔离层,因为没有人告诉它"所有资源模型必须共享一个归属层"。
这是 AI 逐任务开发的典型后果:每个模型局部合理,整体缺失一致的安全边界。
5. 关联¶
- 002 · 工具/沙箱配置更新存在 IDOR:
agent_tools表无tenant_id直接导致 IDOR - 009 · Gateway API Key 的明文存储与非恒定时间比对:
api_key_hash的存储和验证逻辑不一致