CodeDojo runs commands from repositories that may be unfamiliar or intentionally broken. Treat every practice repository as untrusted code.
The MVP includes two sandbox drivers:
- Docker driver: preferred when Docker is reachable
- Local driver: development fallback only, not a security boundary
CodeDojo tries to reduce risk from:
- test commands that execute arbitrary code
- build scripts or package hooks inside practice repositories
- malicious or accidental filesystem writes during a session
- runaway CPU, memory, process, or time usage
- network access from sandboxed commands
- coach responses that reveal implementation details
CodeDojo does not currently defend against:
- Docker daemon compromise
- kernel or container runtime vulnerabilities
- malicious code run through the local driver
- malicious repositories exploiting the host Git client during clone/open
- denial of service against the host outside configured Docker limits
- secrets already present in the repository copy
When Docker is reachable, CLI flows use internal/sandbox/docker.
The Docker driver:
- copies the selected repository into a temporary workspace
- starts a long-running container from
codedojo/go:1.23by default - uses
/workspaceas the working directory - mounts only the temporary workspace read-write
- sets the container root filesystem read-only
- drops all Linux capabilities
- sets
no-new-privileges - disables networking for the default
NetworkNonepolicy - applies memory, CPU, and PID limits from
sandbox.Spec - sets
HOME,TMPDIR,GOCACHE, andGOMODCACHEinside/workspace - removes the container and temporary workspace on close
This is the expected mode for running untrusted practice repositories.
Docker isolation is still shared-kernel isolation. It depends on:
- a correctly configured Docker daemon
- host kernel and container runtime security
- the configured image not containing unexpected privileged tooling
- the user not mounting sensitive host paths into the workspace
Do not run CodeDojo against hostile repositories on a machine that holds sensitive credentials unless you understand and accept the Docker risk.
When Docker is unavailable, CodeDojo falls back to internal/sandbox/local and prints a warning.
The local driver:
- copies the repository into a temporary directory
- runs commands directly on the host with
exec.CommandContext - does not enforce network policy
- does not enforce CPU limits
- does not enforce memory limits
- does not isolate processes beyond normal OS user permissions
- removes the temporary directory on close
The local driver is for development, tests, and trusted repositories only. It does not prevent arbitrary code from reading environment variables, accessing the network, writing outside the workspace, spawning child processes, or using host credentials available to the current user.
CodeDojo avoids modifying the original local repository path. repo.OpenLocal copies the source repository into a temporary directory before task generation. Sandbox drivers then copy that working tree again into their own temporary workspace.
Sandbox ReadFile and WriteFile methods reject non-local paths using filepath.IsLocal, so direct REPL file operations cannot use absolute paths or .. escapes. This guard applies to CodeDojo file helper methods, not to arbitrary commands run inside the sandbox.
Repository copy rejects symlinks that resolve outside the source repository. Symlinks that resolve inside the source repository are copied as relative links pointing at the copied target.
The web repository browser is stricter during selection. It labels symlinked directories but does not traverse them, and direct browse requests to a symlink path are rejected. Choose the symlink's real target path when you intentionally want that repository.
The .codedojo/ directory is reserved for CodeDojo runtime metadata in practice copies. Do not store project configuration there; use the root-level .codedojo.yaml file for repository overrides.
The default CLI sandbox spec uses NetworkNone.
In Docker mode, this maps to Docker networking disabled / none.
In local mode, network policy is logged but not enforced. Commands run by the local driver can use the host network.
NetworkRestricted currently maps to none in Docker mode. There is no allowlist-based restricted network implementation yet.
The Docker driver applies:
- memory limit
- memory swap equal to memory limit
- CPU quota through NanoCPUs
- PID limit
- command timeout
The local driver only respects command context cancellation. It does not enforce memory, CPU, or PID limits.
Avoid placing secrets in practice repositories. CodeDojo copies the repository contents into temporary workspaces, and commands may read files available inside those copies.
Coach backend secrets:
- Anthropic uses the config API key or
ANTHROPIC_API_KEY - Anthropic model selection is read from
coach.modelin config; the built-in default is a dated snapshot model ID. - Ollama can use
coach.model,OLLAMA_MODEL, andOLLAMA_BASE_URL
Remote repository authentication:
- CLI
reviewandlearncommands use standard environment auth hints, includingGITHUB_TOKEN,GIT_ASKPASS, and discovered local SSH keys. codedojo serveaccepts pasted Git URLs and?repo=links in the web UI. The browser must use Open in CodeDojo before the server clones and inspects a remote repository.- Sensei packs are local JSON manifests that point back to a source repository path or URL and include saved source snapshots. Only open packs from trusted teammates, because starting a Sensei kata clones or copies that source and runs its configured tests in the selected sandbox.
codedojo servedoes not use discovered SSH keys for web-submitted clone URLs unless started with--allow-ssh.- Prefer HTTPS URLs with scoped tokens for web UI use. Use
--allow-sshonly when you trust local browser access to the server.
Docker sandbox commands do not receive arbitrary host environment variables by default; the driver sets a small workspace-specific environment. Local sandbox commands inherit the process environment through Go's default command behavior when no explicit environment is set, so local mode can expose host environment variables to untrusted commands.
Coach hints are wrapped by coach.RetryWithStricterPrompt.
The validator rejects:
- fenced code blocks with more than three non-empty lines
- function or method definitions in supported languages
- task-specific banned identifiers
This protects the learning loop from accidental solution leaks. It is not a security control for executing untrusted code.
For trusted local development:
./bin/codedojo review --repo testdata/sample-go-repoFor unfamiliar repositories:
make images
./bin/codedojo review --repo <repo-url-or-copy>Confirm Docker is available before starting. If CodeDojo prints a local fallback warning, stop and fix Docker before using an untrusted repository.
Until a formal security policy is added, do not file public issues for exploitable vulnerabilities. Contact the repository maintainer privately, include reproduction steps, and describe whether the issue affects Docker mode, local mode, coach output, or repository handling.
Known follow-up work:
- document a formal private vulnerability reporting address before public launch
- make local mode opt-in for non-test CLI use
- add image provenance and digest pinning for sandbox images
- add optional Docker seccomp/AppArmor profiles
- add allowlist-based restricted networking if
NetworkRestrictedis exposed to users - scrub or explicitly set the environment for local sandbox commands