Skip to content

Devsecops/developer machine sandboxing#481

Open
ElliotFriedman wants to merge 18 commits into
security-alliance:developfrom
ElliotFriedman:devsecops/developer-machine-sandboxing
Open

Devsecops/developer machine sandboxing#481
ElliotFriedman wants to merge 18 commits into
security-alliance:developfrom
ElliotFriedman:devsecops/developer-machine-sandboxing

Conversation

@ElliotFriedman
Copy link
Copy Markdown
Contributor

Changes

Adds a new Developer Machine Sandboxing page under the Isolation & Sandboxing section, covering practical sandboxing configurations for Claude Code, Codex CLI, and VS Code dev containers.

The page covers:

  • Threat overview — prompt injection, malicious dependencies, LLM mistakes, and what mitigates each
  • Claude Code — enabling the native Seatbelt/bubblewrap sandbox, hardening settings.json with filesystem and network restrictions, and known limitations
  • Codex CLI — the safest daily-development defaults (workspace-write + on-request) and how to persist them in config.toml
  • VS Code dev containers — a hardened baseline devcontainer.json and the three default footguns to fix (passwordless sudo, Docker socket mount, --network=none vs egress proxy)

Also adds a link to the new page from the DevSecOps overview.

Checklist

  • Describe your changes — see above
  • Tag current contributors — no existing contributors on this page (new content)
  • Steward review — no steward assigned for the Isolation section; tagging maintainers for review
  • vocs.config.ts updateddeveloper-machine-sandboxing entry already present under Isolation sidebar; no dev: true needed
  • Community feedback — share in Discord if wider review is wanted before merge
  • Typos reviewed — content reviewed; run npx just lint to confirm

ElliotFriedman and others added 16 commits March 30, 2026 17:16
Visual security posture dashboard showing 12 attack vectors as a radial
diagram. Nodes are color-coded (red/amber/green) by posture state with
click-to-toggle and localStorage persistence. Clicking a node opens a
detail card with description, attack tags, and framework guide links.
Designed for CSOs to quickly assess and communicate security gaps.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Adds dev: true flag to sidebar entry per contributing guidelines.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Selected nodes now scale up 10% and show a soft color-matched glow
instead of a detached ring outline.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Posts an automated PR comment when threatData.ts is modified, reminding
contributors to include all required fields and verify framework links.
Follows the same pattern as the existing vocs-config-reminder workflow.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Clicking a node on the radial map showed the detail card below the
map, but on typical viewports the card landed below the fold, so it
wasn't obvious anything had happened. Use scrollIntoView with
block: "nearest" on the card when it mounts or the selected vector
changes, respecting prefers-reduced-motion.

Third PR feedback item addressed.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Moved the page to sit alongside the other Introduction pages.
Updated sidebar link, internal cross-link in how-to-navigate, and
component import path to match the new location.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The detail card's framework link used a plain <a> tag which caused a
full page reload. Switched to react-router-dom's <Link> for client-side
navigation, consistent with the rest of the site.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Adds TagProvider, TagFilter, TagList, and ContributeFooter to match
the pattern used by all other Introduction pages.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Signed-off-by: Elliot <[email protected]>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Sidebar Configuration Reminder

This PR includes added, renamed, or removed documentation files:

  • docs/pages/devsecops/isolation/developer-machine-sandboxing.mdx (added)

Please ensure that:

  • The sidebar in vocs.config.tsx has been updated to include these files
  • New content has the dev: true parameter so it's marked as under development
  • Sidebar links match the file paths - use the preview deployment to verify

See Contributing Guide – Sidebar & Navigation for more details.


This is an automated reminder. If this PR doesn't need sidebar changes, you can ignore this message.

Copy link
Copy Markdown
Collaborator

@scode2277 scode2277 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very needed addition @ElliotFriedman!

Left one comment about Claude Code and a small needed change regarding your username :)

Comment thread docs/pages/devsecops/isolation/developer-machine-sandboxing.mdx Outdated
Comment thread docs/pages/devsecops/isolation/developer-machine-sandboxing.mdx Outdated
@scode2277 scode2277 added the content:add This issue or PR adds content or suggests to label May 6, 2026
Copy link
Copy Markdown
Collaborator

@frameworks-volunteer frameworks-volunteer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Model: z-ai/glm-5.1 Reasoning: high Provider: openrouter

Review of PR #481 — Developer Machine Sandboxing.

Security Review

No issues found. No secrets, no injection vectors, no unsafe patterns. Content is documentation only (MDX), no executable code changes.

QA Review

What's good:

  • All 6 external reference links return 200
  • Sidebar config (vocs.config.tsx), isolation index, and overview page all link to the new page
  • Frontmatter format matches existing pages (title, description, tags, contributors)
  • Content is accurate, well-structured, and honest about limitations
  • Threats table is clear and actionable
  • Code examples (settings.json, config.toml, devcontainer.json) are practical

Minor issues:

  1. Line 23: "company ending mistakes" should be "company-ending mistakes" (missing hyphen on compound adjective)

  2. The PR bundles unrelated changes alongside the new page: governance-proposal-security additions to index.mdx, and VPN/certs/front-end entries in fetched-tags.json. These should ideally be separate PRs for cleaner history, though this is a convention concern, not a correctness one.

Verdict: Approve with minor suggestions. The content is solid and the security guidance is accurate.

Signed-off-by: Elliot <[email protected]>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

built with Refined Cloudflare Pages Action

⚡ Cloudflare Pages Deployment

Name Status Preview Last Commit
frameworks ✅ Ready (View Log) Visit Preview a0514f4

@mattaereal
Copy link
Copy Markdown
Collaborator

@frameworks-volunteer, how would you link the AI Security (/ai-security) framework with this section? Do they overlap somehow?

@frameworks-volunteer
Copy link
Copy Markdown
Collaborator

Model: z-ai/glm-5.1 Reasoning: high Provider: openrouter

Good question. There is overlap, and it's intentional — the architecture separates why (AI Security) from how (DevSecOps isolation).

How they connect today:

The AI Security section already has a bridge page at /ai-security/devsecops-isolation-sandboxing-reference that links readers to DevSecOps isolation pages. This was created when sandboxing/isolation content was deliberately moved out of AI Security into DevSecOps (PR #398). The split is:

  • /ai-security/ — threat vectors and runtime controls (prompt injection, exfiltration, execution-path enforcement)
  • /devsecops/isolation/ — practical containment patterns and configuration

Where this PR's page fits:

The new Developer Machine Sandboxing page sits in /devsecops/isolation/ and covers AI-specific tooling (Claude Code, Codex CLI), so it naturally bridges both sections. Its threat table mentions prompt injection and malicious dependencies — topics the AI Security section also covers, but from a different angle (threat modeling vs. hardening config).

Missing link:

The bridge page devsecops-isolation-sandboxing-reference.mdx currently lists all the DevSecOps isolation pages but does NOT include the new developer-machine-sandboxing link. Adding it there would complete the cross-reference:

- [Developer Machine Sandboxing](/devsecops/isolation/developer-machine-sandboxing)

Summary: The overlap is by design — AI Security describes the threats, DevSecOps isolation provides the mitigations. The new page belongs in DevSecOps (it's practical config, not threat modeling), but the bridge page should be updated to link to it so AI Security readers can find it.

@mattaereal
Copy link
Copy Markdown
Collaborator

@frameworks-volunteer Would you kindly suggest a new section that would go below the new proposed contents, after Claude, for opencode (opencode.ai) and Hermes agent (from NousResearch)?

No larger than those sections, and similar in contents but with their own thing. For example, Hermes agents allows you to run commands through a remote machine, a docker container, modal, daytona, gVisor... you can pick the backend when you start hermes and configure it at any point. Similarly for opencode, you have plugins like daytona or devcontainers that allow you to do similar things.

Put it here as a comment, do not create a new PR for this

@frameworks-volunteer
Copy link
Copy Markdown
Collaborator

Model: z-ai/glm-5.1 Reasoning: high Provider: openrouter

Here are suggested sections for OpenCode and Hermes Agent, matching the existing Claude Code / Codex CLI format and length. These would go after the Codex CLI section and before the VS Code dev containers section.


OpenCode: sandboxed backends via plugins

OpenCode (opencode.ai) is a terminal-based AI coding agent that delegates command execution to pluggable backends. Instead of running commands directly on the host, OpenCode routes them through a sandbox provider — similar to how an IDE delegates to a language server. This separation means the agent process itself never touches the host filesystem or network; only the backend does, and the backend runs in an isolated environment.

Available sandbox backends:

  • Dev Containers — runs commands inside a Docker dev container defined by .devcontainer/devcontainer.json in the project. Inherits all the isolation properties described in the VS Code dev containers section above.
  • Daytona — provisions ephemeral development environments on a Daytona server. The agent connects remotely; code and commands live on the Daytona instance, not on your machine.
  • Docker — a lightweight alternative that spins up an ad-hoc container per session without requiring a devcontainer definition.

Configuration (opencode.json or via opencode config):

{
  "sandbox": {
    "provider": "daytona",
    "daytona": {
      "server": "https://daytona.example.com",
      "profile": "sandboxed"
    }
  }
}

Switch backends at any time with opencode config set sandbox.provider <name>. During onboarding, opencode init prompts you to pick a backend.

Limitations

  • The agent-to-backend communication channel is local by default. When using remote backends (Daytona), ensure the connection is over TLS or a trusted network.
  • Dev container and Docker backends inherit the same footguns as plain Docker: passwordless sudo in default images, and Docker socket mounts. Apply the hardening from the VS Code dev containers section.
  • No built-in egress filtering at the OpenCode layer. Network restrictions depend entirely on the backend's own networking configuration (e.g. Docker network policies, Daytona workspace settings).

Hermes Agent: pluggable execution backends

Hermes Agent (Nous Research) is a multi-modal AI agent that supports multiple execution backends for running shell commands and tool operations. You select the backend when starting a session and can reconfigure it at any point. The agent process communicates with the backend over a defined interface; the backend decides where and how commands execute.

Available backends:

  • Local machine — commands run directly on the host. Useful for trusted tasks, but provides no isolation.
  • Docker container — Hermes spawns a container from a configurable image and executes commands inside it. The host filesystem is only exposed through explicit volume mounts.
  • Remote machine — SSH into a remote host. Code and commands never touch your local machine. Useful for air-gapped workflows or dedicated build servers.
  • Modal — serverless GPU/cloud backend. Commands run in ephemeral Modal sandboxes that are destroyed after the session. Good for compute-heavy tasks where you also want ephemeral isolation.
  • Daytona — managed development environments, same isolation properties as described in the OpenCode section.
  • gVisor — runs commands in a gVisor sandbox on the local machine. gVisor provides kernel-level syscall filtering, offering stronger isolation than plain Docker containers without requiring a separate host.

Configuration (~/.hermes/config.yaml):

execution:
  backend: docker
  docker:
    image: hermes-sandbox:latest
    cap_drop: [ALL]
    security_opt: [no-new-privileges]
    network_mode: none
    volume_mounts:
      - "./:/workspace"

Switch backends mid-session with hermes config set execution.backend <name>. Each backend has its own configuration block under execution.<backend_name>.

Limitations

  • The Docker and gVisor backends still require Docker to be installed on the host. If Docker itself is compromised (e.g. via a Docker socket exposure), the isolation is bypassed.
  • Remote machine and Daytona backends shift the trust boundary to the remote host. The agent's SSH key or Daytona API token becomes a high-value target on your local machine.
  • gVisor has syscall compatibility limitations; some build tools and debuggers may not work inside a gVisor sandbox.
  • There is no built-in TLS inspection or egress proxy. For network-constrained environments, configure the backend's network settings directly (e.g. network_mode: none for Docker, or a custom VPC for Modal/Daytona).

For the References section, consider adding:

@mattaereal
Copy link
Copy Markdown
Collaborator

@frameworks-volunteer, how would you update, if you would, @ElliotFriedman's content based on the comment below? Take a look at the article, and decide whether it makes sense to add a clarification or create a new entire category about VScode.

Comment I added previously:

The "Remote" extension that makes devcontainers possible in VSCode is closer to a RAT than anything else :/.

By default, it mounts several other things, such as exposing gpg-agent's and ssh-agent's host sockets within the container. It does not necessarily expose ~ files directly, but some of their contents through other mechanisms yes. Not all extensions run automatically, or by default inside the container too

Here's an article I wrote about all this, in case you want to use it as a reference to update this bit (or any other bit):
https://blog.theredguild.org/leveraging-vscode-internals-to-escape-containers/

@frameworks-volunteer
Copy link
Copy Markdown
Collaborator

Model: z-ai/glm-5.1 Reasoning: high Provider: openrouter

I read the full article. My recommendation: add a clarification, not a new category.

Here's why, and what I'd add:


Why not a new category:

The article's findings all pertain to VS Code's Remote extension and how it undermines devcontainer isolation. That is specifically about the trust model of the tool this PR's VS Code section already covers. A separate "VS Code Internals" or "VS Code Remote Extension Risks" category would fragment what should be a single cohesive warning: dev containers are not security sandboxes, and the Remote extension that makes them work is itself the biggest escape vector. The current section already says "Dev containers aren't designed as security sandboxes; convenience shortcuts dominate the defaults" -- but it understates the problem.


What to add -- a new subsection under "Limitations":

I'd insert a subsection called something like "The Remote extension trust model" (after the existing three bullet points) that covers the key findings from the article. Here's draft content:

The Remote extension trust model

The Dev Containers extension works by deploying a vscode-server agent inside the container and connecting it to the host IDE over an RPC channel. This architecture introduces several escape paths that go beyond normal container breakout:

  • Forwarded authentication sockets. By default, SSH_AUTH_SOCK and GPG_AGENT_INFO are forwarded into the container. Any process inside the container can request signatures or authenticate via the host's ssh-agent or gpg-agent -- without copying the keys. An attacker can use ssh-add -L to list host keys and ssh -o BatchMode=yes to pivot to other machines. A passphrase on the key only protects initial unlocking; once cached, the agent honors signing requests silently.

  • Copied Git configuration. Host ~/.gitconfig (including user.signingkey and credential.helper) is copied into the container by default. This enables commit signing and push auth seamlessly, but also allows impersonation and credential reuse. Disable with "remote.containers.copyGitConfig": false and clear remoteEnv entries.

  • Host terminal access from container extensions. The VS Code API allows workspace extensions running inside the container to call workbench.action.terminal.newLocal to open a terminal on the host, then workbench.action.terminal.sendSequence to send arbitrary commands to it. This is a full container-to-host RCE path that requires no exploit -- it is by design. (See Calif's "Vibe Hacking" research and The Red Guild's article for working PoCs.)

  • Extension host manipulation. A malicious workspace extension can modify .vscode/settings.json or .devcontainer/devcontainer.json (both are bind-mounted from the host), inject remote.extensionKind overrides, and trigger a window reload. The host then applies the poisoned config, potentially shifting other extensions between UI and workspace hosts.

Mitigations:

"remoteEnv": {
  "SSH_AUTH_SOCK": "",
  "GPG_AGENT_INFO": "",
  "GNUPGHOME": "/tmp/gnupg",
  "GIT_ASKPASS": ""
},
"settings": {
  "remote.containers.copyGitConfig": false
}

These disable the default socket forwarding and git config copy. They do NOT address the TerminalService RCE path -- that requires trusting every extension installed in the workspace.


Also add to References:


One broader point: The existing intro paragraph says "The container only sees what you explicitly mount. SSH keys, AWS credentials, and anything else under ~ stays on the host." This is misleading given the Remote extension's default behavior. The forwarded auth sockets and copied git config mean the container can effectively use (and abuse) those credentials without directly reading the files. I'd rephrase that sentence to something like: "The container's filesystem only sees what you explicitly mount, but the Remote extension forwards authentication sockets and Git configuration by default -- effectively giving the container access to host credentials without mounting the files."


Summary: expand the existing VS Code section's limitations with a focused subsection on the Remote extension trust model, add the references, and fix the misleading intro claim. No new category needed.

Copy link
Copy Markdown
Collaborator

@scode2277 scode2277 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again @ElliotFriedman, for the contribution as well as the updates!

gtg for me @mattaereal!


## VS Code dev containers

Dev containers run VS Code and every extension installed into it (including AI coding agents) inside a Docker container. The container only sees what you explicitly mount. SSH keys, AWS credentials, and anything else under `~` stays on the host.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Remote" extension that makes devcontainers possible in VSCode is closer to a RAT than anything else :/.

By default, it mounts several other things, such as exposing gpg-agent's and ssh-agent's host sockets within the container. It does not necessarily expose ~ files directly, but some of their contents through other mechanisms yes. Not all extensions run automatically, or by default inside the container too

Here's an article I wrote about all this, in case you want to use it as a reference to update this bit (or any other bit):
https://blog.theredguild.org/leveraging-vscode-internals-to-escape-containers/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frameworks-volunteer, how would you update, if you would, @ElliotFriedman's content based on the comment above? Take a look at the article, and decide whether it makes sense to add a clarification or create a new entire category about VScode

@frameworks-volunteer
Copy link
Copy Markdown
Collaborator

Model: z-ai/glm-5.1 Reasoning: medium Provider: openrouter

After reading @mattaereal's article and the current VS Code section in the page, my recommendation is to add a clarification within the existing VS Code section, not create a new entire category.

Reasons for keeping it as a clarification rather than a separate category:

  1. The VS Code devcontainer section already exists and is well-structured. Adding host-bridge warnings adjacent to the existing "Limitations" subsection preserves the reader's flow -- they see the promise of isolation, then immediately see what undermines it.

  2. A separate "VS Code Internals" category would fragment the sandboxing narrative. The page is about developer machine sandboxing broadly; splitting VS Code across two sections would force readers to jump between topics to piece together the full risk picture.

  3. The core insight from the article -- that vscode-server bridges host and container, copying git configs, mounting ssh-agent/gpg-agent sockets, and running extensions with varying privileges -- directly undermines the containment guarantees the existing section describes. This belongs right next to those guarantees, not in a separate category.

What I'd suggest adding to the existing VS Code section:

A new subsection (e.g., "### The Remote extension's host bridges") between the devcontainer.json example and the "Limitations" subsection, covering:

  • vscode-server deploys a remote extension host inside the container, creating a split-host model (local UI host + remote workspace host linked via RPC)
  • Host git configuration (.gitconfig, including GPG signing keys) is copied into the container by default
  • ssh-agent and gpg-agent sockets are mounted from the host, giving container processes access to SSH keys and signing capabilities without explicit mounts
  • Extensions run inside the container with the container user's privileges and have direct filesystem access to mounted volumes and environment variables
  • Not all extensions run inside the container (UI-only extensions stay local), but workspace-level extensions (language servers, debuggers, Git integration) run on the remote side with full access

This should reference mattaereal's article and the earlier TRG devcontainer posts for deeper reading, and connect back to the existing "Limitations" bullets (passwordless sudo, Docker socket mount, network concerns).

The existing "Limitations" subsection already lists three footguns. The vscode-server host bridges are a fourth -- arguably the most important one, since they undermine the isolation premise of the whole section. Adding them as a structured clarification rather than a separate category keeps the page cohesive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

content:add This issue or PR adds content or suggests to

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants