Skip to content

Commit 0c5dcc6

Browse files
Copilotpelikhan
andauthored
Restore Codex default-deny fetch behavior for workflow compilation (#34726)
* fix: disable codex fetch unless web-fetch tool is configured Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * test: align codex fetch test naming and comments Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * docs: clarify codex fetch override comments Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * docs: tighten fetch override wording Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Co-authored-by: Peli de Halleux <pelikhan@users.noreply.github.com>
1 parent af33b01 commit 0c5dcc6

2 files changed

Lines changed: 17 additions & 8 deletions

File tree

pkg/workflow/codex_engine.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,22 @@ func (e *CodexEngine) GetExecutionSteps(workflowData *WorkflowData, logFile stri
166166
// Codex enables web search by default, so we must explicitly set web_search="disabled" to disable it.
167167
// The --no-search flag does not exist; use the -c web_search="disabled" config option instead.
168168
// See https://developers.openai.com/codex/cli/features#web-search
169-
// Leading space is intentional: the format string concatenates this directly after "exec" with no space separator.
169+
// Leading space is intentional: these params are concatenated directly and need their own separator.
170170
webSearchParam := ` -c web_search="disabled"`
171171
if workflowData.ParsedTools != nil && workflowData.ParsedTools.WebSearch != nil {
172172
// Web search is enabled by default in Codex; no extra flag needed.
173173
webSearchParam = ""
174174
}
175175

176+
// Build fetch parameter: enforce AWF default-deny for fetch unless web-fetch tool is present.
177+
// Codex enables fetch by default, so this code explicitly sets fetch="disabled" unless web-fetch is configured.
178+
// Leading space is intentional: these params are concatenated directly and need their own separator.
179+
webFetchParam := ` -c fetch="disabled"`
180+
if workflowData.ParsedTools != nil && workflowData.ParsedTools.WebFetch != nil {
181+
// When web-fetch is configured, omit override so Codex default fetch behavior remains enabled.
182+
webFetchParam = ""
183+
}
184+
176185
// See https://github.com/github/gh-aw/issues/892
177186
// In AWF mode we bypass Codex approvals/sandboxing because AWF provides the sandbox layer.
178187
// Outside AWF, keep Codex sandboxing enabled and disable approvals for non-interactive execution.
@@ -220,12 +229,12 @@ func (e *CodexEngine) GetExecutionSteps(workflowData *WorkflowData, logFile stri
220229
// Harness-wrapped execution: the harness reads --prompt-file and passes its content
221230
// as the last positional arg. The harness also provides retry logic.
222231
execPrefix := fmt.Sprintf(`%s %s/%s %s`, nodeRuntimeResolutionCommand, SetupActionDestinationShell, harnessScriptName, commandName)
223-
codexCommand = fmt.Sprintf("%s exec%s%s%s%s--prompt-file /tmp/gh-aw/aw-prompts/prompt.txt",
224-
execPrefix, modelParam, webSearchParam, executionPolicyParam, customArgsParam)
232+
codexCommand = fmt.Sprintf("%s exec%s%s%s%s%s--prompt-file /tmp/gh-aw/aw-prompts/prompt.txt",
233+
execPrefix, modelParam, webSearchParam, webFetchParam, executionPolicyParam, customArgsParam)
225234
} else {
226235
// Without harness: use shell expansion for the prompt (no retry logic).
227-
codexCommand = fmt.Sprintf("%s exec%s%s%s%s\"$INSTRUCTION\"",
228-
commandName, modelParam, webSearchParam, executionPolicyParam, customArgsParam)
236+
codexCommand = fmt.Sprintf("%s exec%s%s%s%s%s\"$INSTRUCTION\"",
237+
commandName, modelParam, webSearchParam, webFetchParam, executionPolicyParam, customArgsParam)
229238
}
230239

231240
// Build the full command with agent file handling and AWF wrapping if enabled

pkg/workflow/codex_engine_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ func TestCodexEngineWebSearch(t *testing.T) {
10101010
func TestCodexEngineWebFetch(t *testing.T) {
10111011
engine := NewCodexEngine()
10121012

1013-
t.Run("fetch config is not emitted when tool not specified", func(t *testing.T) {
1013+
t.Run("disables fetch by default when web-fetch tool not specified", func(t *testing.T) {
10141014
workflowData := &WorkflowData{
10151015
Name: "test-workflow",
10161016
}
@@ -1019,8 +1019,8 @@ func TestCodexEngineWebFetch(t *testing.T) {
10191019
t.Fatalf("Expected 1 step, got %d", len(steps))
10201020
}
10211021
stepContent := strings.Join([]string(steps[0]), "\n")
1022-
if strings.Contains(stepContent, `-c fetch="disabled"`) {
1023-
t.Errorf(`Expected no -c fetch="disabled" config when web-fetch tool is not specified, got:\n%s`, stepContent)
1022+
if !strings.Contains(stepContent, `-c fetch="disabled"`) {
1023+
t.Errorf(`Expected -c fetch="disabled" config when web-fetch tool is not specified, got:\n%s`, stepContent)
10241024
}
10251025
})
10261026

0 commit comments

Comments
 (0)