DeerFlow 的 Docker 认证测试缺口:TC-DOCKER-01..06 为何未执行、等价覆盖在哪里,以及如何复现
发布时间:2026/9/7 2:42:51 锦皓数字建站

DeerFlow 的 Docker 认证测试缺口TC-DOCKER-01..06 为何未执行、等价覆盖在哪里以及如何复现【免费下载链接】deer-flowAn open-source long-horizon SuperAgent harness that researches, codes, and creates. With the help of sandboxes, memories, tools, skill, subagents and message gateway, it handles different levels of tasks that could take minutes to hours.项目地址: https://gitcode.com/GitHub_Trending/de/deer-flow本文以 Docker Test Gap 为核心讲解 DeerFlow 认证Auth模块在完整发版验证后唯一未执行的 6 个容器运行时测试用例TC-DOCKER-01..06的成因、每个用例的认证行为为何已被非 Docker 测试等价覆盖以及当环境具备 Docker 时如何按 测试计划 原样复现这些用例。读完后你可以掌握如何为一个“环境不可用导致的测试缺口”建立可追溯的等价覆盖映射以及AUTH_JWT_SECRET、DEER_FLOW_HOME卷挂载、多 Worker 限速器等容器细节背后的源码实现。一、缺口从何而来sg_dev 环境没有 Docker 守护进程DeerFlow 的认证模块有一份完整的测试计划 AUTH_TEST_PLAN.md其中第七节 7.4 专门定义了 Docker 部署模式./scripts/deploy.sh docker/docker-compose.yaml下的 6 个用例 TC-DOCKER-01..06。发版验证阶段除这 6 个用例外的所有测试章节都在两类环境上跑完了本地开发机Mac所有服务本地运行已部署的 sg_dev 实例10.251.229.92gateway frontend nginx 经 SSH 隧道访问。而 sg_dev 上没有安装 Docker 守护进程缺口文档中保留了当时的取证命令$ ssh sg_dev which docker; docker --version # (empty) # bash: docker: command not foundTC-DOCKER 用例属于“容器运行时行为”测试需要真正的 Docker 引擎来拉起docker/docker-compose.yaml中的服务因此在 sg_dev 上无法执行。这份文档的作用就是显式登记这唯一的未执行部分而不是含糊地宣布“全部通过”。二、未执行的 6 个用例覆盖点与无法执行的原因完整继承缺口文档中的用例登记表用例标题覆盖内容未执行原因TC-DOCKER-01deerflow.db卷持久化验证DEER_FLOW_HOMEbind mount 在容器重启后仍然存活需要docker compose upTC-DOCKER-02容器重启后会话保持AUTH_JWT_SECRET环境变量使 cookie 在docker compose down up之后依然有效需要docker compose down/upTC-DOCKER-03每 Worker 限速器状态分歧确认进程内_login_attempts字典在多个gunicornworker 之间不共享状态缺口文档写作时 compose 文件默认 4 workers已知限制已文档化需要多 worker 容器TC-DOCKER-04IM 渠道使用内部 Gateway 认证验证 Feishu/Slack/Telegram 分发器调用 Gateway 兼容的 LangGraph API 时附带进程内本地内部认证头与 CSRF cookie/header需要docker logsTC-DOCKER-05重置凭据的外露方式reset_admin在DEER_FLOW_HOME下写入 0600 权限的凭据文件而非打印明文基于文件的行为已由非 Docker 重置测试验证唯一的 Docker 专属缺口是确认卷挂载能把该文件带到宿主机需要容器 宿主机卷TC-DOCKER-06Docker 部署使用 Gateway 内嵌运行时./scripts/deploy.sh产出 Gateway frontend nginx 拓扑无独立langgraph容器认证流程与本地make dev相同需要docker compose up这 6 个用例的完整命令与预期结果写在测试计划 7.4 节例如 TC-DOCKER-01 要求在容器启动后注册用户再到宿主机${DEER_FLOW_HOME:-backend/.deer-flow}/data/deerflow.db用sqlite3查到该用户TC-DOCKER-02 则验证带AUTH_JWT_SECRET时旧 cookie 重启后仍返回 200。三、每个 Docker 用例的认证行为已被谁覆盖缺口文档的核心结论是每个 Docker 用例中“与认证相关”的行为都已经有在 sg_dev 或本地跑过的等价用例覆盖未执行的只是容器打包bind mount、多 worker、日志收集这一层。完整映射表如下Docker 用例认证行为由谁覆盖TC-DOCKER-01卷持久化sg_dev 上的 TC-REENT-01admin 行在 gateway 重启后仍存在——同一个 SQLite 文件只是中间少了容器层TC-DOCKER-02会话持久化TC-API-02/03/06cookie 往返加上 TC-REENT-04多 cookie——JWT 校验是无进程状态的容器重启等价于pkill uvicorn uv run uvicornTC-DOCKER-03每 worker 限速TC-GW-04 TC-REENT-09单 worker 限速 5 分钟过期。跨 worker 分歧是内存字典这一架构属性没有任何认证代码路径存在差异TC-DOCKER-04IM 渠道内部认证代码级证据app/channels/manager.py创建langgraph_sdk客户端时附带create_internal_auth_headers()与 CSRF cookie/header渠道 worker 不依赖浏览器 cookieTC-DOCKER-05凭据外露reset_admin以 0600 模式写.deer-flow/admin_initial_credentials.txt且只记录路径——唯一的 Docker 专属步骤是 bind mount 是否把该路径投射到宿主机这是 compose 配置检查不是运行时行为差异TC-DOCKER-06Gateway 内嵌运行时容器测试计划 7.2 节TC-GW-01..05 第二节sg_dev 上的 Gateway 认证流程——同一份 Gateway 代码容器只是打包方式变化下面结合仓库源码验证上表中几个关键论断的实际实现。3.1 IM 渠道的内部认证TC-DOCKER-04backend/app/channels/manager.py 在构建 LangGraph SDK 客户端时同时导入了内部认证头与 CSRF 常量from app.gateway.csrf_middleware import CSRF_COOKIE_NAME, CSRF_HEADER_NAME, generate_csrf_token from app.gateway.internal_auth import create_internal_auth_headers对应的实现位于 backend/app/gateway/internal_auth.py。这与缺口文档的表述一致渠道分发器走“进程内本地”的内部认证头 匹配的 CSRF cookie/header 调用 Gateway 兼容 API而不是依赖浏览器 cookie。因此在裸金属环境做代码级验证即可覆盖其认证语义Docker 化只是多了一个docker logs的观测手段。3.2 reset_admin 的 0600 凭据文件TC-DOCKER-05backend/app/gateway/auth/reset_admin.py 的模块文档明确说明新密码写入.deer-flow/admin_initial_credentials.txtmode 0600而不是打印出来“让 CI / 日志聚合器永远看不到明文密钥”。其成功路径的输出与测试计划中的grep预期逐字对应print(fCredentials written to: {cred_path} (mode 0600))底层文件写入由 backend/app/gateway/auth/credential_file.py 完成文件以os.open(..., 0o600)原子创建保证密码即使在“写入与 chmod 之间”的单系统调用窗口内也绝不被全局可读。这正是测试计划 TC-DOCKER-05 中“日志只出现路径、grep -iE Password: .{15,}应当无匹配”预期的实现依据。3.3 进程内限速器与多 Worker 分歧TC-DOCKER-03backend/app/gateway/routers/auth.py 中登录限速的核心状态就是一个模块级字典注释直接写出了多 worker 的限制# In-process dict — not shared across workers. # # **Limitation**: with multi-worker deployments (e.g., gunicorn -w N), each # worker maintains its own lockout table, so an attacker effectively gets # N × max_login_attempts guesses before being locked out everywhere. ... _login_attempts: dict[str, tuple[int, float, float]] {}阈值与锁定时长来自auth.local配置每次调用实时读取默认值定义在 backend/packages/harness/deerflow/config/auth_config.pymax_login_attempts默认 5最小 2、lockout_seconds默认 300。backend/tests/test_auth.py 中的test_rate_limiter_blocks_after_max_failures、test_rate_limiter_resets_on_success等单测钉死了单 worker 语义而跨 worker 不共享状态是这段代码的结构属性因此在 sg_dev 单 worker 环境验证过单 worker 行为 源码级确认状态存储位置即构成缺口文档所说的等价覆盖。一个值得注意的源码演进细节缺口文档提到“compose 文件默认 4 workers”而当前 docker/docker-compose.yaml 中 gateway 的启动命令为uvicorn app.gateway.app:app ... --workers ${GATEWAY_WORKERS:-1}即当前默认单 worker仅在启用 Redis stream bridge 且接受各 worker 本地化限制run 取消、请求去重、每 worker IM 渠道服务时才通过GATEWAY_WORKERS覆盖。从源码结构看这一默认值收敛并不改变 TC-DOCKER-03 的结论——分歧风险依然存在且随 worker 数线性放大只是默认拓扑下不再暴露多 worker 部署如需精确限速源码注释建议替换为 Redis 等共享存储。3.4 AUTH_JWT_SECRET 与会话持久化TC-DOCKER-02JWT 密钥的加载逻辑在 backend/app/gateway/auth/config.py优先读环境变量AUTH_JWT_SECRET未设置时调用_load_or_create_secret()——从{base_dir}/.jwt_secret读取已持久化的密钥读不到则用secrets.token_urlsafe(32)生成一个并以 0600 权限写回该文件同时打印告警提示生产环境应显式配置。这里可以推断一个对复现 TC-DOCKER-02 有实际影响的细节{base_dir}位于DEER_FLOW_HOMEcompose 中为/app/backend/.deer-flowbind mount 自宿主机${DEER_FLOW_HOME}因此即使不设置AUTH_JWT_SECRET只要docker compose down up不删除宿主机数据目录自动生成的密钥仍可从.jwt_secret文件读回旧 cookie 大概率继续有效只有在卷/宿主机目录被清掉时才回到测试计划描述的“每次启动新临时密钥、旧 JWT 签名失效 → 401”场景。缺口文档把“显式设置AUTH_JWT_SECRET”列为 Docker 复现的前置条件这在多副本、多实例共享同一数据库的场景下依然是更稳妥的做法。3.5 卷挂载与 Gateway 内嵌运行时拓扑TC-DOCKER-01/06docker/docker-compose.yaml 中 gateway 服务的关键挂载与变量volumes: - ${DEER_FLOW_CONFIG_PATH}:/app/backend/config.yaml:ro - ${DEER_FLOW_EXTENSIONS_CONFIG_PATH}:/app/backend/extensions_config.json - ../skills:/app/skills:ro - ${DEER_FLOW_HOME}:/app/backend/.deer-flow environment: - DEER_FLOW_HOME/app/backend/.deer-flowDEER_FLOW_HOME这一行 bind mount 正是 TC-DOCKER-01 要验证的对象容器内deerflow.db以及.jwt_secret、admin_initial_credentials.txt全部落在宿主机目录容器重启/重建不丢数据。而整个 compose 文件的服务集合只有 nginx、frontend、gateway、redis外加可选 provisioner不存在独立的langgraph容器——即测试计划 7.4 前置说明所指的“runtime 嵌入 gateway 容器”拓扑./scripts/deploy.sh产出的就是这套 Gateway frontend nginx 结构认证流程与本地make dev完全同源这支撑了 TC-DOCKER-06 由 TC-GW-01..05 等价覆盖的论断。四、复现步骤当 Docker 可用时如何补齐缺口缺口文档给出了原样复现的前置条件与命令。任何安装了dockerdocker compose的机器都可以执行# 宿主机前置要求 docker --version # 24.x docker compose version # plugin 2.x # 必需的环境变量否则每次容器重启 session 全部重置 echo AUTH_JWT_SECRET$(python3 -c import secrets; print(secrets.token_urlsafe(32))) \ .env # 可选把 DEER_FLOW_HOME 固定到一个稳定的宿主机路径 echo DEER_FLOW_HOME$HOME/deer-flow-data .env然后按 AUTH_TEST_PLAN.md 7.4 节 原样运行 TC-DOCKER-01..06。摘出其中两个最具代表性的用例作为示例TC-DOCKER-01卷持久化./scripts/deploy.sh启动后注册用户再回宿主机校验sleep 15 BASEhttp://localhost:2026 curl -s -X POST $BASE/api/v1/auth/register \ -H Content-Type: application/json \ -d {email:docker-testexample.com,password:DockerTest1!} -w \nHTTP %{http_code} ls -la ${DEER_FLOW_HOME:-backend/.deer-flow}/data/deerflow.db sqlite3 ${DEER_FLOW_HOME:-backend/.deer-flow}/data/deerflow.db \ SELECT email FROM users WHERE emaildocker-testexample.com;TC-DOCKER-02重启后会话保持登录拿 cookie → 确认/auth/me返回 200 →./scripts/deploy.sh down ./scripts/deploy.sh重启 → 用旧 cookie 再访问/auth/me有AUTH_JWT_SECRET预期 200。其余 TC-DOCKER-0320 次错密码观察 429 触发点、TC-DOCKER-04docker logs deer-flow-gateway查渠道日志无 auth 错误、TC-DOCKER-05docker exec deer-flow-gateway python -m app.gateway.auth.reset_admin后在宿主机DEER_FLOW_HOME下确认 0600 凭据文件、日志仅出现路径、TC-DOCKER-06确认deer-flow-gateway容器存在且未登录访问/api/models返回 401的完整命令均在测试计划 7.4 节 中逐条给出。五、决策记录缺口为何不阻塞发版缺口文档末尾的决策日志给出了两条明确结论值得作为发布实践参考不阻塞发版Not blocking the release。每个 Docker 用例中与认证相关的行为在裸金属上都有已验证的等价物缺口纯粹位于容器打包细节bind mounts、多 worker、日志收集层面而不是认证代码路径是否工作的问题。TC-DOCKER-05 已在 AUTH_TEST_PLAN.md 中就地更新以反映当前重置流程reset_admin→ 0600 凭据文件、日志无泄露。旧的“在 docker logs 里 grep Password:”式预期会静默失败并给出虚假的覆盖感——文档同步修订避免陈旧断言长期误导测试执行者。六、小结容器测试缺口的可复用处理模式回到 Docker Test Gap 这份文档本身它示范了一套可复用的模式显式登记环境能力缺失无 Docker 守护进程不隐瞒、不降格单独成文并保留取证命令逐条等价映射每个未执行用例都能指出“认证行为由哪个已执行用例覆盖 剩余差异属于哪一层容器打包”源码级佐证等价性不靠口头断言而是指向internal_auth、credential_file、_login_attempts等具体实现位置读者可自行核对可复现出口给出前置条件Docker 版本、AUTH_JWT_SECRET、DEER_FLOW_HOME与执行入口测试计划章节任何有 Docker 的机器都能把缺口补回完整。认证模块的其余测试面接口流程、攻击测试、可重入、升级、红队对抗、回归清单见 AUTH_TEST_PLAN.md认证机制设计背景见 AUTH_DESIGN.md。【免费下载链接】deer-flowAn open-source long-horizon SuperAgent harness that researches, codes, and creates. With the help of sandboxes, memories, tools, skill, subagents and message gateway, it handles different levels of tasks that could take minutes to hours.项目地址: https://gitcode.com/GitHub_Trending/de/deer-flow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。