diff --git a/pkg/workflow/codex_engine.go b/pkg/workflow/codex_engine.go index 9b09d45a092..77a18f56270 100644 --- a/pkg/workflow/codex_engine.go +++ b/pkg/workflow/codex_engine.go @@ -236,6 +236,17 @@ func (e *CodexEngine) GetExecutionSteps(workflowData *WorkflowData, logFile stri codexCommandWithSetup = fmt.Sprintf("%s && %s", mcpCLIPath, codexCommandWithSetup) } + excludeEnvVarNames := ComputeAWFExcludeEnvVarNames(workflowData, []string{"CODEX_API_KEY", "OPENAI_API_KEY"}) + // Codex CLI must read API credentials from environment variables directly. + // Keep CODEX_API_KEY/OPENAI_API_KEY available in-container; only exclude other secret vars. + var filteredExcludeEnvVarNames []string + for _, name := range excludeEnvVarNames { + if name == "CODEX_API_KEY" || name == "OPENAI_API_KEY" { + continue + } + filteredExcludeEnvVarNames = append(filteredExcludeEnvVarNames, name) + } + command = BuildAWFCommand(AWFCommandConfig{ EngineName: "codex", EngineCommand: codexCommandWithSetup, @@ -248,8 +259,9 @@ func (e *CodexEngine) GetExecutionSteps(workflowData *WorkflowData, logFile stri // appended to $GITHUB_STEP_SUMMARY after secret redaction. PathSetup: "mkdir -p \"$CODEX_HOME/logs\" && touch " + AgentStepSummaryPath, // Exclude every env var whose step-env value is a secret so the agent - // cannot read raw token values via bash tools (env / printenv). - ExcludeEnvVarNames: ComputeAWFExcludeEnvVarNames(workflowData, []string{"CODEX_API_KEY", "OPENAI_API_KEY"}), + // cannot read raw token values via bash tools (env / printenv), except + // CODEX_API_KEY/OPENAI_API_KEY which Codex needs for API authentication. + ExcludeEnvVarNames: filteredExcludeEnvVarNames, }) } else { // Build the command without AWF wrapping. diff --git a/pkg/workflow/codex_engine_test.go b/pkg/workflow/codex_engine_test.go index 027ee79f05d..e9ac32ffa43 100644 --- a/pkg/workflow/codex_engine_test.go +++ b/pkg/workflow/codex_engine_test.go @@ -776,6 +776,40 @@ func TestCodexEngineEnvOverridesTokenExpression(t *testing.T) { }) } +func TestCodexEngineAWFDoesNotExcludeAuthEnvVars(t *testing.T) { + engine := NewCodexEngine() + + workflowData := &WorkflowData{ + Name: "test-workflow", + ParsedTools: &ToolsConfig{ + GitHub: &GitHubToolConfig{}, + }, + NetworkPermissions: &NetworkPermissions{ + Allowed: []string{"defaults"}, + Firewall: &FirewallConfig{ + Enabled: true, + }, + }, + } + + steps := engine.GetExecutionSteps(workflowData, "/tmp/gh-aw/test.log") + if len(steps) != 1 { + t.Fatalf("Expected 1 step, got %d", len(steps)) + } + + stepContent := strings.Join(steps[0], "\n") + + if strings.Contains(stepContent, "--exclude-env CODEX_API_KEY") { + t.Errorf("Codex API key env var must not be excluded from AWF container, got:\n%s", stepContent) + } + if strings.Contains(stepContent, "--exclude-env OPENAI_API_KEY") { + t.Errorf("OpenAI API key env var must not be excluded from AWF container, got:\n%s", stepContent) + } + if !strings.Contains(stepContent, "--exclude-env GITHUB_MCP_SERVER_TOKEN") { + t.Errorf("Expected non-Codex secret env vars to still be excluded, got:\n%s", stepContent) + } +} + func TestCodexEngineWebSearch(t *testing.T) { engine := NewCodexEngine()