You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A Dockerfile.odek in the working directory was built automatically with no
approval gate, while the analogous sandbox_image/sandbox_env project-config
knobs correctly require explicit operator approval. docker build executes
the repo-controlled Dockerfile's RUN instructions outside the sandbox threat
model (default capabilities, entire working directory readable as build
context), so merely running odek inside a malicious repository - including
odek serve, which sandboxes by default - granted host-adjacent code
execution and workspace exfiltration.
Changes:
- approveProjectSandbox now also requires approval for an implicit
Dockerfile.odek build (sandbox active, no explicit image, file present).
The approval is keyed on the Dockerfile content hash, so editing the file
invalidates a prior "trust this project" approval. The prompt warns that
building runs repo-controlled code with the whole working directory as
build context.
- setupSandbox enforces the approval non-interactively at build time
(env bypass, persisted trust, or in-process session approval), closing
the gap where a Dockerfile appears or changes after startup - e.g. a
serve-mode sandbox created per WebSocket connection, or a session
continuation that re-enables the sandbox.
- continueCmd now calls approveProjectSandbox like every other command;
previously odek continue applied project sandbox overrides without any
approval at all.
- docker build runs with --network=none by default so RUN steps cannot
fetch attacker payloads or exfiltrate build-context data over the
network; ODEK_SANDBOX_BUILD_NETWORK=1 (operator-only) opts back in for
legitimate networked builds such as RUN apk add.
Regression tests cover the requirement detection, non-TTY fail-closed
behavior, env bypass, once-vs-trust semantics, content-change invalidation
at both gates, build-time enforcement, and the --network=none default.
Docs updated: SANDBOXING.md, SECURITY.md (new section 18b), CONFIG.md,
AGENTS.md.
-**REPL history file permissions** (`cmd/odek/repl_editor.go`) — `~/.odek/repl_history` is now created/hardened with `0600` permissions (and any existing world-readable file is `chmod`d on the next persist), preventing local users from reading pasted API keys, tokens, and URLs from the REPL history.
160
160
-**Serve sandbox default-on** — `odek serve` enables `--sandbox` automatically unless `--no-sandbox` is passed. Project-requested sandbox overrides from `./odek.json` still require explicit approval via the project sandbox gate.
161
161
-**Project-level sandbox approval** (`cmd/odek/project_sandbox_approval.go`) — `./odek.json` can set `sandbox_env`, `sandbox_image`, `sandbox_network`, and `sandbox_volumes`, but these knobs are not applied until the operator explicitly approves them (`y` = once, `t` = trust this project), or `ODEK_APPROVE_PROJECT_SANDBOX=1` is set for CI/non-interactive use. Persisted approvals live in `~/.odek/project_sandbox_approvals.json` (0600). This closes the C-1 vector where a malicious repo could exfiltrate host secrets via `${VAR}` interpolation in `sandbox_env`, pull an attacker-controlled image, or widen the container's network access.
162
+
-**Implicit Dockerfile.odek build approval** (`cmd/odek/project_sandbox_approval.go` + `internal/sandbox/sandbox.go`) — a `Dockerfile.odek` in the working directory is gated behind the same approval mechanism as project sandbox overrides, because `docker build` runs its repo-controlled `RUN` instructions outside the sandbox threat model with the entire working directory as build context. The approval key includes the Dockerfile content hash (edits force re-approval), `setupSandbox` re-verifies approval non-interactively at build time (closing post-startup introduction/modification, e.g. serve-mode per-connection containers), and builds run with `--network=none` by default (`ODEK_SANDBOX_BUILD_NETWORK=1` opts back in).
162
163
-**Sandbox volume confinement** (`internal/sandbox/sandbox.go`) — extra `--sandbox-volume` host paths must resolve to a location under the working directory, cannot contain `..` or symlink escapes, and cannot match sensitive prefixes such as `/etc`, `/proc`, `/sys`, `/dev`, `/root`, `/home`, `/var`, `/run`, or `/var/run/docker.sock`.
163
164
-**Sandbox read-only enforcement** (`cmd/odek/sandbox_file.go` + `cmd/odek/file_tool.go` + `cmd/odek/perf_tools.go`) — when a sandbox container is active, `write_file`, `patch`, and `batch_patch` translate host paths to `/workspace/...` and copy data into the container with `docker cp`, so a read-only workspace mount (`--sandbox-readonly`) is enforced for the agent's own file tools.
164
165
-**Project config sensitive-field rejection** (`internal/config/loader.go`) — `./odek.json` is untrusted, so `base_url`, `api_key`, `system`, the `dangerous` section, `embedding`, `memory`, `sessions`, `skills.dirs`/`skills.embedding`, `telegram`, and `web_search` set there are ignored (with stderr warnings). Project-level sandbox knobs (`sandbox_env`, `sandbox_image`, `sandbox_network`, `sandbox_volumes`) are not silently ignored either; they are gated by the project-level sandbox approval flow before application. These can only be configured from operator-controlled sources: `~/.odek/config.json`, `ODEK_*` env vars, or CLI flags.
0 commit comments