From 05c3b226e1f690fb3257b4660f6f1e94386a55f6 Mon Sep 17 00:00:00 2001 From: Zach Kipp Date: Fri, 5 Dec 2025 13:20:21 -0700 Subject: [PATCH 1/4] feat(claude-code): use boundary simple mode (no special permissions) Changes boundary from namespace mode (requiring sudo/CAP_NET_ADMIN) to simple mode which uses HTTP_PROXY environment variables. - Install boundary to ~/.local/bin (no sudo needed) - Use 'boundary --simple' instead of 'boundary-run' - No special Linux permissions required Trade-off: processes can bypass the proxy by ignoring HTTP_PROXY env vars. For full isolation, namespace mode is still available but requires privileged containers or CAP_NET_ADMIN capability. --- .../modules/claude-code/scripts/start.sh | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index 59983b9e8..86dbdad09 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -30,6 +30,7 @@ ARG_ENABLE_BOUNDARY_PPROF=${ARG_ENABLE_BOUNDARY_PPROF:-false} ARG_BOUNDARY_PPROF_PORT=${ARG_BOUNDARY_PPROF_PORT:-"6067"} ARG_COMPILE_FROM_SOURCE=${ARG_COMPILE_FROM_SOURCE:-false} ARG_CODER_HOST=${ARG_CODER_HOST:-} +ARG_BOUNDARY_ADDITIONAL_ALLOWED_URLS=${ARG_BOUNDARY_ADDITIONAL_ALLOWED_URLS:-} echo "--------------------------------" @@ -75,14 +76,14 @@ function install_boundary() { # Build the binary make build - # Install binary and wrapper script (optional) - sudo cp boundary /usr/local/bin/ - sudo cp scripts/boundary-wrapper.sh /usr/local/bin/boundary-run - sudo chmod +x /usr/local/bin/boundary-run + # Install binary to user-local bin (no sudo needed for simple mode) + mkdir -p "$HOME/.local/bin" + cp boundary "$HOME/.local/bin/" + chmod +x "$HOME/.local/bin/boundary" else - # Install boundary using official install script + # Install boundary using official install script to user-local directory echo "Installing boundary using official install script (version: $ARG_BOUNDARY_VERSION)" - curl -fsSL https://raw.githubusercontent.com/coder/boundary/main/install.sh | bash -s -- --version "$ARG_BOUNDARY_VERSION" + INSTALL_DIR="$HOME/.local/bin" curl -fsSL https://raw.githubusercontent.com/coder/boundary/main/install.sh | bash -s -- --version "$ARG_BOUNDARY_VERSION" fi } @@ -210,12 +211,12 @@ function start_agentapi() { install_boundary mkdir -p "$ARG_BOUNDARY_LOG_DIR" - printf "Starting with coder boundary enabled\n" + printf "Starting with coder boundary enabled (simple mode - no special permissions)\n" - # Build boundary args with conditional --unprivileged flag - BOUNDARY_ARGS=(--log-dir "$ARG_BOUNDARY_LOG_DIR") + # Build boundary args - using --simple mode (no sudo/capabilities required) + BOUNDARY_ARGS=(--simple --log-dir "$ARG_BOUNDARY_LOG_DIR") # Add default allowed URLs - BOUNDARY_ARGS+=(--allow "domain=anthropic.com" --allow "domain=registry.npmjs.org" --allow "domain=sentry.io" --allow "domain=claude.ai" --allow "domain=$ARG_CODER_HOST") + BOUNDARY_ARGS+=(--allow "domain=anthropic.com" --allow "domain=registry.npmjs.org" --allow "domain=sentry.io" --allow "domain=claude.ai" --allow "domain=${ARG_CODER_HOST%%:*}") # Add any additional allowed URLs from the variable if [ -n "$ARG_BOUNDARY_ADDITIONAL_ALLOWED_URLS" ]; then @@ -238,8 +239,9 @@ function start_agentapi() { BOUNDARY_ARGS+=(--pprof-port "$ARG_BOUNDARY_PPROF_PORT") fi + # Use boundary directly with --simple flag (no boundary-run wrapper needed) agentapi server --type claude --term-width 67 --term-height 1190 -- \ - boundary-run "${BOUNDARY_ARGS[@]}" -- \ + boundary "${BOUNDARY_ARGS[@]}" -- \ claude "${ARGS[@]}" else agentapi server --type claude --term-width 67 --term-height 1190 -- claude "${ARGS[@]}" From d425df477c1778a9b6fb5ee7580daf79ad4f7a62 Mon Sep 17 00:00:00 2001 From: Zach Kipp Date: Fri, 5 Dec 2025 13:27:27 -0700 Subject: [PATCH 2/4] fix: pass INSTALL_DIR to bash, not curl --- registry/coder-labs/templates/tasks-docker/main.tf | 14 ++++++++++++-- .../coder/modules/claude-code/scripts/start.sh | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/registry/coder-labs/templates/tasks-docker/main.tf b/registry/coder-labs/templates/tasks-docker/main.tf index 5fbea1af5..07222acd7 100644 --- a/registry/coder-labs/templates/tasks-docker/main.tf +++ b/registry/coder-labs/templates/tasks-docker/main.tf @@ -32,8 +32,8 @@ data "coder_task" "me" {} # Or use a custom agent: module "claude-code" { count = data.coder_workspace.me.start_count - source = "registry.coder.com/coder/claude-code/coder" - version = "4.0.0" + source = "/Users/zach/src/registry/registry/coder/modules/claude-code" + # version = "4.0.0" agent_id = coder_agent.main.id workdir = "/home/coder/projects" order = 999 @@ -43,6 +43,12 @@ module "claude-code" { model = "sonnet" permission_mode = "plan" post_install_script = data.coder_parameter.setup_script.value + enable_boundary = true + boundary_version = "v0.2.1" + boundary_log_dir = "/tmp/boundary_logs" + boundary_log_level = "DEBUG" + boundary_additional_allowed_urls = ["method=GET domain=google.com"] + boundary_proxy_port = "8087" } # We are using presets to set the prompts, image, and set up instructions @@ -359,6 +365,10 @@ resource "docker_container" "workspace" { volume_name = docker_volume.home_volume.name read_only = false } + capabilities { + add = ["NET_ADMIN", "SYS_ADMIN"] + } + security_opts = ["seccomp=unconfined"] # Add labels in Docker to keep track of orphan resources. labels { diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index 86dbdad09..737052f88 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -83,7 +83,7 @@ function install_boundary() { else # Install boundary using official install script to user-local directory echo "Installing boundary using official install script (version: $ARG_BOUNDARY_VERSION)" - INSTALL_DIR="$HOME/.local/bin" curl -fsSL https://raw.githubusercontent.com/coder/boundary/main/install.sh | bash -s -- --version "$ARG_BOUNDARY_VERSION" + curl -fsSL https://raw.githubusercontent.com/coder/boundary/main/install.sh | INSTALL_DIR="$HOME/.local/bin" bash -s -- --version "$ARG_BOUNDARY_VERSION" fi } From b60ea7c583817cf3d72502948b6b92125ba2ed7c Mon Sep 17 00:00:00 2001 From: Zach Kipp Date: Fri, 5 Dec 2025 13:41:53 -0700 Subject: [PATCH 3/4] fix(claude-code): add audit socket for boundary logs reporting Pass --audit-socket to boundary so it reports network events to the Coder agent, which forwards them to coderd for display in the UI. --- registry/coder/modules/claude-code/scripts/start.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index 737052f88..d48f1c113 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -215,6 +215,16 @@ function start_agentapi() { # Build boundary args - using --simple mode (no sudo/capabilities required) BOUNDARY_ARGS=(--simple --log-dir "$ARG_BOUNDARY_LOG_DIR") + + # Add audit socket for reporting to Coder agent + AUDIT_SOCKET="${TMPDIR:-/tmp}/coder-boundary-audit.sock" + if [ -S "$AUDIT_SOCKET" ]; then + BOUNDARY_ARGS+=(--audit-socket "$AUDIT_SOCKET") + printf "Using audit socket: %s\n" "$AUDIT_SOCKET" + else + printf "Warning: Audit socket not found at %s - boundary logs won't be reported to Coder\n" "$AUDIT_SOCKET" + fi + # Add default allowed URLs BOUNDARY_ARGS+=(--allow "domain=anthropic.com" --allow "domain=registry.npmjs.org" --allow "domain=sentry.io" --allow "domain=claude.ai" --allow "domain=${ARG_CODER_HOST%%:*}") From 8bea8eeb34e0e074bfdb0d0ad70cbb5617417964 Mon Sep 17 00:00:00 2001 From: Zach Kipp Date: Fri, 5 Dec 2025 15:06:38 -0700 Subject: [PATCH 4/4] fix(claude-code): clean up existing boundary dir before cloning --- registry/coder/modules/claude-code/scripts/start.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index d48f1c113..d04829828 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -69,6 +69,12 @@ function install_boundary() { if [ "${ARG_COMPILE_FROM_SOURCE:-false}" = "true" ]; then # Install boundary by compiling from source echo "Compiling boundary from source (version: $ARG_BOUNDARY_VERSION)" + + # Clean up existing directory if it exists + if [ -d "boundary" ]; then + rm -rf boundary + fi + git clone https://github.com/coder/boundary.git cd boundary git checkout "$ARG_BOUNDARY_VERSION" @@ -80,6 +86,8 @@ function install_boundary() { mkdir -p "$HOME/.local/bin" cp boundary "$HOME/.local/bin/" chmod +x "$HOME/.local/bin/boundary" + + cd .. else # Install boundary using official install script to user-local directory echo "Installing boundary using official install script (version: $ARG_BOUNDARY_VERSION)"