From 15f737dc3886622e93ca45636cd6413e13441f07 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 20:09:36 +0000 Subject: [PATCH 1/7] Initial plan From cfc17b1ec888f5823f4a9d979b1d9d4d95f8bbaf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 20:30:11 +0000 Subject: [PATCH 2/7] fix: sync converted codex gateway config into writable CODEX_HOME Agent-Logs-Url: https://github.com/github/gh-aw/sessions/9bfb489b-1cea-425d-8ea1-099e3ad8f516 Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- .github/workflows/ai-moderator.lock.yml | 10 +++++++ .github/workflows/changeset.lock.yml | 10 +++++++ .../codex-github-remote-mcp-test.lock.yml | 10 +++++++ .github/workflows/daily-fact.lock.yml | 10 +++++++ .../daily-observability-report.lock.yml | 10 +++++++ .../duplicate-code-detector.lock.yml | 10 +++++++ .github/workflows/grumpy-reviewer.lock.yml | 10 +++++++ .github/workflows/issue-arborist.lock.yml | 10 +++++++ .../schema-feature-coverage.lock.yml | 10 +++++++ .../workflows/smoke-call-workflow.lock.yml | 10 +++++++ .github/workflows/smoke-codex.lock.yml | 10 +++++++ pkg/workflow/codex_engine.go | 29 ++++++++++++++++--- pkg/workflow/codex_engine_test.go | 10 +++++++ pkg/workflow/codex_mcp.go | 23 +++++++++++++-- 14 files changed, 166 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ai-moderator.lock.yml b/.github/workflows/ai-moderator.lock.yml index d1277093405..86f6c170937 100644 --- a/.github/workflows/ai-moderator.lock.yml +++ b/.github/workflows/ai-moderator.lock.yml @@ -738,6 +738,16 @@ jobs: } } GH_AW_MCP_CONFIG_e663c9f713ba8ef0_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_41a4d5c2d909bed6_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_41a4d5c2d909bed6_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index 2a330b74e56..ecf56e9bdbc 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -757,6 +757,16 @@ jobs: } } GH_AW_MCP_CONFIG_6c95ba396f64fff8_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_20aa83733790ce7c_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_20aa83733790ce7c_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/codex-github-remote-mcp-test.lock.yml b/.github/workflows/codex-github-remote-mcp-test.lock.yml index 81c46f85102..1cec66a6e67 100644 --- a/.github/workflows/codex-github-remote-mcp-test.lock.yml +++ b/.github/workflows/codex-github-remote-mcp-test.lock.yml @@ -434,6 +434,16 @@ jobs: } } GH_AW_MCP_CONFIG_65f825e6fcc54e90_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_6ef9da006a49787c_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GITHUB_PERSONAL_ACCESS_TOKEN", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_6ef9da006a49787c_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Download activation artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml index 1e68e32bdbd..e150ed12dde 100644 --- a/.github/workflows/daily-fact.lock.yml +++ b/.github/workflows/daily-fact.lock.yml @@ -862,6 +862,16 @@ jobs: } } GH_AW_MCP_CONFIG_1b4b127ec8d7bd00_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_252c56bd99e6f878_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_252c56bd99e6f878_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/daily-observability-report.lock.yml b/.github/workflows/daily-observability-report.lock.yml index f6d5cf57bd7..49404169b42 100644 --- a/.github/workflows/daily-observability-report.lock.yml +++ b/.github/workflows/daily-observability-report.lock.yml @@ -790,6 +790,16 @@ jobs: } } GH_AW_MCP_CONFIG_929e8f2937cc782f_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_08284ac4f16ebe02_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_TOKEN", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_08284ac4f16ebe02_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml index c48e016cb16..7f9df409b33 100644 --- a/.github/workflows/duplicate-code-detector.lock.yml +++ b/.github/workflows/duplicate-code-detector.lock.yml @@ -764,6 +764,16 @@ jobs: } } GH_AW_MCP_CONFIG_64aeaad4be91ee91_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_5f2b419d8d1a0762_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_5f2b419d8d1a0762_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index cb5dc234a75..72e1ee5c699 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -785,6 +785,16 @@ jobs: } } GH_AW_MCP_CONFIG_8427183129186c74_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_fd0494d129bb4dc0_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_fd0494d129bb4dc0_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml index 2ed2937f5c7..69b9e85dcf2 100644 --- a/.github/workflows/issue-arborist.lock.yml +++ b/.github/workflows/issue-arborist.lock.yml @@ -797,6 +797,16 @@ jobs: } } GH_AW_MCP_CONFIG_ae10dba5409c9fdc_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_8df1e17e12a5553f_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_8df1e17e12a5553f_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/schema-feature-coverage.lock.yml b/.github/workflows/schema-feature-coverage.lock.yml index fa182fca21d..5f7f5681d13 100644 --- a/.github/workflows/schema-feature-coverage.lock.yml +++ b/.github/workflows/schema-feature-coverage.lock.yml @@ -689,6 +689,16 @@ jobs: } } GH_AW_MCP_CONFIG_f7f791fc4a40ada4_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_12a1c9e5a4cc208c_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_12a1c9e5a4cc208c_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/smoke-call-workflow.lock.yml b/.github/workflows/smoke-call-workflow.lock.yml index 73f573bbbe8..d711d385da2 100644 --- a/.github/workflows/smoke-call-workflow.lock.yml +++ b/.github/workflows/smoke-call-workflow.lock.yml @@ -698,6 +698,16 @@ jobs: } } GH_AW_MCP_CONFIG_c186530a09a3396a_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_2d745eed178272e7_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_2d745eed178272e7_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index ca33fbb5ae0..d0da04a3286 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -1178,6 +1178,16 @@ jobs: } } GH_AW_MCP_CONFIG_78a63514935420e3_EOF + + # Sync converter output to writable CODEX_HOME for Codex + mkdir -p /tmp/gh-aw/mcp-config + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_6ca2c660677622ac_EOF + [shell_environment_policy] + inherit = "core" + include_only = ["CODEX_API_KEY", "GH_AW_ASSETS_ALLOWED_EXTS", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_SAFE_OUTPUTS", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "HOME", "OPENAI_API_KEY", "PATH"] + GH_AW_CODEX_SHELL_POLICY_6ca2c660677622ac_EOF + cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" + chmod 600 "/tmp/gh-aw/mcp-config/config.toml" - name: Download activation artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: diff --git a/pkg/workflow/codex_engine.go b/pkg/workflow/codex_engine.go index 9b09d45a092..01951651da9 100644 --- a/pkg/workflow/codex_engine.go +++ b/pkg/workflow/codex_engine.go @@ -463,9 +463,7 @@ func (e *CodexEngine) expandNeutralToolsToCodexToolsFromMap(tools map[string]any return result.ToMap() } -// renderShellEnvironmentPolicy generates the [shell_environment_policy] section for config.toml -// This controls which environment variables are passed through to MCP servers for security -func (e *CodexEngine) renderShellEnvironmentPolicy(yaml *strings.Builder, tools map[string]any, mcpTools []string, workflowData *WorkflowData) { +func (e *CodexEngine) getShellEnvironmentPolicyVars(tools map[string]any, mcpTools []string) []string { // Collect all environment variables needed by MCP servers envVars := make(map[string]bool) @@ -509,13 +507,21 @@ func (e *CodexEngine) renderShellEnvironmentPolicy(yaml *strings.Builder, tools } } - // Sort environment variable names for consistent output var sortedEnvVars []string for envVar := range envVars { sortedEnvVars = append(sortedEnvVars, envVar) } sort.Strings(sortedEnvVars) + return sortedEnvVars +} + +// renderShellEnvironmentPolicy generates the [shell_environment_policy] section for config.toml +// This controls which environment variables are passed through to MCP servers for security +func (e *CodexEngine) renderShellEnvironmentPolicy(yaml *strings.Builder, tools map[string]any, mcpTools []string, workflowData *WorkflowData) { + _ = workflowData + sortedEnvVars := e.getShellEnvironmentPolicyVars(tools, mcpTools) + // Render [shell_environment_policy] section yaml.WriteString(" \n") yaml.WriteString(" [shell_environment_policy]\n") @@ -530,6 +536,21 @@ func (e *CodexEngine) renderShellEnvironmentPolicy(yaml *strings.Builder, tools yaml.WriteString("]\n") } +func (e *CodexEngine) renderShellEnvironmentPolicyToml(yaml *strings.Builder, tools map[string]any, mcpTools []string, indent string) { + sortedEnvVars := e.getShellEnvironmentPolicyVars(tools, mcpTools) + + yaml.WriteString(indent + "[shell_environment_policy]\n") + yaml.WriteString(indent + "inherit = \"core\"\n") + yaml.WriteString(indent + "include_only = [") + for i, envVar := range sortedEnvVars { + if i > 0 { + yaml.WriteString(", ") + } + yaml.WriteString("\"" + envVar + "\"") + } + yaml.WriteString("]\n") +} + // RenderMCPConfig is implemented in codex_mcp.go // renderCodexMCPConfig is implemented in codex_mcp.go diff --git a/pkg/workflow/codex_engine_test.go b/pkg/workflow/codex_engine_test.go index 027ee79f05d..b261a4a7f00 100644 --- a/pkg/workflow/codex_engine_test.go +++ b/pkg/workflow/codex_engine_test.go @@ -250,6 +250,16 @@ func TestCodexEngineRenderMCPConfig(t *testing.T) { "}", "}", "GH_AW_MCP_CONFIG_NORM_EOF", + "", + "# Sync converter output to writable CODEX_HOME for Codex", + "mkdir -p /tmp/gh-aw/mcp-config", + "cat > \"/tmp/gh-aw/mcp-config/config.toml\" << GH_AW_CODEX_SHELL_POLICY_NORM_EOF", + "[shell_environment_policy]", + "inherit = \"core\"", + "include_only = [\"CODEX_API_KEY\", \"GITHUB_PERSONAL_ACCESS_TOKEN\", \"HOME\", \"OPENAI_API_KEY\", \"PATH\"]", + "GH_AW_CODEX_SHELL_POLICY_NORM_EOF", + "cat \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"/tmp/gh-aw/mcp-config/config.toml\"", + "chmod 600 \"/tmp/gh-aw/mcp-config/config.toml\"", }, }, } diff --git a/pkg/workflow/codex_mcp.go b/pkg/workflow/codex_mcp.go index 19e259b8870..cf3226bf2c3 100644 --- a/pkg/workflow/codex_mcp.go +++ b/pkg/workflow/codex_mcp.go @@ -99,11 +99,30 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an yaml.WriteString(" # Generate JSON config for MCP gateway\n") // Gateway uses JSON format without Copilot-specific fields and multi-line args - return renderStandardJSONMCPConfig(yaml, tools, mcpTools, workflowData, + if err := renderStandardJSONMCPConfig(yaml, tools, mcpTools, workflowData, "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json", false, false, func(yaml *strings.Builder, toolName string, toolConfig map[string]any, isLast bool) error { return e.renderCodexJSONMCPConfigWithContext(yaml, toolName, toolConfig, isLast, workflowData) - }, nil) + }, nil); err != nil { + return err + } + + // start_mcp_gateway.cjs converts the gateway output and writes Codex config to + // ${RUNNER_TEMP}/gh-aw/mcp-config/config.toml. Codex reads config from + // $CODEX_HOME/config.toml, so copy the converted config into writable CODEX_HOME + // and prepend shell policy (converter output does not include this section). + yaml.WriteString(" \n") + yaml.WriteString(" # Sync converter output to writable CODEX_HOME for Codex\n") + yaml.WriteString(" mkdir -p /tmp/gh-aw/mcp-config\n") + + shellPolicyDelimiter := GenerateHeredocDelimiterFromSeed("CODEX_SHELL_POLICY", workflowData.FrontmatterHash) + yaml.WriteString(" cat > \"/tmp/gh-aw/mcp-config/config.toml\" << " + shellPolicyDelimiter + "\n") + e.renderShellEnvironmentPolicyToml(yaml, tools, mcpTools, " ") + yaml.WriteString(" " + shellPolicyDelimiter + "\n") + yaml.WriteString(" cat \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"/tmp/gh-aw/mcp-config/config.toml\"\n") + yaml.WriteString(" chmod 600 \"/tmp/gh-aw/mcp-config/config.toml\"\n") + + return nil } // renderCodexMCPConfigWithContext generates custom MCP server configuration for a single tool in codex workflow config.toml From 53ada6b2ea0faf3f08c8fbf5d8cb983b5b26d273 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 20:39:16 +0000 Subject: [PATCH 3/7] refactor: remove unused workflowData parameter in codex shell policy renderer Agent-Logs-Url: https://github.com/github/gh-aw/sessions/9bfb489b-1cea-425d-8ea1-099e3ad8f516 Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- pkg/workflow/codex_engine.go | 3 +-- pkg/workflow/codex_mcp.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/workflow/codex_engine.go b/pkg/workflow/codex_engine.go index 01951651da9..049de526804 100644 --- a/pkg/workflow/codex_engine.go +++ b/pkg/workflow/codex_engine.go @@ -518,8 +518,7 @@ func (e *CodexEngine) getShellEnvironmentPolicyVars(tools map[string]any, mcpToo // renderShellEnvironmentPolicy generates the [shell_environment_policy] section for config.toml // This controls which environment variables are passed through to MCP servers for security -func (e *CodexEngine) renderShellEnvironmentPolicy(yaml *strings.Builder, tools map[string]any, mcpTools []string, workflowData *WorkflowData) { - _ = workflowData +func (e *CodexEngine) renderShellEnvironmentPolicy(yaml *strings.Builder, tools map[string]any, mcpTools []string) { sortedEnvVars := e.getShellEnvironmentPolicyVars(tools, mcpTools) // Render [shell_environment_policy] section diff --git a/pkg/workflow/codex_mcp.go b/pkg/workflow/codex_mcp.go index cf3226bf2c3..29c2a495681 100644 --- a/pkg/workflow/codex_mcp.go +++ b/pkg/workflow/codex_mcp.go @@ -37,7 +37,7 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an // Add shell environment policy to control which environment variables are passed through // This is a security feature to prevent accidental exposure of secrets - e.renderShellEnvironmentPolicy(yaml, tools, mcpTools, workflowData) + e.renderShellEnvironmentPolicy(yaml, tools, mcpTools) // Expand neutral tools (like playwright: null) to include the copilot agent tools expandedTools := e.expandNeutralToolsToCodexToolsFromMap(tools) From 18d23dc0e0104b61cd0516823e8bc90bc78fb6b7 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Mon, 20 Apr 2026 14:11:23 -0700 Subject: [PATCH 4/7] Update pkg/workflow/codex_mcp.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- pkg/workflow/codex_mcp.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/workflow/codex_mcp.go b/pkg/workflow/codex_mcp.go index 29c2a495681..41afe59fb3f 100644 --- a/pkg/workflow/codex_mcp.go +++ b/pkg/workflow/codex_mcp.go @@ -120,6 +120,17 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an e.renderShellEnvironmentPolicyToml(yaml, tools, mcpTools, " ") yaml.WriteString(" " + shellPolicyDelimiter + "\n") yaml.WriteString(" cat \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"/tmp/gh-aw/mcp-config/config.toml\"\n") + if strings.TrimSpace(workflowData.EngineConfig.Config) != "" { + customConfigDelimiter := GenerateHeredocDelimiterFromSeed("CODEX_CUSTOM_CONFIG", workflowData.FrontmatterHash) + yaml.WriteString(" \n") + yaml.WriteString(" # Append engine-level custom Codex config\n") + yaml.WriteString(" cat >> \"/tmp/gh-aw/mcp-config/config.toml\" << " + customConfigDelimiter + "\n") + yaml.WriteString(workflowData.EngineConfig.Config) + if !strings.HasSuffix(workflowData.EngineConfig.Config, "\n") { + yaml.WriteString("\n") + } + yaml.WriteString(" " + customConfigDelimiter + "\n") + } yaml.WriteString(" chmod 600 \"/tmp/gh-aw/mcp-config/config.toml\"\n") return nil From 9b5f377890cb66ab8fd7e1b75a476c2179576d27 Mon Sep 17 00:00:00 2001 From: Landon Cox Date: Mon, 20 Apr 2026 14:11:35 -0700 Subject: [PATCH 5/7] Update pkg/workflow/codex_mcp.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- pkg/workflow/codex_mcp.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pkg/workflow/codex_mcp.go b/pkg/workflow/codex_mcp.go index 41afe59fb3f..400a6aefdf1 100644 --- a/pkg/workflow/codex_mcp.go +++ b/pkg/workflow/codex_mcp.go @@ -124,14 +124,13 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an customConfigDelimiter := GenerateHeredocDelimiterFromSeed("CODEX_CUSTOM_CONFIG", workflowData.FrontmatterHash) yaml.WriteString(" \n") yaml.WriteString(" # Append engine-level custom Codex config\n") - yaml.WriteString(" cat >> \"/tmp/gh-aw/mcp-config/config.toml\" << " + customConfigDelimiter + "\n") - yaml.WriteString(workflowData.EngineConfig.Config) - if !strings.HasSuffix(workflowData.EngineConfig.Config, "\n") { - yaml.WriteString("\n") - } - yaml.WriteString(" " + customConfigDelimiter + "\n") - } - yaml.WriteString(" chmod 600 \"/tmp/gh-aw/mcp-config/config.toml\"\n") + yaml.WriteString(" mkdir -p \"${CODEX_HOME}\"\n") + + shellPolicyDelimiter := GenerateHeredocDelimiterFromSeed("CODEX_SHELL_POLICY", workflowData.FrontmatterHash) + yaml.WriteString(" umask 077 && cat > \"${CODEX_HOME}/config.toml\" << " + shellPolicyDelimiter + "\n") + e.renderShellEnvironmentPolicyToml(yaml, tools, mcpTools, " ") + yaml.WriteString(" " + shellPolicyDelimiter + "\n") + yaml.WriteString(" cat \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"${CODEX_HOME}/config.toml\"\n") return nil } From 1c05837b220773deb67c733c2673b3dcf3d65ed1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 21:29:41 +0000 Subject: [PATCH 6/7] fix: repair codex mcp config generation and sync to CODEX_HOME Agent-Logs-Url: https://github.com/github/gh-aw/sessions/c295e628-1e15-4d3a-a32c-f707d20f506d Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- pkg/workflow/codex_engine_test.go | 3 +++ pkg/workflow/codex_mcp.go | 18 +++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/pkg/workflow/codex_engine_test.go b/pkg/workflow/codex_engine_test.go index b261a4a7f00..d4680f3388c 100644 --- a/pkg/workflow/codex_engine_test.go +++ b/pkg/workflow/codex_engine_test.go @@ -260,6 +260,9 @@ func TestCodexEngineRenderMCPConfig(t *testing.T) { "GH_AW_CODEX_SHELL_POLICY_NORM_EOF", "cat \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"/tmp/gh-aw/mcp-config/config.toml\"", "chmod 600 \"/tmp/gh-aw/mcp-config/config.toml\"", + "mkdir -p \"${CODEX_HOME}\"", + "cp \"/tmp/gh-aw/mcp-config/config.toml\" \"${CODEX_HOME}/config.toml\"", + "chmod 600 \"${CODEX_HOME}/config.toml\"", }, }, } diff --git a/pkg/workflow/codex_mcp.go b/pkg/workflow/codex_mcp.go index 400a6aefdf1..7c1c669c287 100644 --- a/pkg/workflow/codex_mcp.go +++ b/pkg/workflow/codex_mcp.go @@ -120,17 +120,21 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an e.renderShellEnvironmentPolicyToml(yaml, tools, mcpTools, " ") yaml.WriteString(" " + shellPolicyDelimiter + "\n") yaml.WriteString(" cat \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"/tmp/gh-aw/mcp-config/config.toml\"\n") - if strings.TrimSpace(workflowData.EngineConfig.Config) != "" { + if workflowData.EngineConfig != nil && strings.TrimSpace(workflowData.EngineConfig.Config) != "" { customConfigDelimiter := GenerateHeredocDelimiterFromSeed("CODEX_CUSTOM_CONFIG", workflowData.FrontmatterHash) yaml.WriteString(" \n") yaml.WriteString(" # Append engine-level custom Codex config\n") + yaml.WriteString(" cat >> \"/tmp/gh-aw/mcp-config/config.toml\" << " + customConfigDelimiter + "\n") + yaml.WriteString(workflowData.EngineConfig.Config) + if !strings.HasSuffix(workflowData.EngineConfig.Config, "\n") { + yaml.WriteString("\n") + } + yaml.WriteString(" " + customConfigDelimiter + "\n") + } + yaml.WriteString(" chmod 600 \"/tmp/gh-aw/mcp-config/config.toml\"\n") yaml.WriteString(" mkdir -p \"${CODEX_HOME}\"\n") - - shellPolicyDelimiter := GenerateHeredocDelimiterFromSeed("CODEX_SHELL_POLICY", workflowData.FrontmatterHash) - yaml.WriteString(" umask 077 && cat > \"${CODEX_HOME}/config.toml\" << " + shellPolicyDelimiter + "\n") - e.renderShellEnvironmentPolicyToml(yaml, tools, mcpTools, " ") - yaml.WriteString(" " + shellPolicyDelimiter + "\n") - yaml.WriteString(" cat \"${RUNNER_TEMP}/gh-aw/mcp-config/config.toml\" >> \"${CODEX_HOME}/config.toml\"\n") + yaml.WriteString(" cp \"/tmp/gh-aw/mcp-config/config.toml\" \"${CODEX_HOME}/config.toml\"\n") + yaml.WriteString(" chmod 600 \"${CODEX_HOME}/config.toml\"\n") return nil } From 76e2ee4066aa6feafca45bcd3638acbffec1549a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Apr 2026 21:37:44 +0000 Subject: [PATCH 7/7] chore: recompile lock workflows for codex config sync update Agent-Logs-Url: https://github.com/github/gh-aw/sessions/c295e628-1e15-4d3a-a32c-f707d20f506d Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com> --- .github/workflows/ai-moderator.lock.yml | 3 +++ .github/workflows/changeset.lock.yml | 3 +++ .github/workflows/codex-github-remote-mcp-test.lock.yml | 3 +++ .github/workflows/daily-fact.lock.yml | 3 +++ .github/workflows/daily-observability-report.lock.yml | 3 +++ .github/workflows/duplicate-code-detector.lock.yml | 3 +++ .github/workflows/grumpy-reviewer.lock.yml | 3 +++ .github/workflows/issue-arborist.lock.yml | 3 +++ .github/workflows/schema-feature-coverage.lock.yml | 3 +++ .github/workflows/smoke-call-workflow.lock.yml | 3 +++ .github/workflows/smoke-codex.lock.yml | 3 +++ 11 files changed, 33 insertions(+) diff --git a/.github/workflows/ai-moderator.lock.yml b/.github/workflows/ai-moderator.lock.yml index 86f6c170937..d3ae224bfd6 100644 --- a/.github/workflows/ai-moderator.lock.yml +++ b/.github/workflows/ai-moderator.lock.yml @@ -748,6 +748,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_41a4d5c2d909bed6_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index ecf56e9bdbc..57799850045 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -767,6 +767,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_20aa83733790ce7c_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/codex-github-remote-mcp-test.lock.yml b/.github/workflows/codex-github-remote-mcp-test.lock.yml index 1cec66a6e67..faffcef1820 100644 --- a/.github/workflows/codex-github-remote-mcp-test.lock.yml +++ b/.github/workflows/codex-github-remote-mcp-test.lock.yml @@ -444,6 +444,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_6ef9da006a49787c_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Download activation artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml index e150ed12dde..09f20f248f1 100644 --- a/.github/workflows/daily-fact.lock.yml +++ b/.github/workflows/daily-fact.lock.yml @@ -872,6 +872,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_252c56bd99e6f878_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/daily-observability-report.lock.yml b/.github/workflows/daily-observability-report.lock.yml index 49404169b42..6473661d960 100644 --- a/.github/workflows/daily-observability-report.lock.yml +++ b/.github/workflows/daily-observability-report.lock.yml @@ -800,6 +800,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_08284ac4f16ebe02_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml index 7f9df409b33..f03b0b1a2a2 100644 --- a/.github/workflows/duplicate-code-detector.lock.yml +++ b/.github/workflows/duplicate-code-detector.lock.yml @@ -774,6 +774,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_5f2b419d8d1a0762_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index 72e1ee5c699..ec2106d21b9 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -795,6 +795,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_fd0494d129bb4dc0_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml index 69b9e85dcf2..080b8382f52 100644 --- a/.github/workflows/issue-arborist.lock.yml +++ b/.github/workflows/issue-arborist.lock.yml @@ -807,6 +807,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_8df1e17e12a5553f_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/schema-feature-coverage.lock.yml b/.github/workflows/schema-feature-coverage.lock.yml index 5f7f5681d13..c99e2efbcdc 100644 --- a/.github/workflows/schema-feature-coverage.lock.yml +++ b/.github/workflows/schema-feature-coverage.lock.yml @@ -699,6 +699,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_12a1c9e5a4cc208c_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/smoke-call-workflow.lock.yml b/.github/workflows/smoke-call-workflow.lock.yml index d711d385da2..4a8119f7c8f 100644 --- a/.github/workflows/smoke-call-workflow.lock.yml +++ b/.github/workflows/smoke-call-workflow.lock.yml @@ -708,6 +708,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_2d745eed178272e7_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index d0da04a3286..aadef968390 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -1188,6 +1188,9 @@ jobs: GH_AW_CODEX_SHELL_POLICY_6ca2c660677622ac_EOF cat "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" >> "/tmp/gh-aw/mcp-config/config.toml" chmod 600 "/tmp/gh-aw/mcp-config/config.toml" + mkdir -p "${CODEX_HOME}" + cp "/tmp/gh-aw/mcp-config/config.toml" "${CODEX_HOME}/config.toml" + chmod 600 "${CODEX_HOME}/config.toml" - name: Download activation artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: