diff --git a/.github/workflows/docs-noob-tester.lock.yml b/.github/workflows/docs-noob-tester.lock.yml index dceec06750..af3b27d10c 100644 --- a/.github/workflows/docs-noob-tester.lock.yml +++ b/.github/workflows/docs-noob-tester.lock.yml @@ -694,7 +694,7 @@ jobs: timeout-minutes: 30 run: | set -o pipefail - sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains '*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deb.nodesource.com,deno.land,get.pnpm.io,github.com,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.npmjs.com,www.npmjs.org,yarnpkg.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.20.1 --skip-pull --enable-api-proxy \ + sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains '*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,cdn.playwright.dev,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,deb.nodesource.com,deno.land,get.pnpm.io,github.com,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.npmjs.com,www.npmjs.org,yarnpkg.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.20.1 --skip-pull --enable-api-proxy \ -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE diff --git a/.github/workflows/slide-deck-maintainer.lock.yml b/.github/workflows/slide-deck-maintainer.lock.yml index 210294c733..a2c918d009 100644 --- a/.github/workflows/slide-deck-maintainer.lock.yml +++ b/.github/workflows/slide-deck-maintainer.lock.yml @@ -755,7 +755,7 @@ jobs: timeout-minutes: 45 run: | set -o pipefail - sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains '*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,bun.sh,deb.nodesource.com,deno.land,get.pnpm.io,github.com,host.docker.internal,jsr.io,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,skimdb.npmjs.com,telemetry.enterprise.githubcopilot.com,www.npmjs.com,www.npmjs.org,yarnpkg.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.20.1 --skip-pull --enable-api-proxy \ + sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains '*.jsr.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,bun.sh,cdn.playwright.dev,deb.nodesource.com,deno.land,get.pnpm.io,github.com,host.docker.internal,jsr.io,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,playwright.download.prss.microsoft.com,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,skimdb.npmjs.com,telemetry.enterprise.githubcopilot.com,www.npmjs.com,www.npmjs.org,yarnpkg.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.20.1 --skip-pull --enable-api-proxy \ -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(cat*)'\'' --allow-tool '\''shell(cd*)'\'' --allow-tool '\''shell(curl*)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(find*)'\'' --allow-tool '\''shell(git add:*)'\'' --allow-tool '\''shell(git branch:*)'\'' --allow-tool '\''shell(git checkout:*)'\'' --allow-tool '\''shell(git commit:*)'\'' --allow-tool '\''shell(git merge:*)'\'' --allow-tool '\''shell(git rm:*)'\'' --allow-tool '\''shell(git status)'\'' --allow-tool '\''shell(git switch:*)'\'' --allow-tool '\''shell(git)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(grep*)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(head*)'\'' --allow-tool '\''shell(kill*)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(ls*)'\'' --allow-tool '\''shell(lsof*)'\'' --allow-tool '\''shell(npm ci*)'\'' --allow-tool '\''shell(npm install*)'\'' --allow-tool '\''shell(npm run*)'\'' --allow-tool '\''shell(npx @marp-team/marp-cli*)'\'' --allow-tool '\''shell(npx http-server*)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(pwd*)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(tail*)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE diff --git a/pkg/workflow/domains.go b/pkg/workflow/domains.go index 49581bc877..389571ff50 100644 --- a/pkg/workflow/domains.go +++ b/pkg/workflow/domains.go @@ -99,6 +99,13 @@ var ClaudeDefaultDomains = []string{ "ts-ocsp.ws.symantec.com", } +// PlaywrightDomains are the domains required for Playwright browser downloads +// These domains are needed when Playwright MCP server initializes in the Docker container +var PlaywrightDomains = []string{ + "cdn.playwright.dev", + "playwright.download.prss.microsoft.com", +} + // init loads the ecosystem domains from the embedded JSON func init() { domainsLog.Print("Loading ecosystem domains from embedded JSON") @@ -349,6 +356,23 @@ func extractHTTPMCPDomains(tools map[string]any) []string { return domains } +// extractPlaywrightDomains returns Playwright domains when Playwright tool is configured +// Returns a slice of domain names required for Playwright browser downloads +// These domains are needed when Playwright MCP server initializes in the Docker container +func extractPlaywrightDomains(tools map[string]any) []string { + if tools == nil { + return []string{} + } + + // Check if Playwright tool is configured + if _, hasPlaywright := tools["playwright"]; hasPlaywright { + domainsLog.Printf("Detected Playwright tool, adding %d domains for browser downloads", len(PlaywrightDomains)) + return PlaywrightDomains + } + + return []string{} +} + // mergeDomainsWithNetwork combines default domains with NetworkPermissions allowed domains // Returns a deduplicated, sorted, comma-separated string suitable for AWF's --allow-domains flag func mergeDomainsWithNetwork(defaultDomains []string, network *NetworkPermissions) string { @@ -388,6 +412,15 @@ func mergeDomainsWithNetworkToolsAndRuntimes(defaultDomains []string, network *N } } + // Add Playwright ecosystem domains (if Playwright tool is specified) + // This ensures browser binaries can be downloaded when Playwright initializes + if tools != nil { + playwrightDomains := extractPlaywrightDomains(tools) + for _, domain := range playwrightDomains { + domainMap[domain] = true + } + } + // Add runtime ecosystem domains (if runtimes are specified) if runtimes != nil { runtimeDomains := getDomainsFromRuntimes(runtimes) diff --git a/pkg/workflow/http_mcp_domains_test.go b/pkg/workflow/http_mcp_domains_test.go index dc9600cea0..78c2746b77 100644 --- a/pkg/workflow/http_mcp_domains_test.go +++ b/pkg/workflow/http_mcp_domains_test.go @@ -232,3 +232,107 @@ func TestGetClaudeAllowedDomainsWithTools(t *testing.T) { require.Contains(t, result, "anthropic.com", "Should include Claude defaults") require.Contains(t, result, "registry.npmjs.org", "Should include Node ecosystem") } + +// TestExtractPlaywrightDomains tests extraction of Playwright ecosystem domains when Playwright tool is configured +func TestExtractPlaywrightDomains(t *testing.T) { + tests := []struct { + name string + tools map[string]any + expected []string + }{ + { + name: "playwright tool configured", + tools: map[string]any{ + "playwright": map[string]any{ + "allowed_domains": []string{"github.com"}, + }, + }, + expected: []string{"playwright.download.prss.microsoft.com", "cdn.playwright.dev"}, + }, + { + name: "playwright tool with empty config", + tools: map[string]any{ + "playwright": map[string]any{}, + }, + expected: []string{"playwright.download.prss.microsoft.com", "cdn.playwright.dev"}, + }, + { + name: "playwright tool with null config", + tools: map[string]any{ + "playwright": nil, + }, + expected: []string{"playwright.download.prss.microsoft.com", "cdn.playwright.dev"}, + }, + { + name: "no playwright tool", + tools: map[string]any{ + "github": map[string]any{ + "mode": "local", + }, + }, + expected: []string{}, + }, + { + name: "empty tools", + tools: map[string]any{}, + expected: []string{}, + }, + { + name: "nil tools", + tools: nil, + expected: []string{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := extractPlaywrightDomains(tt.tools) + + // Sort both slices for comparison + SortStrings(result) + SortStrings(tt.expected) + + assert.Equal(t, tt.expected, result, "Extracted Playwright domains should match expected") + }) + } +} + +// TestGetCopilotAllowedDomainsWithPlaywright tests that Playwright domains are automatically included for Copilot engine +func TestGetCopilotAllowedDomainsWithPlaywright(t *testing.T) { + network := &NetworkPermissions{ + Allowed: []string{"defaults"}, + } + + tools := map[string]any{ + "playwright": map[string]any{ + "allowed_domains": []string{"github.com"}, + }, + } + + result := GetCopilotAllowedDomainsWithTools(network, tools) + + // Should include Copilot defaults and Playwright ecosystem domains + require.Contains(t, result, "playwright.download.prss.microsoft.com", "Should include Playwright download domain") + require.Contains(t, result, "cdn.playwright.dev", "Should include Playwright CDN domain") + require.Contains(t, result, "api.githubcopilot.com", "Should include Copilot defaults") +} + +// TestGetCodexAllowedDomainsWithPlaywright tests that Playwright domains are automatically included for Codex engine +func TestGetCodexAllowedDomainsWithPlaywright(t *testing.T) { + network := &NetworkPermissions{ + Allowed: []string{"defaults"}, + } + + tools := map[string]any{ + "playwright": map[string]any{ + "allowed_domains": []string{"example.com"}, + }, + } + + result := GetCodexAllowedDomainsWithTools(network, tools) + + // Should include Codex defaults and Playwright ecosystem domains + require.Contains(t, result, "playwright.download.prss.microsoft.com", "Should include Playwright download domain") + require.Contains(t, result, "cdn.playwright.dev", "Should include Playwright CDN domain") + require.Contains(t, result, "api.openai.com", "Should include Codex defaults") +}