devcontainer-security
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSecured VS Code Dev Containers for Coding Agents
面向编码Agent的安全VS Code开发容器
Set up a hardened VS Code DevContainer that sandboxes coding agents while maintaining full development capability.
搭建一个经过加固的VS Code DevContainer,在沙箱化编码Agent的同时保留完整的开发能力。
When to Use This Skill
适用场景
- Setting up a new DevContainer for coding agent use
- Hardening an existing DevContainer against escape vectors
- Adding git worktree support for parallel development
- Setting up sibling Docker services (databases, emulators)
- Verifying security controls are working
- Setting up Node.js / pnpm in a DevContainer
- 为编码Agent搭建新的DevContainer
- 加固现有DevContainer以防范逃逸向量
- 为并行开发添加git worktree支持
- 配置Docker同级服务(数据库、模拟器)
- 验证安全控制措施是否生效
- 在DevContainer中配置Node.js/pnpm
Threat Model
威胁模型
We're protecting against three things:
- Supply chain attacks - malicious npm packages executing code during install or at runtime
- Prompt injection - malicious content convincing the agent to run harmful commands
- Agent mistakes - unintentional destructive actions
The goal is to limit blast radius, not eliminate all risk.
我们主要防范三类威胁:
- 供应链攻击 - 恶意npm包在安装或运行时执行恶意代码
- 提示注入 - 恶意内容诱导Agent执行有害命令
- Agent误操作 - 无意识的破坏性操作
我们的目标是限制影响范围,而非消除所有风险。
Architecture Overview
架构概述
┌─────────────────────────────────────────────────┐
│ Host Machine │
│ ┌───────────────────────────────────────────┐ │
│ │ Docker Engine │ │
│ │ ┌──────────────┐ ┌──────────────────┐ │ │
│ │ │ docker-proxy │◄─│ claude-code │ │ │
│ │ │ (read-only) │ │ (DevContainer) │ │ │
│ │ └──────┬───────┘ └──────────────────┘ │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ │ │
│ │ │ Docker Socket│ │ │
│ │ └──────────────┘ │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘┌─────────────────────────────────────────────────┐
│ Host Machine │
│ ┌───────────────────────────────────────────┐ │
│ │ Docker Engine │ │
│ │ ┌──────────────┐ ┌──────────────────┐ │ │
│ │ │ docker-proxy │◄─│ claude-code │ │ │
│ │ │ (read-only) │ │ (DevContainer) │ │ │
│ │ └──────┬───────┘ └──────────────────┘ │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ │ │
│ │ │ Docker Socket│ │ │
│ │ └──────────────┘ │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘Security Controls Summary
安全控制措施摘要
| Control | What It Blocks | How |
|---|---|---|
| Docker socket proxy | Container escape | Read-only API proxy (POST=0, EXEC=0) |
| No sudo | Privilege escalation | Not installed in image |
| Drop all capabilities | Kernel attack surface | |
| No new privileges | Setuid/setgid escalation | |
| No SSH keys | Git push / code exfil | Keys not mounted, agent socket deleted |
| VS Code IPC hardening | Host command execution | Three-layer env var + socket cleanup |
| No credential injection | Docker/git credential leaks | VS Code settings disabled |
| 控制措施 | 防护范围 | 实现方式 |
|---|---|---|
| Docker套接字代理 | 容器逃逸 | 只读API代理(POST=0,EXEC=0) |
| 无sudo权限 | 权限提升 | 镜像中不安装sudo |
| 移除所有能力 | 内核攻击面 | 在docker-compose.yml中配置 |
| 禁止新增权限 | Setuid/Setgid权限提升 | 配置 |
| 无SSH密钥 | Git推送/代码泄露 | 不挂载密钥,删除Agent套接字 |
| VS Code IPC加固 | 主机命令执行 | 三层环境变量+套接字清理机制 |
| 无凭证注入 | Docker/Git凭证泄露 | 禁用VS Code相关设置 |
Documentation Index
文档索引
| Document | Contents |
|---|---|
| SECURITY-HARDENING.md | Three-layer defence against VS Code escape vectors, the |
| DOCKER-PROXY.md | Docker socket proxy setup, sibling container communication |
| NODE-SETUP.md | Node.js + pnpm Dockerfile patterns, startup commands |
| WORKTREE-SUPPORT.md | Git worktree support, dynamic container naming, isolated volumes |
| VERIFICATION.md | How to verify security controls, integration testing with devcontainers-cli, automated test scripts |
| 文档 | 内容 |
|---|---|
| SECURITY-HARDENING.md | 针对VS Code逃逸向量的三层防御机制, |
| DOCKER-PROXY.md | Docker套接字代理配置,同级容器通信方法 |
| NODE-SETUP.md | Node.js + pnpm的Dockerfile模板,启动命令配置 |
| WORKTREE-SUPPORT.md | Git worktree支持,动态容器命名,隔离卷配置 |
| VERIFICATION.md | 安全控制验证方法,与devcontainers-cli的集成测试,自动化测试脚本 |
Quick Start — Minimal Secured DevContainer
快速开始 — 极简安全DevContainer
Three files are needed. See each sub-document for detailed explanations.
.devcontainer/devcontainer.jsonjson
{
"name": "Secured Dev Container",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/app",
"remoteUser": "vscode",
"shutdownAction": "stopCompose",
"remoteEnv": {
"SSH_AUTH_SOCK": "",
"GPG_AGENT_INFO": "",
"BROWSER": "",
"VSCODE_IPC_HOOK_CLI": null,
"VSCODE_GIT_IPC_HANDLE": null,
"GIT_ASKPASS": null,
"VSCODE_GIT_ASKPASS_MAIN": null,
"VSCODE_GIT_ASKPASS_NODE": null,
"VSCODE_GIT_ASKPASS_EXTRA_ARGS": null,
"REMOTE_CONTAINERS_IPC": null,
"REMOTE_CONTAINERS_SOCKETS": null,
"REMOTE_CONTAINERS_DISPLAY_SOCK": null,
"WAYLAND_DISPLAY": null
},
// postStartCommand: clean up sockets created before VS Code attaches
"postStartCommand": "find /tmp -maxdepth 2 \\( -name 'vscode-ssh-auth-*.sock' -o -name 'vscode-remote-containers-ipc-*.sock' -o -name 'vscode-remote-containers-*.js' \\) -delete 2>/dev/null || true",
// IPC socket cleanup (vscode-ipc-*.sock, vscode-git-*.sock) is handled by a background
// loop in the Docker Compose command — postAttachCommand is unreliable for background
// processes due to VS Code's cgroup-based lifecycle cleanup. See SECURITY-HARDENING.md.
"customizations": {
"vscode": {
"settings": {
"dev.containers.dockerCredentialHelper": false,
"dev.containers.copyGitConfig": false
}
}
}
}.devcontainer/docker-compose.yml.devcontainer/Dockerfile需要三个文件。详见各子文档的详细说明。
.devcontainer/devcontainer.jsonjson
{
"name": "Secured Dev Container",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/app",
"remoteUser": "vscode",
"shutdownAction": "stopCompose",
"remoteEnv": {
"SSH_AUTH_SOCK": "",
"GPG_AGENT_INFO": "",
"BROWSER": "",
"VSCODE_IPC_HOOK_CLI": null,
"VSCODE_GIT_IPC_HANDLE": null,
"GIT_ASKPASS": null,
"VSCODE_GIT_ASKPASS_MAIN": null,
"VSCODE_GIT_ASKPASS_NODE": null,
"VSCODE_GIT_ASKPASS_EXTRA_ARGS": null,
"REMOTE_CONTAINERS_IPC": null,
"REMOTE_CONTAINERS_SOCKETS": null,
"REMOTE_CONTAINERS_DISPLAY_SOCK": null,
"WAYLAND_DISPLAY": null
},
// postStartCommand: clean up sockets created before VS Code attaches
"postStartCommand": "find /tmp -maxdepth 2 \\( -name 'vscode-ssh-auth-*.sock' -o -name 'vscode-remote-containers-ipc-*.sock' -o -name 'vscode-remote-containers-*.js' \\) -delete 2>/dev/null || true",
// IPC socket cleanup (vscode-ipc-*.sock, vscode-git-*.sock) is handled by a background
// loop in the Docker Compose command — postAttachCommand is unreliable for background
// processes due to VS Code's cgroup-based lifecycle cleanup. See SECURITY-HARDENING.md.
"customizations": {
"vscode": {
"settings": {
"dev.containers.dockerCredentialHelper": false,
"dev.containers.copyGitConfig": false
}
}
}
}.devcontainer/docker-compose.yml.devcontainer/DockerfileAccepted Risks
已接受的风险
These are trade-offs for development usability:
| Risk | Why Accepted |
|---|---|
| Network egress (data exfiltration) | Development requires internet access |
| Workspace write access | Essential for development; git tracks changes |
| Agent credentials readable | Token is revocable; limited blast radius |
| Environment variables (.env) | Development requires env vars, no production keys |
以下是为了开发易用性做出的权衡:
| 风险 | 接受原因 |
|---|---|
| 网络出站(数据泄露) | 开发需要访问互联网 |
| 工作区写入权限 | 开发必备,Git会追踪所有变更 |
| Agent凭证可读取 | 令牌可撤销,影响范围已受限 |
| 环境变量(.env) | 开发需要环境变量,不包含生产密钥 |