From 86e5d4765f70a584f6701c2deb20cbf28a81bdef Mon Sep 17 00:00:00 2001 From: Susana Cardoso Ferreira Date: Thu, 12 Feb 2026 12:39:37 +0000 Subject: [PATCH 1/4] feat: add AI Bridge Proxy support to copilot module --- registry/coder-labs/modules/copilot/README.md | 31 ++++- .../modules/copilot/copilot.tftest.hcl | 113 ++++++++++++++++++ registry/coder-labs/modules/copilot/main.tf | 32 +++++ .../modules/copilot/scripts/start.sh | 38 ++++++ 4 files changed, 213 insertions(+), 1 deletion(-) diff --git a/registry/coder-labs/modules/copilot/README.md b/registry/coder-labs/modules/copilot/README.md index 76b8f025c..5bc494a28 100644 --- a/registry/coder-labs/modules/copilot/README.md +++ b/registry/coder-labs/modules/copilot/README.md @@ -3,7 +3,7 @@ display_name: Copilot CLI description: GitHub Copilot CLI agent for AI-powered terminal assistance icon: ../../../../.icons/github.svg verified: false -tags: [agent, copilot, ai, github, tasks] +tags: [agent, copilot, ai, github, tasks, aibridge] --- # Copilot @@ -164,6 +164,35 @@ module "copilot" { } ``` +### Usage with AI Bridge Proxy + +[AI Bridge Proxy](https://coder.com/docs/ai-coder/ai-bridge/ai-bridge-proxy) routes Copilot traffic through [AI Bridge](https://coder.com/docs/ai-coder/ai-bridge) for centralized LLM management and governance. +The proxy environment variables are scoped to the Copilot process only and do not affect other workspace traffic. + +```tf +module "aibridge-proxy" { + source = "registry.coder.com/coder/aibridge-proxy/coder" + version = "1.0.0" + agent_id = coder_agent.main.id + proxy_url = "https://aiproxy.example.com" +} + +module "copilot" { + source = "registry.coder.com/coder-labs/copilot/coder" + version = "0.4.0" + agent_id = coder_agent.main.id + workdir = "/home/coder/projects" + enable_aibridge_proxy = true + aibridge_proxy_auth_url = module.aibridge-proxy.proxy_auth_url + aibridge_proxy_cert_path = module.aibridge-proxy.cert_path +} +``` + +> [!NOTE] +> AI Bridge Proxy is a Premium Coder feature that requires [AI Bridge](https://coder.com/docs/ai-coder/ai-bridge) to be enabled. +> See the [AI Bridge Proxy setup guide](https://coder.com/docs/ai-coder/ai-bridge/ai-bridge-proxy/setup) for details on configuring the proxy on your Coder deployment. +> GitHub authentication is still required for Copilot as the proxy authenticates with AI Bridge using the Coder session token, but does not replace GitHub authentication. + ## Authentication The module supports multiple authentication methods (in priority order): diff --git a/registry/coder-labs/modules/copilot/copilot.tftest.hcl b/registry/coder-labs/modules/copilot/copilot.tftest.hcl index 185c019ba..8ef7148d4 100644 --- a/registry/coder-labs/modules/copilot/copilot.tftest.hcl +++ b/registry/coder-labs/modules/copilot/copilot.tftest.hcl @@ -234,3 +234,116 @@ run "app_slug_is_consistent" { error_message = "module_dir_name should be '.copilot-module'" } } + +run "aibridge_proxy_defaults" { + command = plan + + variables { + agent_id = "test-agent" + workdir = "/home/coder" + } + + assert { + condition = var.enable_aibridge_proxy == false + error_message = "enable_aibridge_proxy should default to false" + } + + assert { + condition = var.aibridge_proxy_auth_url == "" + error_message = "aibridge_proxy_auth_url should default to empty" + } + + assert { + condition = var.aibridge_proxy_cert_path == "" + error_message = "aibridge_proxy_cert_path should default to empty" + } +} + +run "aibridge_proxy_enabled" { + command = plan + + variables { + agent_id = "test-agent-aibridge-proxy" + workdir = "/home/coder" + enable_aibridge_proxy = true + aibridge_proxy_auth_url = "https://coder:mock-token@aiproxy.example.com" + aibridge_proxy_cert_path = "/tmp/aibridge-proxy/ca-cert.pem" + } + + assert { + condition = var.enable_aibridge_proxy == true + error_message = "AI Bridge Proxy should be enabled" + } + + assert { + condition = var.aibridge_proxy_auth_url == "https://coder:mock-token@aiproxy.example.com" + error_message = "AI Bridge Proxy auth URL should match the input variable" + } + + assert { + condition = var.aibridge_proxy_cert_path == "/tmp/aibridge-proxy/ca-cert.pem" + error_message = "AI Bridge Proxy cert path should match the input variable" + } +} + +run "aibridge_proxy_validation_missing_proxy_auth_url" { + command = plan + + variables { + agent_id = "test-agent-validation" + workdir = "/home/coder" + enable_aibridge_proxy = true + aibridge_proxy_auth_url = "" + aibridge_proxy_cert_path = "/tmp/aibridge-proxy/ca-cert.pem" + } + + expect_failures = [ + var.enable_aibridge_proxy, + ] +} + +run "aibridge_proxy_validation_missing_cert_path" { + command = plan + + variables { + agent_id = "test-agent-validation" + workdir = "/home/coder" + enable_aibridge_proxy = true + aibridge_proxy_auth_url = "https://coder:mock-token@aiproxy.example.com" + aibridge_proxy_cert_path = "" + } + + expect_failures = [ + var.enable_aibridge_proxy, + ] +} + +run "aibridge_proxy_with_copilot_config" { + command = plan + + variables { + agent_id = "test-agent" + workdir = "/home/coder" + copilot_model = "gpt-5" + github_token = "ghp_test123" + allow_all_tools = true + enable_aibridge_proxy = true + aibridge_proxy_auth_url = "https://coder:mock-token@aiproxy.example.com" + aibridge_proxy_cert_path = "/tmp/aibridge-proxy/ca-cert.pem" + } + + assert { + condition = var.enable_aibridge_proxy == true + error_message = "AI Bridge Proxy should be enabled" + } + + assert { + condition = length(resource.coder_env.github_token) == 1 + error_message = "github_token environment variable should be set alongside proxy" + } + + assert { + condition = length(resource.coder_env.copilot_model) == 1 + error_message = "copilot_model environment variable should be set alongside proxy" + } +} diff --git a/registry/coder-labs/modules/copilot/main.tf b/registry/coder-labs/modules/copilot/main.tf index 218184d75..492b99a75 100644 --- a/registry/coder-labs/modules/copilot/main.tf +++ b/registry/coder-labs/modules/copilot/main.tf @@ -173,6 +173,35 @@ variable "post_install_script" { default = null } +variable "enable_aibridge_proxy" { + type = bool + description = "Route Copilot traffic through AI Bridge Proxy. See https://coder.com/docs/ai-coder/ai-bridge/ai-bridge-proxy" + default = false + + validation { + condition = !var.enable_aibridge_proxy || length(var.aibridge_proxy_auth_url) > 0 + error_message = "aibridge_proxy_auth_url is required when enable_aibridge_proxy is true." + } + + validation { + condition = !var.enable_aibridge_proxy || length(var.aibridge_proxy_cert_path) > 0 + error_message = "aibridge_proxy_cert_path is required when enable_aibridge_proxy is true." + } +} + +variable "aibridge_proxy_auth_url" { + type = string + description = "AI Bridge Proxy URL with authentication. Use the proxy_auth_url output from the aibridge-proxy module." + default = "" + sensitive = true +} + +variable "aibridge_proxy_cert_path" { + type = string + description = "Path to the AI Bridge Proxy CA certificate. Use the cert_path output from the aibridge-proxy module." + default = "" +} + data "coder_workspace" "me" {} data "coder_workspace_owner" "me" {} @@ -279,6 +308,9 @@ module "agentapi" { ARG_TRUSTED_DIRECTORIES='${join(",", var.trusted_directories)}' \ ARG_EXTERNAL_AUTH_ID='${var.external_auth_id}' \ ARG_RESUME_SESSION='${var.resume_session}' \ + ARG_ENABLE_AIBRIDGE_PROXY='${var.enable_aibridge_proxy}' \ + ARG_AIBRIDGE_PROXY_AUTH_URL='${var.aibridge_proxy_auth_url}' \ + ARG_AIBRIDGE_PROXY_CERT_PATH='${var.aibridge_proxy_cert_path}' \ /tmp/start.sh EOT diff --git a/registry/coder-labs/modules/copilot/scripts/start.sh b/registry/coder-labs/modules/copilot/scripts/start.sh index 98341e9bc..57f5c60c8 100644 --- a/registry/coder-labs/modules/copilot/scripts/start.sh +++ b/registry/coder-labs/modules/copilot/scripts/start.sh @@ -22,6 +22,9 @@ ARG_DENY_TOOLS=${ARG_DENY_TOOLS:-} ARG_TRUSTED_DIRECTORIES=${ARG_TRUSTED_DIRECTORIES:-} ARG_EXTERNAL_AUTH_ID=${ARG_EXTERNAL_AUTH_ID:-github} ARG_RESUME_SESSION=${ARG_RESUME_SESSION:-true} +ARG_ENABLE_AIBRIDGE_PROXY=${ARG_ENABLE_AIBRIDGE_PROXY:-false} +ARG_AIBRIDGE_PROXY_AUTH_URL=${ARG_AIBRIDGE_PROXY_AUTH_URL:-} +ARG_AIBRIDGE_PROXY_CERT_PATH=${ARG_AIBRIDGE_PROXY_CERT_PATH:-} validate_copilot_installation() { if ! command_exists copilot; then @@ -118,6 +121,40 @@ setup_github_authentication() { return 0 } +setup_aibridge_proxy() { + if [ "$ARG_ENABLE_AIBRIDGE_PROXY" != "true" ]; then + return 0 + fi + + echo "Setting up AI Bridge Proxy..." + + if [ -z "$ARG_AIBRIDGE_PROXY_AUTH_URL" ]; then + echo "ERROR: AI Bridge Proxy is enabled but no proxy auth URL provided." + exit 1 + fi + + if [ -z "$ARG_AIBRIDGE_PROXY_CERT_PATH" ]; then + echo "ERROR: AI Bridge Proxy is enabled but no certificate path provided." + exit 1 + fi + + if [ ! -f "$ARG_AIBRIDGE_PROXY_CERT_PATH" ]; then + echo "ERROR: AI Bridge Proxy certificate not found at $ARG_AIBRIDGE_PROXY_CERT_PATH." + echo " Ensure the aibridge-proxy module has completed setup." + exit 1 + fi + + # Set proxy environment variables scoped to this process tree only. + # These are inherited by the agentapi/copilot process below, + # but do not affect other workspace processes, avoiding routing + # unnecessary traffic through the proxy. + export HTTPS_PROXY="$ARG_AIBRIDGE_PROXY_AUTH_URL" + export NODE_EXTRA_CA_CERTS="$ARG_AIBRIDGE_PROXY_CERT_PATH" + + echo "✓ AI Bridge Proxy configured" + echo " CA certificate: $ARG_AIBRIDGE_PROXY_CERT_PATH" +} + start_agentapi() { echo "Starting in directory: $ARG_WORKDIR" cd "$ARG_WORKDIR" @@ -157,5 +194,6 @@ start_agentapi() { } setup_github_authentication +setup_aibridge_proxy validate_copilot_installation start_agentapi From 8afeedd0aa1917ca0fdb5c995d1dca0c1b652230 Mon Sep 17 00:00:00 2001 From: Susana Cardoso Ferreira Date: Fri, 13 Feb 2026 11:14:24 +0000 Subject: [PATCH 2/4] chore: update terraform version >=1.9 --- registry/coder-labs/modules/copilot/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/coder-labs/modules/copilot/main.tf b/registry/coder-labs/modules/copilot/main.tf index 492b99a75..78e836496 100644 --- a/registry/coder-labs/modules/copilot/main.tf +++ b/registry/coder-labs/modules/copilot/main.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 1.0" + required_version = ">= 1.9" required_providers { coder = { source = "coder/coder" From a9e60bd45fd9c28d05a39ca2f7cbe40c43eb2c72 Mon Sep 17 00:00:00 2001 From: Susana Cardoso Ferreira Date: Fri, 13 Feb 2026 13:44:10 +0000 Subject: [PATCH 3/4] feat: wait for aibridge-proxy setup before starting copilot --- registry/coder-labs/modules/copilot/scripts/start.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/registry/coder-labs/modules/copilot/scripts/start.sh b/registry/coder-labs/modules/copilot/scripts/start.sh index 57f5c60c8..836603ac3 100644 --- a/registry/coder-labs/modules/copilot/scripts/start.sh +++ b/registry/coder-labs/modules/copilot/scripts/start.sh @@ -128,6 +128,14 @@ setup_aibridge_proxy() { echo "Setting up AI Bridge Proxy..." + # Wait for the aibridge-proxy module to finish. + # Uses startup coordination to block until aibridge-proxy-setup signals completion. + if command -v coder > /dev/null 2>&1; then + coder exp sync want "copilot-aibridge" "aibridge-proxy-setup" || true + coder exp sync start "copilot-aibridge" || true + trap 'coder exp sync complete "copilot-aibridge" > /dev/null 2>&1 || true' EXIT + fi + if [ -z "$ARG_AIBRIDGE_PROXY_AUTH_URL" ]; then echo "ERROR: AI Bridge Proxy is enabled but no proxy auth URL provided." exit 1 From 84b32ac592b845db19cf5f175dfd10652cf22d79 Mon Sep 17 00:00:00 2001 From: Susana Cardoso Ferreira Date: Fri, 13 Feb 2026 13:50:29 +0000 Subject: [PATCH 4/4] docs: update README --- registry/coder-labs/modules/copilot/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/registry/coder-labs/modules/copilot/README.md b/registry/coder-labs/modules/copilot/README.md index 5bc494a28..212cc40db 100644 --- a/registry/coder-labs/modules/copilot/README.md +++ b/registry/coder-labs/modules/copilot/README.md @@ -193,6 +193,10 @@ module "copilot" { > See the [AI Bridge Proxy setup guide](https://coder.com/docs/ai-coder/ai-bridge/ai-bridge-proxy/setup) for details on configuring the proxy on your Coder deployment. > GitHub authentication is still required for Copilot as the proxy authenticates with AI Bridge using the Coder session token, but does not replace GitHub authentication. +> [!IMPORTANT] +> When using AI Bridge Proxy, enable [startup coordination](https://coder.com/docs/admin/templates/startup-coordination) by setting `CODER_AGENT_SOCKET_SERVER_ENABLED=true` in the workspace container environment. +> This ensures the Copilot module waits for the `aibridge-proxy` module to complete before starting. Without it, the Copilot start script may fail if the certificate is not yet available. + ## Authentication The module supports multiple authentication methods (in priority order):