Skip to content

Commit a0430e6

Browse files
shanewhite97Shane White35C4n0r
authored
feat(coder-labs/modules/codex): add boundary support via agentapi module (#795)
## Description Adds boundary support to the Codex module by passing boundary variables through to the agentapi module and using AGENTAPI_BOUNDARY_PREFIX in the start script. Depends on #780 ## Type of Change - [x] Feature/enhancement ## Module Information **Path:** `registry/coder-labs/modules/codex` **Breaking change:** No --------- Co-authored-by: Shane White <shane.white@cloudsecure.ltd> Co-authored-by: 35C4n0r <70096901+35C4n0r@users.noreply.github.com>
1 parent 2ee14fd commit a0430e6

4 files changed

Lines changed: 133 additions & 26 deletions

File tree

registry/coder-labs/modules/codex/README.md

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Run Codex CLI in your workspace to access OpenAI's models through the Codex inte
1313
```tf
1414
module "codex" {
1515
source = "registry.coder.com/coder-labs/codex/coder"
16-
version = "4.2.0"
16+
version = "4.3.0"
1717
agent_id = coder_agent.example.id
1818
openai_api_key = var.openai_api_key
1919
workdir = "/home/coder/project"
@@ -32,7 +32,7 @@ module "codex" {
3232
module "codex" {
3333
count = data.coder_workspace.me.start_count
3434
source = "registry.coder.com/coder-labs/codex/coder"
35-
version = "4.2.0"
35+
version = "4.3.0"
3636
agent_id = coder_agent.example.id
3737
openai_api_key = "..."
3838
workdir = "/home/coder/project"
@@ -51,7 +51,7 @@ For tasks integration with AI Bridge, add `enable_aibridge = true` to the [Usage
5151
```tf
5252
module "codex" {
5353
source = "registry.coder.com/coder-labs/codex/coder"
54-
version = "4.2.0"
54+
version = "4.3.0"
5555
agent_id = coder_agent.example.id
5656
workdir = "/home/coder/project"
5757
enable_aibridge = true
@@ -94,7 +94,7 @@ data "coder_task" "me" {}
9494
9595
module "codex" {
9696
source = "registry.coder.com/coder-labs/codex/coder"
97-
version = "4.2.0"
97+
version = "4.3.0"
9898
agent_id = coder_agent.example.id
9999
openai_api_key = "..."
100100
ai_prompt = data.coder_task.me.prompt
@@ -105,14 +105,34 @@ module "codex" {
105105
}
106106
```
107107

108+
### Usage with Agent Boundaries
109+
110+
This example shows how to configure the Codex module to run the agent behind a process-level boundary that restricts its network access.
111+
112+
By default, when `enable_boundary = true`, the module uses `coder boundary` subcommand (provided by Coder) without requiring any installation.
113+
114+
```tf
115+
module "codex" {
116+
source = "registry.coder.com/coder-labs/codex/coder"
117+
version = "4.3.0"
118+
agent_id = coder_agent.main.id
119+
openai_api_key = var.openai_api_key
120+
workdir = "/home/coder/project"
121+
enable_boundary = true
122+
}
123+
```
124+
125+
> [!NOTE]
126+
> 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.
127+
108128
### Advanced Configuration
109129

110130
This example shows additional configuration options for custom models, MCP servers, and base configuration.
111131

112132
```tf
113133
module "codex" {
114134
source = "registry.coder.com/coder-labs/codex/coder"
115-
version = "4.2.0"
135+
version = "4.3.0"
116136
agent_id = coder_agent.example.id
117137
openai_api_key = "..."
118138
workdir = "/home/coder/project"

registry/coder-labs/modules/codex/main.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,4 +473,47 @@ describe("codex", async () => {
473473
);
474474
expect(configToml).toContain('profile = "aibridge"');
475475
});
476+
477+
test("boundary-enabled", async () => {
478+
const { id } = await setup({
479+
moduleVariables: {
480+
enable_boundary: "true",
481+
boundary_config_path: "/tmp/test-boundary.yaml",
482+
},
483+
});
484+
// Write boundary config
485+
await execContainer(id, [
486+
"bash",
487+
"-c",
488+
`cat > /tmp/test-boundary.yaml <<'EOF'
489+
jail_type: landjail
490+
proxy_port: 8087
491+
log_level: warn
492+
allowlist:
493+
- "domain=api.openai.com"
494+
EOF`,
495+
]);
496+
// Add mock coder binary for boundary setup
497+
await writeExecutable({
498+
containerId: id,
499+
filePath: "/usr/bin/coder",
500+
content: `#!/bin/bash
501+
if [ "$1" = "boundary" ]; then
502+
if [ "$2" = "--help" ]; then
503+
echo "boundary help"
504+
exit 0
505+
fi
506+
shift; shift; exec "$@"
507+
fi
508+
echo "mock coder"`,
509+
});
510+
await execModuleScript(id);
511+
await expectAgentAPIStarted(id);
512+
// Verify boundary wrapper was used in start script
513+
const startLog = await readFileContainer(
514+
id,
515+
"/home/coder/.codex-module/agentapi-start.log",
516+
);
517+
expect(startLog).toContain("boundary");
518+
});
476519
});

registry/coder-labs/modules/codex/main.tf

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,36 @@ variable "codex_system_prompt" {
176176
default = "You are a helpful coding assistant. Start every response with `Codex says:`"
177177
}
178178

179+
variable "enable_boundary" {
180+
type = bool
181+
description = "Enable coder boundary for network filtering."
182+
default = false
183+
}
184+
185+
variable "boundary_config_path" {
186+
type = string
187+
description = "Path to boundary config.yaml inside the workspace. If provided, exposed as BOUNDARY_CONFIG env var."
188+
default = ""
189+
}
190+
191+
variable "boundary_version" {
192+
type = string
193+
description = "Boundary version. When use_boundary_directly is true, a release version should be provided or 'latest' for the latest release."
194+
default = "latest"
195+
}
196+
197+
variable "compile_boundary_from_source" {
198+
type = bool
199+
description = "Whether to compile boundary from source instead of using the official install script."
200+
default = false
201+
}
202+
203+
variable "use_boundary_directly" {
204+
type = bool
205+
description = "Whether to use boundary binary directly instead of coder boundary subcommand."
206+
default = false
207+
}
208+
179209
resource "coder_env" "openai_api_key" {
180210
agent_id = var.agent_id
181211
name = "OPENAI_API_KEY"
@@ -212,26 +242,31 @@ locals {
212242

213243
module "agentapi" {
214244
source = "registry.coder.com/coder/agentapi/coder"
215-
version = "2.2.0"
216-
217-
agent_id = var.agent_id
218-
folder = local.workdir
219-
web_app_slug = local.app_slug
220-
web_app_order = var.order
221-
web_app_group = var.group
222-
web_app_icon = var.icon
223-
web_app_display_name = var.web_app_display_name
224-
cli_app = var.cli_app
225-
cli_app_slug = var.cli_app ? "${local.app_slug}-cli" : null
226-
cli_app_display_name = var.cli_app ? var.cli_app_display_name : null
227-
module_dir_name = local.module_dir_name
228-
install_agentapi = var.install_agentapi
229-
agentapi_subdomain = var.subdomain
230-
agentapi_version = var.agentapi_version
231-
enable_state_persistence = var.enable_state_persistence
232-
pre_install_script = var.pre_install_script
233-
post_install_script = var.post_install_script
234-
start_script = <<-EOT
245+
version = "2.3.0"
246+
247+
agent_id = var.agent_id
248+
folder = local.workdir
249+
web_app_slug = local.app_slug
250+
web_app_order = var.order
251+
web_app_group = var.group
252+
web_app_icon = var.icon
253+
web_app_display_name = var.web_app_display_name
254+
cli_app = var.cli_app
255+
cli_app_slug = var.cli_app ? "${local.app_slug}-cli" : null
256+
cli_app_display_name = var.cli_app ? var.cli_app_display_name : null
257+
module_dir_name = local.module_dir_name
258+
install_agentapi = var.install_agentapi
259+
agentapi_subdomain = var.subdomain
260+
agentapi_version = var.agentapi_version
261+
enable_state_persistence = var.enable_state_persistence
262+
pre_install_script = var.pre_install_script
263+
post_install_script = var.post_install_script
264+
enable_boundary = var.enable_boundary
265+
boundary_config_path = var.boundary_config_path
266+
boundary_version = var.boundary_version
267+
compile_boundary_from_source = var.compile_boundary_from_source
268+
use_boundary_directly = var.use_boundary_directly
269+
start_script = <<-EOT
235270
#!/bin/bash
236271
set -o errexit
237272
set -o pipefail

registry/coder-labs/modules/codex/scripts/start.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,16 @@ capture_session_id() {
210210

211211
start_codex() {
212212
printf "Starting Codex with arguments: %s\n" "${CODEX_ARGS[*]}"
213-
agentapi server --type codex --term-width 67 --term-height 1190 -- codex "${CODEX_ARGS[@]}" &
213+
# AGENTAPI_BOUNDARY_PREFIX is set by the agentapi module's main.sh when
214+
# enable_boundary=true. It points to a wrapper script that runs the command
215+
# through coder boundary, sandboxing only the agent process.
216+
if [ -n "${AGENTAPI_BOUNDARY_PREFIX:-}" ]; then
217+
printf "Starting with coder boundary enabled\n"
218+
agentapi server --type codex --term-width 67 --term-height 1190 -- \
219+
"${AGENTAPI_BOUNDARY_PREFIX}" codex "${CODEX_ARGS[@]}" &
220+
else
221+
agentapi server --type codex --term-width 67 --term-height 1190 -- codex "${CODEX_ARGS[@]}" &
222+
fi
214223
capture_session_id
215224
}
216225

0 commit comments

Comments
 (0)