From 2e4b3d8bae6221979ab75a369498bcdefbaf4ad8 Mon Sep 17 00:00:00 2001 From: Shane White Date: Tue, 10 Mar 2026 09:08:20 +0000 Subject: [PATCH 1/3] feat: add boundary support via agentapi module --- registry/coder-labs/modules/codex/README.md | 26 +++++++ .../coder-labs/modules/codex/main.test.ts | 43 +++++++++++ registry/coder-labs/modules/codex/main.tf | 76 ++++++++++++++----- .../coder-labs/modules/codex/scripts/start.sh | 11 ++- 4 files changed, 135 insertions(+), 21 deletions(-) diff --git a/registry/coder-labs/modules/codex/README.md b/registry/coder-labs/modules/codex/README.md index b4a895dea..54a6f01e5 100644 --- a/registry/coder-labs/modules/codex/README.md +++ b/registry/coder-labs/modules/codex/README.md @@ -140,6 +140,32 @@ module "codex" { > [!WARNING] > This module configures Codex with a `workspace-write` sandbox that allows AI tasks to read/write files in the specified workdir. While the sandbox provides security boundaries, Codex can still modify files within the workspace. Use this module _only_ in trusted environments and be aware of the security implications. +### Network Filtering with Coder Boundary + +This example shows how to enable network filtering using Coder Boundary to restrict outbound network access. + +```tf +module "codex" { + source = "registry.coder.com/coder-labs/codex/coder" + version = "4.2.0" + agent_id = coder_agent.example.id + openai_api_key = "..." + workdir = "/home/coder/project" + # Enable boundary + enable_boundary = true + boundary_config_path = "/home/coder/.config/coder_boundary/config.yaml" + # Optional: install boundary binary instead of using coder subcommand + # use_boundary_directly = true + # boundary_version = "0.6.0" +} +``` + +When `enable_boundary = true`: + +- All network traffic from Codex is routed through a filtering proxy +- Only allowlisted domains are accessible (configure via boundary config.yaml) +- Users must mount the boundary config file into the workspace (see [Agent Boundaries docs](https://coder.com/docs/ai-coder/agent-boundaries#configuration)) + ## How it Works - **Install**: The module installs Codex CLI and sets up the environment diff --git a/registry/coder-labs/modules/codex/main.test.ts b/registry/coder-labs/modules/codex/main.test.ts index a4edd8185..dab75563e 100644 --- a/registry/coder-labs/modules/codex/main.test.ts +++ b/registry/coder-labs/modules/codex/main.test.ts @@ -482,4 +482,47 @@ describe("codex", async () => { "[profiles.aibridge]\n" + 'model_provider = "aibridge"', ); }); + + test("boundary-enabled", async () => { + const { id } = await setup({ + moduleVariables: { + enable_boundary: "true", + boundary_config_path: "/tmp/test-boundary.yaml", + }, + }); + // Write boundary config + await execContainer(id, [ + "bash", + "-c", + `cat > /tmp/test-boundary.yaml <<'EOF' +jail_type: landjail +proxy_port: 8087 +log_level: warn +allowlist: + - "domain=api.openai.com" +EOF`, + ]); + // Add mock coder binary for boundary setup + await writeExecutable({ + containerId: id, + filePath: "/usr/bin/coder", + content: `#!/bin/bash +if [ "$1" = "boundary" ]; then + if [ "$2" = "--help" ]; then + echo "boundary help" + exit 0 + fi + shift; shift; exec "$@" +fi +echo "mock coder"`, + }); + await execModuleScript(id); + await expectAgentAPIStarted(id); + // Verify boundary wrapper was used in start script + const startLog = await readFileContainer( + id, + "/home/coder/.codex-module/agentapi-start.log", + ); + expect(startLog).toContain("boundary"); + }); }); diff --git a/registry/coder-labs/modules/codex/main.tf b/registry/coder-labs/modules/codex/main.tf index cc07ce2f9..90734f4e9 100644 --- a/registry/coder-labs/modules/codex/main.tf +++ b/registry/coder-labs/modules/codex/main.tf @@ -170,6 +170,36 @@ variable "codex_system_prompt" { default = "You are a helpful coding assistant. Start every response with `Codex says:`" } +variable "enable_boundary" { + type = bool + description = "Enable coder boundary for network filtering." + default = false +} + +variable "boundary_config_path" { + type = string + description = "Path to boundary config.yaml inside the workspace. If provided, exposed as BOUNDARY_CONFIG env var." + default = "" +} + +variable "boundary_version" { + type = string + description = "Boundary version. When use_boundary_directly is true, a release version should be provided or 'latest' for the latest release." + default = "latest" +} + +variable "compile_boundary_from_source" { + type = bool + description = "Whether to compile boundary from source instead of using the official install script." + default = false +} + +variable "use_boundary_directly" { + type = bool + description = "Whether to use boundary binary directly instead of coder boundary subcommand." + default = false +} + resource "coder_env" "openai_api_key" { agent_id = var.agent_id name = "OPENAI_API_KEY" @@ -204,26 +234,32 @@ locals { } module "agentapi" { - source = "registry.coder.com/coder/agentapi/coder" - version = "2.0.0" - - agent_id = var.agent_id - folder = local.workdir - web_app_slug = local.app_slug - web_app_order = var.order - web_app_group = var.group - web_app_icon = var.icon - web_app_display_name = var.web_app_display_name - cli_app = var.cli_app - cli_app_slug = var.cli_app ? "${local.app_slug}-cli" : null - cli_app_display_name = var.cli_app ? var.cli_app_display_name : null - module_dir_name = local.module_dir_name - install_agentapi = var.install_agentapi - agentapi_subdomain = var.subdomain - agentapi_version = var.agentapi_version - pre_install_script = var.pre_install_script - post_install_script = var.post_install_script - start_script = <<-EOT + # source = "registry.coder.com/coder/agentapi/coder" + # version = "2.0.0" + source = "git::https://github.com/shanewhite97/registry.git//registry/coder/modules/agentapi?ref=feat/agent-api-boundary-support" + + agent_id = var.agent_id + folder = local.workdir + web_app_slug = local.app_slug + web_app_order = var.order + web_app_group = var.group + web_app_icon = var.icon + web_app_display_name = var.web_app_display_name + cli_app = var.cli_app + cli_app_slug = var.cli_app ? "${local.app_slug}-cli" : null + cli_app_display_name = var.cli_app ? var.cli_app_display_name : null + module_dir_name = local.module_dir_name + install_agentapi = var.install_agentapi + agentapi_subdomain = var.subdomain + agentapi_version = var.agentapi_version + pre_install_script = var.pre_install_script + post_install_script = var.post_install_script + enable_boundary = var.enable_boundary + boundary_config_path = var.boundary_config_path + boundary_version = var.boundary_version + compile_boundary_from_source = var.compile_boundary_from_source + use_boundary_directly = var.use_boundary_directly + start_script = <<-EOT #!/bin/bash set -o errexit set -o pipefail diff --git a/registry/coder-labs/modules/codex/scripts/start.sh b/registry/coder-labs/modules/codex/scripts/start.sh index 3e55dc70f..457c2897c 100644 --- a/registry/coder-labs/modules/codex/scripts/start.sh +++ b/registry/coder-labs/modules/codex/scripts/start.sh @@ -213,7 +213,16 @@ capture_session_id() { start_codex() { printf "Starting Codex with arguments: %s\n" "${CODEX_ARGS[*]}" - agentapi server --term-width 67 --term-height 1190 -- codex "${CODEX_ARGS[@]}" & + # AGENTAPI_BOUNDARY_PREFIX is set by the agentapi module's main.sh when + # enable_boundary=true. It points to a wrapper script that runs the command + # through coder boundary, sandboxing only the agent process. + if [ -n "${AGENTAPI_BOUNDARY_PREFIX:-}" ]; then + printf "Starting with coder boundary enabled\n" + agentapi server --type codex --term-width 67 --term-height 1190 -- \ + "${AGENTAPI_BOUNDARY_PREFIX}" codex "${CODEX_ARGS[@]}" & + else + agentapi server --type codex --term-width 67 --term-height 1190 -- codex "${CODEX_ARGS[@]}" & + fi capture_session_id } From 9ba792ca7cffe009a03edc579aac8bb8796671f6 Mon Sep 17 00:00:00 2001 From: Shane White Date: Wed, 11 Mar 2026 15:35:26 +0000 Subject: [PATCH 2/3] chore: update README version and agentapi version --- registry/coder-labs/modules/codex/README.md | 12 ++++++------ registry/coder-labs/modules/codex/main.tf | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/registry/coder-labs/modules/codex/README.md b/registry/coder-labs/modules/codex/README.md index f547d4881..ade7afa63 100644 --- a/registry/coder-labs/modules/codex/README.md +++ b/registry/coder-labs/modules/codex/README.md @@ -13,7 +13,7 @@ Run Codex CLI in your workspace to access OpenAI's models through the Codex inte ```tf module "codex" { source = "registry.coder.com/coder-labs/codex/coder" - version = "4.2.0" + version = "4.3.0" agent_id = coder_agent.example.id openai_api_key = var.openai_api_key workdir = "/home/coder/project" @@ -32,7 +32,7 @@ module "codex" { module "codex" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder-labs/codex/coder" - version = "4.2.0" + version = "4.3.0" agent_id = coder_agent.example.id openai_api_key = "..." workdir = "/home/coder/project" @@ -51,7 +51,7 @@ For tasks integration with AI Bridge, add `enable_aibridge = true` to the [Usage ```tf module "codex" { source = "registry.coder.com/coder-labs/codex/coder" - version = "4.2.0" + version = "4.3.0" agent_id = coder_agent.example.id workdir = "/home/coder/project" enable_aibridge = true @@ -94,7 +94,7 @@ data "coder_task" "me" {} module "codex" { source = "registry.coder.com/coder-labs/codex/coder" - version = "4.2.0" + version = "4.3.0" agent_id = coder_agent.example.id openai_api_key = "..." ai_prompt = data.coder_task.me.prompt @@ -112,7 +112,7 @@ This example shows additional configuration options for custom models, MCP serve ```tf module "codex" { source = "registry.coder.com/coder-labs/codex/coder" - version = "4.2.0" + version = "4.3.0" agent_id = coder_agent.example.id openai_api_key = "..." workdir = "/home/coder/project" @@ -147,7 +147,7 @@ This example shows how to enable network filtering using Coder Boundary to restr ```tf module "codex" { source = "registry.coder.com/coder-labs/codex/coder" - version = "4.2.0" + version = "4.3.0" agent_id = coder_agent.example.id openai_api_key = "..." workdir = "/home/coder/project" diff --git a/registry/coder-labs/modules/codex/main.tf b/registry/coder-labs/modules/codex/main.tf index 2a3cff7f4..4d9c5ae14 100644 --- a/registry/coder-labs/modules/codex/main.tf +++ b/registry/coder-labs/modules/codex/main.tf @@ -241,9 +241,8 @@ locals { } module "agentapi" { - # source = "registry.coder.com/coder/agentapi/coder" - # version = "2.2.0" - source = "git::https://github.com/shanewhite97/registry.git//registry/coder/modules/agentapi?ref=feat/agent-api-boundary-support" + source = "registry.coder.com/coder/agentapi/coder" + version = "2.3.0" agent_id = var.agent_id folder = local.workdir From f4d05482e28df86c61a63493d03498ad3d104d9b Mon Sep 17 00:00:00 2001 From: Shane White Date: Wed, 11 Mar 2026 17:10:39 +0000 Subject: [PATCH 3/3] docs: Updated README.md file for codex module --- registry/coder-labs/modules/codex/README.md | 46 +++++++++------------ 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/registry/coder-labs/modules/codex/README.md b/registry/coder-labs/modules/codex/README.md index ade7afa63..5e8ac2729 100644 --- a/registry/coder-labs/modules/codex/README.md +++ b/registry/coder-labs/modules/codex/README.md @@ -105,6 +105,26 @@ module "codex" { } ``` +### Usage with Agent Boundaries + +This example shows how to configure the Codex module to run the agent behind a process-level boundary that restricts its network access. + +By default, when `enable_boundary = true`, the module uses `coder boundary` subcommand (provided by Coder) without requiring any installation. + +```tf +module "codex" { + source = "registry.coder.com/coder-labs/codex/coder" + version = "4.3.0" + agent_id = coder_agent.main.id + openai_api_key = var.openai_api_key + workdir = "/home/coder/project" + enable_boundary = true +} +``` + +> [!NOTE] +> For developers: The module also supports installing boundary from a release version (`use_boundary_directly = true`) or compiling from source (`compile_boundary_from_source = true`). These are escape hatches for development and testing purposes. + ### Advanced Configuration This example shows additional configuration options for custom models, MCP servers, and base configuration. @@ -140,32 +160,6 @@ module "codex" { > [!WARNING] > This module configures Codex with a `workspace-write` sandbox that allows AI tasks to read/write files in the specified workdir. While the sandbox provides security boundaries, Codex can still modify files within the workspace. Use this module _only_ in trusted environments and be aware of the security implications. -### Network Filtering with Coder Boundary - -This example shows how to enable network filtering using Coder Boundary to restrict outbound network access. - -```tf -module "codex" { - source = "registry.coder.com/coder-labs/codex/coder" - version = "4.3.0" - agent_id = coder_agent.example.id - openai_api_key = "..." - workdir = "/home/coder/project" - # Enable boundary - enable_boundary = true - boundary_config_path = "/home/coder/.config/coder_boundary/config.yaml" - # Optional: install boundary binary instead of using coder subcommand - # use_boundary_directly = true - # boundary_version = "0.6.0" -} -``` - -When `enable_boundary = true`: - -- All network traffic from Codex is routed through a filtering proxy -- Only allowlisted domains are accessible (configure via boundary config.yaml) -- Users must mount the boundary config file into the workspace (see [Agent Boundaries docs](https://coder.com/docs/ai-coder/agent-boundaries#configuration)) - ## How it Works - **Install**: The module installs Codex CLI and sets up the environment