Compare commits

...

4 Commits

Author SHA1 Message Date
Zach Kipp 8bea8eeb34 fix(claude-code): clean up existing boundary dir before cloning 2025-12-05 15:06:38 -07:00
Zach Kipp b60ea7c583 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.
2025-12-05 13:41:53 -07:00
Zach Kipp d425df477c fix: pass INSTALL_DIR to bash, not curl 2025-12-05 13:27:27 -07:00
Zach Kipp 05c3b226e1 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.
2025-12-05 13:20:21 -07:00
2 changed files with 43 additions and 13 deletions
@@ -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 {
@@ -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 "--------------------------------"
@@ -68,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"
@@ -75,14 +82,16 @@ 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"
cd ..
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"
curl -fsSL https://raw.githubusercontent.com/coder/boundary/main/install.sh | INSTALL_DIR="$HOME/.local/bin" bash -s -- --version "$ARG_BOUNDARY_VERSION"
fi
}
@@ -210,12 +219,22 @@ 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 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")
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 +257,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[@]}"