Skip to content

fix: shrink workspace privilege and egress surface - #180

Open
nboyers wants to merge 2 commits into
mainfrom
fix/shrink-workspace-privilege-and-egress
Open

fix: shrink workspace privilege and egress surface#180
nboyers wants to merge 2 commits into
mainfrom
fix/shrink-workspace-privilege-and-egress

Conversation

@nboyers

@nboyers nboyers commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #179. Prerequisites for adding Cilium egress policy: each of these
either weakens the enforcement claim or enlarges the allowlist Cilium has to permit.

1. Drop unnecessary privileged from realworld

realworld ran its workspace container with privileged = true and
allow_privilege_escalation = true. Verified unnecessary:

  • its image, public.ecr.aws/f7a1d7a4/coder-aienv, installs no container runtime
    (grep podman\|docker images/aws/coder-aienv/Dockerfile.noble → nothing)
  • no sudo anywhere in the template, and none in any of its six registry modules
  • memorycard runs the same image with both set to false, in production

A privileged container holds host capabilities and can in principle manipulate the
eBPF maps that back pod network policy, so this was the main caveat on any
egress-lockdown claim for the template. memorycard was previously the only
defensible one; now it is two.

Not changed: devbox, datasci and universal-sandbox keep privileged.
Their image (coder-aidev) does apt install podman podman-compose and symlinks
dockerpodman, and universal-sandbox's MongoDB preset runs sudo apt-get install, which allow_privilege_escalation = false would break by setting
no_new_privs. Also unchanged: envbox (needs it) and selenium's exectrace sidecar.

2. install_prefix on vscode-web: stop re-downloading VS Code every start

memorycard and realworld set use_cached = true with no install_prefix.
The module resolves VSCODE_WEB="${INSTALL_PREFIX}/bin/code-server" and defaults
INSTALL_PREFIX to /tmp/vscode-web, which is empty on a fresh pod, so the cache
check at run.sh:83 misses and it downloads the server from
vscode.download.prss.microsoft.com on every workspace start.

The image already bakes it in and symlinks /usr/local/bin/code-server, so
install_prefix = "/usr/local" makes the cache hit, matching devbox and datasci.

Also fixes realworld's launch script, which hardcoded
/tmp/vscode-web/bin/code-server --install-extension and would have broken as soon
as the prefix moved. It now calls code-server off PATH, as memorycard already did.
This matters because the cached path exit 0s before the module's own extension
install, so that loop is the real extension installer.

Removes two Microsoft CDN domains from the eventual allowlist, and cuts startup time.

3. devbox Boundary config write bug

mkdir -p $HOME/.config/coder_boundary
$HOME/.config/coder_boundary/config.yaml            # executes the path as a command
chmod 600 $HOME/.config/coder_boundary/config.yaml  # file does not exist yet
cat << EOT > $HOME/.config/coder_boundary/config.yaml   # created only here

Under #!/bin/sh with no set -e both failed silently, so the Boundary allowlist
ended up mode 644 instead of 600. Reordered: write, then restrict. This is the L7
half of the enforcement design, so its config needs to actually be protected.

Verification

terraform fmt -check -recursive clean; terraform validate Success on all three.
CI builds a real workspace per template, so an agent that fails to start after
losing privileged or after the code-server path change will fail the check.

Rollback is re-activating the previous template version, per --activate=false.

🤖 Generated with Claude Code

Three independent problems, all of which weaken or complicate network
enforcement on workspace pods.

realworld ran its workspace container with privileged = true and
allow_privilege_escalation = true. Neither is needed: its image
(coder-aienv) ships no container runtime, and nothing in the template or
any of its modules uses sudo. memorycard runs the same image with both
set to false. A privileged container holds host capabilities and could in
principle tamper with the eBPF maps backing pod network policy, so this
also removed the main caveat on any egress-lockdown claim for the
template. devbox, datasci and universal-sandbox keep privileged: their
image installs podman and symlinks docker to it.

memorycard and realworld passed use_cached = true to vscode-web with no
install_prefix. The module resolves ${INSTALL_PREFIX}/bin/code-server and
falls back to /tmp/vscode-web, which is empty on a fresh pod, so both
templates re-downloaded the VS Code server from Microsoft on every start.
The image already bakes it into /usr/local/lib/vscode-web and symlinks
/usr/local/bin/code-server, so install_prefix = "/usr/local" makes the
cache hit. realworld's launch script hardcoded the old /tmp path, which
would have broken once the prefix moved, so it now calls code-server off
PATH as memorycard already did.

devbox's Boundary post-install script executed the config path as a
command and chmod'd the file before the heredoc created it. Under
/bin/sh with no set -e both failed silently, leaving the config at mode
644. Reordered so the file is written first and then restricted.
@nboyers
nboyers changed the base branch from fix/normalize-workspace-pod-labels to main August 17, 2026 17:12
@nboyers
nboyers force-pushed the fix/shrink-workspace-privilege-and-egress branch from 782e41e to 6a66832 Compare August 17, 2026 17:12
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

Coder Agents Chat: agent finished or is awaiting input

Chat: https://ai.coder.com/agents/a47a5bf0-a2c1-4323-98b6-ef5f53bf90a8
Status: waiting

@github-actions

Copy link
Copy Markdown

Agent Validation PASSED for template devbox

Field Value
Step ALL
Summary Template found, workspace created and verified.
Chat https://ai.coder.com/agents/cec3f7ae-1bb1-4e50-a1b2-850b7b9328e8
Workspace ID ac216658-247c-4d24-b81a-93fe822c5d51
Workspace Status running
Workflow Run View logs

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

Coder Agents Chat: agent finished or is awaiting input

Chat: https://ai.coder.com/agents/24e350f6-85f0-44b3-bce2-ecc3eeef39ad
Status: waiting

@github-actions

Copy link
Copy Markdown

🔍 Build Failure Analysis for template memorycard (workspace: memorycard-32049286500)

Field Value
Root Cause No build logs available - logs are completely empty
Failed Resource UNKNOWN
Error Message No error messages found in logs (logs are empty)
Suggestion Re-run the build and verify that log collection is working properly
Analysis Chat https://ai.coder.com/agents/d6e14358-428d-4608-b846-6a60df1e6982

@github-actions

Copy link
Copy Markdown

Agent Validation PASSED for template devbox

Field Value
Step ALL
Summary Template found, workspace created and verified.
Chat https://ai.coder.com/agents/f953124b-1d9e-47f3-aa4b-3609516bef70
Workspace ID b4e0f657-ba2b-4081-8fe1-20fd9de9a3c0
Workspace Status running
Workflow Run View logs

@github-actions

Copy link
Copy Markdown

🔍 Build Failure Analysis for template memorycard (workspace: memorycard-32049286500)

Field Value
Root Cause No build logs available for analysis - logs are completely empty
Failed Resource UNKNOWN
Error Message No error messages present in logs - log output is empty
Suggestion Retrieve complete build logs from Coder deployment or check alternative log sources
Analysis Chat https://ai.coder.com/agents/24e350f6-85f0-44b3-bce2-ecc3eeef39ad

@github-actions

Copy link
Copy Markdown

Coder Agents Chat: agent finished or is awaiting input

Chat: https://ai.coder.com/agents/f780450b-7589-48a3-a5a9-6cc732a885d7
Status: waiting

@github-actions

Copy link
Copy Markdown

🔍 Build Failure Analysis for template realworld (workspace: realworld-32049286500)

Field Value
Root Cause No build logs available - logs are empty or were not captured
Failed Resource UNKNOWN
Error Message Build logs are completely empty - no output captured
Suggestion Retrieve actual build logs from Coder server or re-run the build with proper log capture
Analysis Chat https://ai.coder.com/agents/f780450b-7589-48a3-a5a9-6cc732a885d7

@github-actions

Copy link
Copy Markdown

Coder Agents Chat: agent finished or is awaiting input

Chat: https://ai.coder.com/agents/25f6b452-dbb6-4f5e-a5b4-d6d5dcea7c48
Status: waiting

@github-actions

Copy link
Copy Markdown

Agent Validation PASSED for template realworld

Field Value
Step ALL
Summary Template found, workspace created and verified.
Chat https://ai.coder.com/agents/25f6b452-dbb6-4f5e-a5b4-d6d5dcea7c48
Workspace ID f66fa6b4-ac1e-430d-af46-e958e16811c8
Workspace Status running
Workflow Run View logs

@github-actions

Copy link
Copy Markdown

Agent Validation PASSED for template devbox

Field Value
Step ALL
Summary Template found, workspace created and verified.
Chat https://ai.coder.com/agents/a47a5bf0-a2c1-4323-98b6-ef5f53bf90a8
Workspace ID aae6856d-0d37-4f05-84b5-2bfb5b42b44d
Workspace Status running
Workflow Run View logs

@github-actions

Copy link
Copy Markdown

Coder Agents Chat: agent finished or is awaiting input

Chat: https://ai.coder.com/agents/8a7eb680-b721-433c-87a4-bfb836949f7c
Status: waiting

@github-actions

Copy link
Copy Markdown

Agent Validation PASSED for template memorycard

Field Value
Step ALL
Summary Template found, workspace created and verified.
Chat https://ai.coder.com/agents/8a7eb680-b721-433c-87a4-bfb836949f7c
Workspace ID 358d8a0a-a53e-4834-9edd-7b7860384844
Workspace Status running
Workflow Run View logs

@github-actions

Copy link
Copy Markdown

Coder Agents Chat: agent finished or is awaiting input

Chat: https://ai.coder.com/agents/b615cf21-072c-4c58-88ac-aa99903669ff
Status: waiting

@github-actions

Copy link
Copy Markdown

Agent Validation PASSED for template devbox

Field Value
Step ALL
Summary Template found, workspace created and verified.
Chat https://ai.coder.com/agents/b615cf21-072c-4c58-88ac-aa99903669ff
Workspace ID 5de2aba8-d5c5-40d0-821a-a50bbdea4801
Workspace Status running
Workflow Run View logs

@github-actions

Copy link
Copy Markdown

Coder Agents Chat: agent finished or is awaiting input

Chat: https://ai.coder.com/agents/ee682dbd-91c7-424b-97ea-33e0e4cf468c
Status: waiting

@github-actions

Copy link
Copy Markdown

Agent Validation PASSED for template realworld

Field Value
Step ALL
Summary Template found, workspace created and verified.
Chat https://ai.coder.com/agents/ee682dbd-91c7-424b-97ea-33e0e4cf468c
Workspace ID c3b7e58b-6060-4903-bbaf-f036f23fd521
Workspace Status running
Workflow Run View logs

@github-actions

Copy link
Copy Markdown

Coder Agents Chat: agent finished or is awaiting input

Chat: https://ai.coder.com/agents/479974c2-feae-474c-b074-7ed02cb5a242
Status: waiting

@github-actions

Copy link
Copy Markdown

Agent Validation PASSED for template memorycard

Field Value
Step ALL
Summary Template found, workspace created and verified.
Chat https://ai.coder.com/agents/479974c2-feae-474c-b074-7ed02cb5a242
Workspace ID e0d80d6c-6e9e-42b2-82de-49e1dce7acef
Workspace Status running
Workflow Run View logs

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant