mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-06-14 03:15:58 +00:00
fix(security): do not bind-mount host CLI auth dirs by default (#3521)
* fix(security): do not bind-mount host CLI auth dirs by default The Compose stack bind-mounted the entire ~/.claude and ~/.codex dirs (read-only) into the root gateway container in every configuration -- exposing not just credentials but full conversation history, per-project session data, and global CLI config. The default OpenAI-compatible model providers and the local sandbox never use them. Move the mounts to an opt-in docker/docker-compose.cli-auth.yaml overlay. Document env-token paths (CLAUDE_CODE_OAUTH_TOKEN, CODEX_AUTH_PATH) in .env.example -- the Gateway credential loader reads env first, so most setups need no mount at all. Document the exposure and per-mode options in SECURITY.md. Reported by @greatmengqi. * docs: clarify ACP adapter auth and add Claude single-file credential option - ACP adapters authenticate independently (many take an env API key like ANTHROPIC_API_KEY and need no mount); the cli-auth overlay is only for adapters that read the full CLI config dir. Avoids steering users toward mounting the whole dir for ACP when env auth usually suffices. - Add CLAUDE_CODE_CREDENTIALS_PATH (single .credentials.json) as a Claude one-file option, matching codex CODEX_AUTH_PATH and the README. * docs: cite claude-code-acp env auth and CLAUDE_CONFIG_DIR in ACP guidance Replace the generic 'some adapters' wording with the verified behavior of the common claude-code-acp adapter (env ANTHROPIC_API_KEY startup + CLAUDE_CONFIG_DIR), so the 'no ~/.claude mount needed for ACP' guidance is backed by a concrete adapter.
This commit is contained in:
@@ -66,3 +66,18 @@ INFOQUEST_API_KEY=your-infoquest-api-key
|
||||
# alias, or behind a different port). docker-compose already sets these.
|
||||
# DEER_FLOW_INTERNAL_GATEWAY_BASE_URL=http://localhost:8001
|
||||
# DEER_FLOW_TRUSTED_ORIGINS=http://localhost:3000,http://localhost:2026
|
||||
|
||||
# ── Claude Code / Codex CLI subscription as a model provider (optional) ───────
|
||||
# If you configure a ClaudeChatModel / Codex model provider (or an ACP agent)
|
||||
# that reuses your CLI subscription login, prefer passing a token via env over
|
||||
# bind-mounting your whole ~/.claude / ~/.codex into the container. The Gateway
|
||||
# credential loader reads these first, so no directory mount is needed.
|
||||
# CLAUDE_CODE_CREDENTIALS_PATH points at a single .credentials.json (Claude)
|
||||
# rather than the whole dir. docker-compose.cli-auth.yaml is the opt-in
|
||||
# directory-mount fallback for adapters that need the full CLI config.
|
||||
# ACP adapters often take their own env API key (e.g. ANTHROPIC_API_KEY) and
|
||||
# need no mount at all — check the adapter's docs. See SECURITY.md.
|
||||
# CLAUDE_CODE_OAUTH_TOKEN=your-claude-code-oauth-token
|
||||
# ANTHROPIC_AUTH_TOKEN=your-anthropic-auth-token
|
||||
# CLAUDE_CODE_CREDENTIALS_PATH=/path/to/.claude/.credentials.json
|
||||
# CODEX_AUTH_PATH=/path/to/codex/auth.json
|
||||
|
||||
+29
@@ -10,3 +10,32 @@ Currently, we have two branches to maintain:
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please go to https://github.com/bytedance/deer-flow/security to report the vulnerability you find.
|
||||
|
||||
## CLI Credential Mounts (Claude Code / Codex)
|
||||
|
||||
DeerFlow can reuse your Claude Code / Codex CLI subscription login as a model
|
||||
provider (`ClaudeChatModel`, the Codex provider) or for ACP agents that run the
|
||||
CLI in-container. The Compose stack used to bind-mount the **entire** `~/.claude`
|
||||
and `~/.codex` directories (read-only) into the gateway container in **every**
|
||||
configuration — exposing not just credentials but full conversation history,
|
||||
per-project session data, and global CLI config. A gateway compromise (prompt
|
||||
injection, tool/MCP misuse, RCE) would leak all of it.
|
||||
|
||||
These directories are **no longer mounted by default**. Supply CLI credentials
|
||||
with the least exposure that fits your setup:
|
||||
|
||||
| Need | How | Exposure |
|
||||
|------|-----|----------|
|
||||
| Claude model provider | env `CLAUDE_CODE_OAUTH_TOKEN` / `ANTHROPIC_AUTH_TOKEN` (via `.env`), or `CLAUDE_CODE_CREDENTIALS_PATH` → a single mounted `.credentials.json` | none / one file |
|
||||
| Codex model provider | env `CODEX_AUTH_PATH` pointing at a single mounted `auth.json` | one file |
|
||||
| ACP agent | the adapter's own auth — many ACP adapters take an env API key (e.g. `ANTHROPIC_API_KEY` / `OPENAI_API_KEY`) and need no mount; use the opt-in `docker/docker-compose.cli-auth.yaml` overlay only if your adapter reads the full CLI config dir | none / full dir |
|
||||
|
||||
The Gateway credential loader checks environment variables **before** the
|
||||
default credential files, so the env-token paths need no bind mount at all. ACP
|
||||
adapters authenticate independently of DeerFlow via their own documented env —
|
||||
for example the common `claude-code-acp` adapter starts as
|
||||
`ANTHROPIC_API_KEY=… claude-code-acp` and honors `CLAUDE_CONFIG_DIR` to redirect
|
||||
its config directory, so it needs no `~/.claude` mount at all. Prefer the
|
||||
adapter's documented env auth, and reach for the
|
||||
`docker-compose.cli-auth.yaml` overlay only as a fallback for an adapter that
|
||||
genuinely reads the full CLI config directory.
|
||||
|
||||
@@ -148,19 +148,12 @@ services:
|
||||
- gateway-uv-cache:/root/.cache/uv
|
||||
# DooD: AioSandboxProvider runs inside the Gateway process.
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
# CLI auth directories for auto-auth (Claude Code + Codex CLI)
|
||||
- type: bind
|
||||
source: ${HOME:?HOME must be set}/.claude
|
||||
target: /root/.claude
|
||||
read_only: true
|
||||
bind:
|
||||
create_host_path: true
|
||||
- type: bind
|
||||
source: ${HOME:?HOME must be set}/.codex
|
||||
target: /root/.codex
|
||||
read_only: true
|
||||
bind:
|
||||
create_host_path: true
|
||||
# CLI auth dirs (Claude Code / Codex) are NOT mounted by default: they
|
||||
# expose the entire ~/.claude and ~/.codex (history, projects, global
|
||||
# config, credentials) into the container. Mount them only when you use
|
||||
# the Claude/Codex CLI login as a model provider or ACP agent, via the
|
||||
# opt-in docker-compose.cli-auth.yaml overlay. Prefer an env token
|
||||
# (CLAUDE_CODE_OAUTH_TOKEN, see .env.example / SECURITY.md).
|
||||
working_dir: /app
|
||||
environment:
|
||||
- CI=true
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# DeerFlow — CLI auth overlay (OPT-IN, NOT loaded by default)
|
||||
#
|
||||
# Bind-mounts the host Claude Code / Codex CLI config dirs into the gateway so:
|
||||
# - ClaudeChatModel / Codex model providers can reuse the CLI subscription
|
||||
# login (~/.claude/.credentials.json, ~/.codex/auth.json), and
|
||||
# - ACP agents (acp_agents in config.yaml) that run the claude/codex CLI
|
||||
# inside the container can read their config.
|
||||
#
|
||||
# SECURITY: these mounts expose the ENTIRE ~/.claude and ~/.codex dirs
|
||||
# (conversation history, projects, global config, long-lived credentials) into
|
||||
# the gateway container, read-only. A gateway compromise leaks all of it. That
|
||||
# is why they are NOT mounted by default.
|
||||
#
|
||||
# Prefer passing only a token via env instead (no directory exposure):
|
||||
# CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_AUTH_TOKEN for Claude, CODEX_AUTH_PATH
|
||||
# for a single Codex auth file — see .env.example and SECURITY.md.
|
||||
# Use this overlay only when you need the full CLI config (e.g. ACP adapters
|
||||
# that run the CLI in-container and read more than just the credential file).
|
||||
#
|
||||
# Manual use (works with both prod and dev compose):
|
||||
# docker compose -f docker-compose.yaml -f docker-compose.cli-auth.yaml up -d
|
||||
services:
|
||||
gateway:
|
||||
volumes:
|
||||
- type: bind
|
||||
source: ${HOME:?HOME must be set}/.claude
|
||||
target: /root/.claude
|
||||
read_only: true
|
||||
bind:
|
||||
create_host_path: true
|
||||
- type: bind
|
||||
source: ${HOME:?HOME must be set}/.codex
|
||||
target: /root/.codex
|
||||
read_only: true
|
||||
bind:
|
||||
create_host_path: true
|
||||
@@ -86,19 +86,12 @@ services:
|
||||
- ${DEER_FLOW_HOME}:/app/backend/.deer-flow
|
||||
# DooD: AioSandboxProvider starts sandbox containers via host Docker daemon
|
||||
- ${DEER_FLOW_DOCKER_SOCKET}:/var/run/docker.sock
|
||||
# CLI auth directories for auto-auth (Claude Code + Codex CLI)
|
||||
- type: bind
|
||||
source: ${HOME:?HOME must be set}/.claude
|
||||
target: /root/.claude
|
||||
read_only: true
|
||||
bind:
|
||||
create_host_path: true
|
||||
- type: bind
|
||||
source: ${HOME:?HOME must be set}/.codex
|
||||
target: /root/.codex
|
||||
read_only: true
|
||||
bind:
|
||||
create_host_path: true
|
||||
# CLI auth dirs (Claude Code / Codex) are NOT mounted by default: they
|
||||
# expose the entire ~/.claude and ~/.codex (history, projects, global
|
||||
# config, credentials) into the container. Mount them only when you use
|
||||
# the Claude/Codex CLI login as a model provider or ACP agent, via the
|
||||
# opt-in docker-compose.cli-auth.yaml overlay. Prefer an env token
|
||||
# (CLAUDE_CODE_OAUTH_TOKEN, see .env.example / SECURITY.md).
|
||||
working_dir: /app
|
||||
environment:
|
||||
- CI=true
|
||||
|
||||
Reference in New Issue
Block a user