问题
Docker Feishu 一键启动有两个叠加的静默失败点:
FEISHU_ALLOW_FROM=ou_a,ou_b / FEISHU_ALLOW_CHATS=oc_a,oc_b 被整体传给一个 CLI 参数,最终写成单元素数组 ['ou_a,ou_b'];真实 sender ou_a / chat oc_a 永远精确匹配不到。
anet channel add feishu 的任何非零退出都被 entrypoint 当成 “likely already-added” 吞掉,随后仍然 exec agent-node。这包括 allowlist 全空时 CLI 明确拒绝的配置错误,也包括其他真实 channel-add 失败。
结果是容器 / agent-node 看起来启动了,但 channel 可能没创建,或所有真实 ID 都被 deny。
代码证据
另一个数据丢失风险:entrypoint 每次重启都会再次调用 channel add,而 writer 会原子重写 access.json。因此在容器内用 anet channel allow 追加的 ID,会在下次重启时被 .env 中的单值覆盖。
安全复现(不需要真实飞书 App,不发消息)
- 在隔离 Docker + 临时 HOME / 节点目录中使用 dummy
ou_A, ou_B, oc_A, oc_B。
- 令
FEISHU_ALLOW_FROM=ou_A,ou_B,走 entrypoint 的参数构造;检查当前生成值为 {"allowFrom":["ou_A,ou_B"]}。
- 对纯函数 resolver 传
senderId='ou_A' 和 allowFrom=['ou_A,ou_B'],当前结果为 denied。
- 再令两个 allowlist env 都为空:CLI 打印
at least one ... required 后,当前 entrypoint 仍打印 continuing 并进入 [start] exec agent-node。
期望修复 / 验收标准
- Docker env 中的多值语义必须明确且一致:若支持逗号列表,则 trim、丢弃空项、去重并写成真实数组;若改为其他格式,模板 / CLI / entrypoint 必须同步且不能静默误解。
FEISHU_ALLOW_FROM 与 FEISHU_ALLOW_CHATS 至少一个含有效 ID;两者均空或只含逗号 / 空白时 fail-fast,容器非零退出且不启动 agent-node。
- channel-add 的未知 / 真实失败必须透传非零。restart 只能识别并处理可证明的 already-configured 情形,不能 catch-all。
- 重启不得静默覆盖通过受支持方式追加的 allowlist;需定义
.env 与 access.json 的唯一来源或合并 / 幂等语义。
- 覆盖 DM / group 多值、空项、单元素、重启幂等、非 allowlist 错误透传。
- 按仓库规则在独立 Dockerfile 中分层测试并保存报告。
安全边界
只用 dummy ID 与隔离 Docker;不得读取或改写生产 Feishu 配置、PID、凭据,也不得向任何 live 群 / 用户发消息。
文档已在 98f3b7ee 临时收紧为 Docker 每类单 ID,业务修复后再放开。
问题
Docker Feishu 一键启动有两个叠加的静默失败点:
FEISHU_ALLOW_FROM=ou_a,ou_b/FEISHU_ALLOW_CHATS=oc_a,oc_b被整体传给一个 CLI 参数,最终写成单元素数组['ou_a,ou_b'];真实 senderou_a/ chatoc_a永远精确匹配不到。anet channel add feishu的任何非零退出都被 entrypoint 当成 “likely already-added” 吞掉,随后仍然exec agent-node。这包括 allowlist 全空时 CLI 明确拒绝的配置错误,也包括其他真实 channel-add 失败。结果是容器 / agent-node 看起来启动了,但 channel 可能没创建,或所有真实 ID 都被 deny。
代码证据
--allow/--allow-chat;catch-all|| { ... continuing; }吞掉所有失败。[allowOpenId]/[allowChatId]。--allow/--allow-chat至少一个;这个失败会被 entrypoint 吞掉。list.includes(senderId)精确匹配,因此ou_a不会命中['ou_a,ou_b']。另一个数据丢失风险:entrypoint 每次重启都会再次调用 channel add,而 writer 会原子重写
access.json。因此在容器内用anet channel allow追加的 ID,会在下次重启时被.env中的单值覆盖。安全复现(不需要真实飞书 App,不发消息)
ou_A,ou_B,oc_A,oc_B。FEISHU_ALLOW_FROM=ou_A,ou_B,走 entrypoint 的参数构造;检查当前生成值为{"allowFrom":["ou_A,ou_B"]}。senderId='ou_A'和allowFrom=['ou_A,ou_B'],当前结果为 denied。at least one ... required后,当前 entrypoint 仍打印continuing并进入[start] exec agent-node。期望修复 / 验收标准
FEISHU_ALLOW_FROM与FEISHU_ALLOW_CHATS至少一个含有效 ID;两者均空或只含逗号 / 空白时 fail-fast,容器非零退出且不启动 agent-node。.env与access.json的唯一来源或合并 / 幂等语义。安全边界
只用 dummy ID 与隔离 Docker;不得读取或改写生产 Feishu 配置、PID、凭据,也不得向任何 live 群 / 用户发消息。
文档已在 98f3b7ee 临时收紧为 Docker 每类单 ID,业务修复后再放开。