buildPullAWFContainersStep creates a step that pre-pulls AWF (agent workflow firewall) container images in the detection job. The detection engine runs inside AWF, which uses three containers (squid, agent, api-proxy). Pre-pulling avoids on-demand pulls at runtime. Only AWF images are pulled here; M
(data *WorkflowData)
| 71 | // three containers (squid, agent, api-proxy). Pre-pulling avoids on-demand pulls at runtime. |
| 72 | // Only AWF images are pulled here; MCP server images are not needed for detection. |
| 73 | func (c *Compiler) buildPullAWFContainersStep(data *WorkflowData) []string { |
| 74 | // Build a minimal WorkflowData that represents the detection engine context so |
| 75 | // collectDockerImages returns only the AWF firewall images (no MCP tool images). |
| 76 | engineSetting := data.AI |
| 77 | if engineSetting == "" { |
| 78 | engineSetting = "claude" |
| 79 | } |
| 80 | detectionData := &WorkflowData{ |
| 81 | Tools: map[string]any{}, |
| 82 | AI: engineSetting, |
| 83 | SandboxConfig: &SandboxConfig{ |
| 84 | Agent: &AgentSandboxConfig{ |
| 85 | Type: SandboxTypeAWF, |
| 86 | }, |
| 87 | }, |
| 88 | ActionCache: data.ActionCache, // Propagate cache so container digest pins are applied |
| 89 | Features: data.Features, // Propagate features so cli-proxy image is included when enabled |
| 90 | } |
| 91 | |
| 92 | images := collectDockerImages(detectionData.Tools, detectionData, c.actionMode) |
| 93 | if len(images) == 0 { |
| 94 | return nil |
| 95 | } |
| 96 | |
| 97 | var b strings.Builder |
| 98 | generateDownloadDockerImagesStep(&b, images) |
| 99 | if b.Len() == 0 { |
| 100 | return nil |
| 101 | } |
| 102 | |
| 103 | // Split the generated YAML into individual lines so each is a separate entry |
| 104 | lines := strings.Split(b.String(), "\n") |
| 105 | var steps []string |
| 106 | for _, line := range lines { |
| 107 | if line != "" { |
| 108 | steps = append(steps, line+"\n") |
| 109 | } |
| 110 | } |
| 111 | return steps |
| 112 | } |
| 113 | |
| 114 | // getThreatDetectionEngineID returns the effective engine ID for the detection job. |
| 115 | // It mirrors threat-detection engine resolution: threat-detection.engine overrides main engine. |