diff --git a/.github/workflows/ai-moderator.lock.yml b/.github/workflows/ai-moderator.lock.yml index 9c1af00cbd..685c2d1f10 100644 --- a/.github/workflows/ai-moderator.lock.yml +++ b/.github/workflows/ai-moderator.lock.yml @@ -746,9 +746,6 @@ jobs: # 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"] model_provider = "openai-proxy" @@ -757,6 +754,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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 awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index 286744cd6f..11c8044eec 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -765,9 +765,6 @@ jobs: # 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"] model_provider = "openai-proxy" @@ -776,6 +773,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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 awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/.github/workflows/codex-github-remote-mcp-test.lock.yml b/.github/workflows/codex-github-remote-mcp-test.lock.yml index e6d055d4ce..fc2cc2748d 100644 --- a/.github/workflows/codex-github-remote-mcp-test.lock.yml +++ b/.github/workflows/codex-github-remote-mcp-test.lock.yml @@ -440,9 +440,6 @@ jobs: # 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"] model_provider = "openai-proxy" @@ -451,6 +448,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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 awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml index 92d4961d7a..58bbb7fed5 100644 --- a/.github/workflows/daily-fact.lock.yml +++ b/.github/workflows/daily-fact.lock.yml @@ -868,9 +868,6 @@ jobs: # 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"] model_provider = "openai-proxy" @@ -879,6 +876,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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 awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/.github/workflows/daily-observability-report.lock.yml b/.github/workflows/daily-observability-report.lock.yml index deeb7ec095..d3a6b0dde4 100644 --- a/.github/workflows/daily-observability-report.lock.yml +++ b/.github/workflows/daily-observability-report.lock.yml @@ -796,9 +796,6 @@ jobs: # 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"] model_provider = "openai-proxy" @@ -807,6 +804,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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 awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml index 93685b820e..33636f2261 100644 --- a/.github/workflows/duplicate-code-detector.lock.yml +++ b/.github/workflows/duplicate-code-detector.lock.yml @@ -770,9 +770,6 @@ jobs: # 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"] model_provider = "openai-proxy" @@ -781,6 +778,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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 awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index caaec57975..37f83f060d 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -793,9 +793,6 @@ jobs: # 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"] model_provider = "openai-proxy" @@ -804,6 +801,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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 awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml index 32a990a7f4..e6c713d55a 100644 --- a/.github/workflows/issue-arborist.lock.yml +++ b/.github/workflows/issue-arborist.lock.yml @@ -803,9 +803,6 @@ jobs: # 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"] model_provider = "openai-proxy" @@ -814,6 +811,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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 awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/.github/workflows/schema-feature-coverage.lock.yml b/.github/workflows/schema-feature-coverage.lock.yml index 3f2c959056..be7154a537 100644 --- a/.github/workflows/schema-feature-coverage.lock.yml +++ b/.github/workflows/schema-feature-coverage.lock.yml @@ -695,9 +695,6 @@ jobs: # 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"] model_provider = "openai-proxy" @@ -706,6 +703,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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 awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/.github/workflows/smoke-call-workflow.lock.yml b/.github/workflows/smoke-call-workflow.lock.yml index 8921019573..ebd2e997ac 100644 --- a/.github/workflows/smoke-call-workflow.lock.yml +++ b/.github/workflows/smoke-call-workflow.lock.yml @@ -706,9 +706,6 @@ jobs: # 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"] model_provider = "openai-proxy" @@ -717,6 +714,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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 awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index cf0f5869b2..6121b71b05 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -1214,9 +1214,6 @@ jobs: # 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_71ae115a66db43bd_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"] model_provider = "openai-proxy" @@ -1225,6 +1222,9 @@ jobs: base_url = "http://172.30.0.30:10000" env_key = "OPENAI_API_KEY" supports_websockets = false + [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_71ae115a66db43bd_EOF awk ' BEGIN { skip_openai_proxy = 0 } diff --git a/pkg/workflow/codex_engine_test.go b/pkg/workflow/codex_engine_test.go index e920292175..2c992ea5bf 100644 --- a/pkg/workflow/codex_engine_test.go +++ b/pkg/workflow/codex_engine_test.go @@ -348,6 +348,33 @@ func TestCodexEngineRenderMCPConfigOpenAIProxyProvider(t *testing.T) { if !strings.Contains(result, "awk '") { t.Errorf("Expected firewall-enabled config append to use awk filtering, got:\n%s", result) } + + normalizedResult := normalizeHeredocDelimiters(result) + syncStart := strings.Index(normalizedResult, "cat > \"/tmp/gh-aw/mcp-config/config.toml\" << GH_AW_CODEX_SHELL_POLICY_NORM_EOF") + if syncStart == -1 { + t.Fatalf("Expected config sync heredoc start in generated config, got:\n%s", normalizedResult) + } + + syncBodyStart := strings.Index(normalizedResult[syncStart:], "\n") + if syncBodyStart == -1 { + t.Fatalf("Expected newline after config sync heredoc start, got:\n%s", normalizedResult[syncStart:]) + } + syncBodyOffset := syncStart + syncBodyStart + 1 + + syncEnd := strings.Index(normalizedResult[syncBodyOffset:], "\n GH_AW_CODEX_SHELL_POLICY_NORM_EOF") + if syncEnd == -1 { + t.Fatalf("Expected config sync heredoc end in generated config, got:\n%s", normalizedResult) + } + + syncBlock := normalizedResult[syncBodyOffset : syncBodyOffset+syncEnd] + modelProviderIndex := strings.Index(syncBlock, "model_provider = \"openai-proxy\"") + shellPolicyIndex := strings.Index(syncBlock, "[shell_environment_policy]") + if modelProviderIndex == -1 || shellPolicyIndex == -1 { + t.Fatalf("Expected model_provider and shell_environment_policy in sync block, got:\n%s", syncBlock) + } + if modelProviderIndex > shellPolicyIndex { + t.Errorf("Expected model_provider to be emitted before [shell_environment_policy] in sync block, got:\n%s", syncBlock) + } }) t.Run("does not inject openai-proxy provider when firewall is disabled", func(t *testing.T) { diff --git a/pkg/workflow/codex_mcp.go b/pkg/workflow/codex_mcp.go index 896ea3a4c0..b01dea62ba 100644 --- a/pkg/workflow/codex_mcp.go +++ b/pkg/workflow/codex_mcp.go @@ -125,10 +125,10 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an shellPolicyDelimiter := GenerateHeredocDelimiterFromSeed("CODEX_SHELL_POLICY", workflowData.FrontmatterHash) yaml.WriteString(" cat > \"/tmp/gh-aw/mcp-config/config.toml\" << " + shellPolicyDelimiter + "\n") - e.renderShellEnvironmentPolicyToml(yaml, tools, mcpTools, " ") if isFirewallEnabled(workflowData) { e.renderOpenAIProxyProviderToml(yaml, " ") } + e.renderShellEnvironmentPolicyToml(yaml, tools, mcpTools, " ") yaml.WriteString(" " + shellPolicyDelimiter + "\n") if isFirewallEnabled(workflowData) { e.renderAppendConvertedConfigWithoutOpenAIProxy(yaml)