Refactor copilot SDK driver into self-contained Node program#36549
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…r message, fix harness terminology Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@copilot the server should be started in copilot_harness.cjs and the driver should only open a client |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
- copilot_harness.cjs: starts sidecar in driver mode using copilot binary from args[1] and GH_AW_COPILOT_SDK_SERVER_ARGS; always generates and injects COPILOT_CONNECTION_TOKEN; always stops sidecar in finally block - copilot_sdk_driver.cjs: main() no longer manages sidecar; reads COPILOT_CONNECTION_TOKEN from env and connects as client only Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in 5b57b4c. The sidecar is now started by |
There was a problem hiding this comment.
Pull request overview
This PR refactors the Copilot SDK driver from a module-only helper into a standalone Node program that is invoked as a normal subprocess by the Copilot harness, shifting configuration from a stdin JSON payload to environment variables. This aligns the Copilot SDK execution path with other “command-style” engines and provides a concrete sample for building Copilot SDK driver extensions.
Changes:
- Adds a standalone
main()entry point tocopilot_sdk_driver.cjs(guarded byrequire.main === module) and reads SDK configuration from env vars. - Introduces new engine constants (
GH_AW_COPILOT_SDK_DRIVER,GH_AW_COPILOT_SDK_SERVER_ARGS) and updates the Copilot engine tests to assert the new env-driven/driver-mode behavior. - Updates numerous workflow
*.lock.ymlfiles to use the new harness invocation pattern and env vars (no stdin JSON piping).
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/copilot_engine_test.go | Updates SDK-mode expectations for driver-mode env vars and removes stdin-payload assertions. |
| pkg/constants/engine_constants.go | Adds new env var constants for Copilot SDK driver mode and sidecar argv transport. |
| actions/setup/js/copilot_sdk_driver.cjs | Adds standalone program entry point that reads configuration from env vars and runs one SDK session. |
| .github/workflows/smoke-copilot-sdk.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/q.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/python-data-charts.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/pr-triage-agent.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/pr-nitpick-reviewer.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/pr-code-quality-reviewer.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/plan.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/pdf-summary.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/org-health-report.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/metrics-collector.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/mcp-inspector.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/linter-miner.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/layout-spec-maintainer.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/jsweep.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/firewall.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/firewall-escape.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/draft-pr-cleanup.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/docs-noob-tester.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/discussion-task-miner.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/dictation-prompt.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/dev-hawk.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/deployment-incident-monitor.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/delight.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/dead-code-remover.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-workflow-updater.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-syntax-error-quality.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-spdd-spec-planner.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-skill-optimizer.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-sentrux-report.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-security-observability.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-secrets-analysis.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-repo-chronicle.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-performance-summary.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-model-inventory.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-malicious-code-scan.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-issues-report.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-geo-optimizer.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-experiment-report.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-compiler-threat-spec-optimizer.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-cli-performance.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-assign-issue-to-user.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-architecture-diagram.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/daily-agent-of-the-day-blog-writer.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/craft.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/copilot-pr-prompt-analysis.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/copilot-pr-nlp-analysis.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/copilot-pr-merged-report.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/copilot-opt.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/copilot-cli-deep-research.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/code-scanning-fixer.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/cli-consistency-checker.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/ci-coach.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/breaking-change-checker.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/brave.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/artifacts-summary.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/architecture-guardian.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
| .github/workflows/agent-performance-analyzer.lock.yml | Switches locked command to driver-mode harness invocation and sets new env vars. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 68/68 changed files
- Comments generated: 2
| // CopilotSDKServerArgsEnvVar is the environment variable that holds the JSON-encoded | ||
| // CLI argument array for the headless Copilot CLI sidecar started by copilot_sdk_driver.cjs. | ||
| // The array includes all server control and configuration flags | ||
| // (--headless, --no-auto-update, --port, --add-dir, --log-level, etc.) | ||
| // that the engine computes at compile time. The driver reads this variable at | ||
| // runtime to start the sidecar without any argument parsing. |
| const model = process.env.COPILOT_MODEL || undefined; | ||
| const connectionToken = process.env.COPILOT_CONNECTION_TOKEN || undefined; | ||
|
|
|
|
|
|
|
✅ Design Decision Gate 🏗️ completed the design decision gate check. No ADR enforcement needed: PR #36549 does not have the 'implementation' label and has 92 new lines of code in business logic directories, which is at or below the 100-line threshold (has_implementation_label=false, requires_adr_by_default_volume=false, has_custom_config=false). |
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅ |
|
🧪 Test Quality Sentinel completed test quality analysis. |
🧪 Test Quality Sentinel Report✅ Test Quality Score: 92/100 — Excellent
📊 Metrics & Test Classification (1 test analyzed)
Test Classification Details
Language SupportTests analyzed:
Verdict📖 Understanding Test ClassificationsDesign Tests (High Value) verify what the system does:
Implementation Tests (Low Value) verify how the system does it:
References: §26857895846
|
There was a problem hiding this comment.
Test Quality Sentinel: 92/100. Test quality is acceptable - 0% of modified tests are implementation tests (threshold: 30%). The single modified test adapts behavioral contract assertions from stdin-pipe to env-var-based configuration. No coding-guideline violations detected.
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /improve-codebase-architecture and /zoom-out — commenting with observations, no hard blockers.
📋 Key Themes & Highlights
Key Themes
- Provider/AWF reflection gap: Driver mode's
main()callsrunWithCopilotSDKwithoutprovider, silently skipping the custom provider config that inline mode injects viasdkCustomProviderConfig. Workflows withAWF_REFLECT_ENABLED=1lose the reflection proxy when running in driver mode. - Phantom argv: The copilot binary path is threaded into the driver subprocess's
process.argvbutmain()reads all config from env vars — the positional arg is unused and undocumented. Confusing for the extension-sample audience this PR targets. - Dual-mode harness: Inline SDK mode (stdin JSON pipe) is preserved alongside the new driver mode with no deprecation signal. This doubles the harness's internal branching for SDK flows.
- Weak test coverage of
GH_AW_COPILOT_SDK_SERVER_ARGS: Triple-fallback quoting check means the assertion only catches a completely absent key, not a malformed value.
Positive Highlights
- ✅ Clean separation: sidecar lifecycle stays with the harness, SDK client logic moves to the driver — a solid division of responsibility.
- ✅ Env-var-based configuration is more robust than the stdin JSON pipe for subprocess boundaries.
- ✅ Good inline comments throughout, especially the Go engine explaining
copilotSDKServerArgsJSONpre-declaration. - ✅ Removing
copilotSDKStdinOptionsstruct and the single-quote escaping logic is a meaningful simplification. - ✅
require.main === modulepattern is idiomatic for a dual-role CommonJS module.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 3.3M
|
|
||
| // --- Run SDK session ------------------------------------------------- | ||
|
|
||
| const result = await runWithCopilotSDK({ |
There was a problem hiding this comment.
[/improve-codebase-architecture] provider (AWF reflection proxy config) is silently dropped in driver mode — workflows using AWF_REFLECT_ENABLED=1 will run without the custom provider.
💡 Details
In inline mode the harness resolves sdkCustomProviderConfig from the AWF reflect API and passes it to runWithCopilotSDK. In driver mode, main() calls runWithCopilotSDK without provider, so the AWF reflection proxy is never used even when AWF_REFLECT_ENABLED=1.
If this is intentional (driver mode does not yet support custom providers), it should be documented here and the harness should log a warning when AWF_REFLECT_ENABLED=1 and driver mode is active. If unintentional, consider passing provider via an env var (e.g. GH_AW_COPILOT_PROVIDER_JSON) similar to how server args are passed.
| // Server args are provided via GH_AW_COPILOT_SDK_SERVER_ARGS (JSON-encoded CLI arg list | ||
| // generated by the Go engine). The copilot binary is args[1] in the driver command: | ||
| // node copilot_harness.cjs $GH_AW_NODE_EXEC copilot_sdk_driver.cjs <copilot-binary> | ||
| const copilotBin = args[1]; |
There was a problem hiding this comment.
[/zoom-out] args[1] (the copilot binary path) is passed through to the driver subprocess via currentArgs, but copilot_sdk_driver.cjs's main() never reads process.argv — all config comes from env vars. This creates a phantom positional argument that future extension authors will find confusing.
💡 Details
The harness uses args[1] only to start the sidecar (correct). Then runProcess({ command, args: currentArgs }) spawns the driver with currentArgs = [copilot_sdk_driver.cjs, copilot-binary] so the driver receives the copilot binary as process.argv[3] — but ignores it.
Since this PR's stated goal is to make the driver a sample for extension authors, having a silently-ignored argv is a footgun. Consider either:
- Removing the copilot binary from the driver's args (pass it only via
GH_AW_COPILOT_SDK_SERVER_ARGSalready set in env), or - Documenting in
main()thatprocess.argv[2]carries the copilot binary and is intentionally unused.
| // Driver mode: the engine started copilot_sdk_driver.cjs as a standalone command. | ||
| // The harness starts the sidecar and then runs the driver like any other subprocess; | ||
| // the driver only opens an SDK client connection to the already-running server. | ||
| const copilotSDKDriverMode = copilotSDKMode && process.env.GH_AW_COPILOT_SDK_DRIVER === "1"; |
There was a problem hiding this comment.
[/improve-codebase-architecture] Inline SDK mode (stdin JSON pipe) is retained alongside the new driver mode, so both code paths coexist permanently. If driver mode is now the canonical path for copilot-sdk: true, consider whether inline mode should be deprecated.
💡 Details
The PR description frames driver mode as the new architecture, but the old readSDKOptionsFromStdin path remains active for copilotSDKMode && !copilotSDKDriverMode. The flag GH_AW_COPILOT_SDK_DRIVER gates the fork, making the harness perpetually maintain two SDK execution paths.
If inline mode will eventually be removed, a // TODO: deprecate inline SDK mode (#XXXX) comment here would signal intent and prevent future engineers from investing in the dead path. If both are deliberately supported long-term, a brief comment explaining the use-case difference would help.
|
|
||
| // GH_AW_COPILOT_SDK_SERVER_ARGS must carry the JSON-encoded server arg list. | ||
| if !strings.Contains(stepContent, constants.CopilotSDKServerArgsEnvVar+":'") && | ||
| !strings.Contains(stepContent, constants.CopilotSDKServerArgsEnvVar+": '") { |
There was a problem hiding this comment.
[/tdd] The GH_AW_COPILOT_SDK_SERVER_ARGS assertion has triple fallback quoting checks — it passes as long as the env var key appears anywhere in the content, regardless of value format. This doesn't actually verify the server args are well-formed JSON.
💡 Suggested tightening
The current assertion:
if !strings.Contains(stepContent, constants.CopilotSDKServerArgsEnvVar+":'">) &&
!strings.Contains(stepContent, constants.CopilotSDKServerArgsEnvVar+": '") {
if !strings.Contains(stepContent, constants.CopilotSDKServerArgsEnvVar+":") {
t.Fatalf(...)
}
}effectively only fails if the key is completely absent. Separately, --headless and --port are checked globally in stepContent, not scoped to the server-args value.
Consider extracting the env var value from the step content and verifying it parses as valid JSON containing the expected flags. At minimum, scope the --headless check to the text after GH_AW_COPILOT_SDK_SERVER_ARGS:
serverArgsIdx := strings.Index(stepContent, constants.CopilotSDKServerArgsEnvVar)
require.Greater(t, serverArgsIdx, -1, "GH_AW_COPILOT_SDK_SERVER_ARGS must be present")
afterArgs := stepContent[serverArgsIdx:]
assert.Contains(t, afterArgs, `"--headless"`, "server args must include --headless")| // GH_AW_COPILOT_SDK_SERVER_ARGS when copilot-sdk: true. It is declared here so that the | ||
| // env-block section further down can reference the same value that was computed while | ||
| // building the command, avoiding the need to re-derive it separately. | ||
| var copilotSDKServerArgsJSON string |
There was a problem hiding this comment.
[/zoom-out] copilotSDKServerArgsJSON is declared at the top of a long function and only assigned ~48 lines later in the isCopilotSDKMode branch. Declaring it next to its assignment site (or inlining it) would reduce cognitive distance, since readers must track the variable across unrelated code paths.
💡 Suggestion
Since copilotSDKServerArgsJSON is only ever set and consumed inside if isCopilotSDKMode { ... } blocks, moving the declaration into that block or into a small helper function would make the scope explicit and avoid the need for the explanatory comment bridging the two locations.
Alternatively, the existing comment explaining the variable's purpose is valuable — consider keeping the comment but moving the var declaration just before the if isCopilotSDKMode { block where serverArgs is computed.
|
|
|
@copilot review all comments and previews . Apply copilot-review skill |
Implemented in f1b5171 (plus 311c0be): I simplified/refactored SDK driver-mode server-args handling by extracting validated env parsing into a dedicated helper, added clearer driver-mode sidecar startup diagnostics, and expanded focused tests for parsing edge cases. I also clarified harness-vs-driver responsibility comments in the related Go constants/execution paths. |
|
|
|
/smoke-copilot-sdk |
|
✅ All tools validated successfully! Agent Container Smoke Test confirms agent container is ready. |
|
💫 TO BE CONTINUED... Smoke Claude failed! Our hero faces unexpected challenges... |
|
🚀 Smoke Antigravity MISSION COMPLETE! Antigravity has spoken. ✨ |
|
🚀 Smoke Pi MISSION COMPLETE! Pi delivered. 🥧 |
|
✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟 |
|
✅ Smoke Copilot SDK completed successfully! |
|
🚀 Smoke Gemini MISSION COMPLETE! Gemini has spoken. ✨ |
|
📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing... |
Agent Container Tool Check
Result: 12/12 tools available ✅ Overall Status: PASS
|
Smoke Test Results
Overall Status: FAIL Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "localhost"See Network Configuration for more information.
|
|
Commit pushed:
|
|
Smoke test summary for run 26879446434:
|
Comment MemoryNote This comment is managed by comment memory.It stores persistent context for this thread in the code block at the top of this comment.
|
💨 Smoke Test: Claude — Run 26879446391Core #1–13: ✅ all passed Overall: PARTIAL (1 intentional skip) — run Warning Firewall blocked 6 domainsThe following domains were blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "accounts.google.com"
- "android.clients.google.com"
- "clients2.google.com"
- "contentautofill.googleapis.com"
- "safebrowsingohttpgateway.googleapis.com"
- "www.google.com"See Network Configuration for more information.
|
There was a problem hiding this comment.
💥 Automated smoke test review - all systems nominal!
Warning
Firewall blocked 6 domains
The following domains were blocked by the firewall during workflow execution:
accounts.google.comandroid.clients.google.comclients2.google.comcontentautofill.googleapis.comsafebrowsingohttpgateway.googleapis.comwww.google.com
To allow these domains, add them to the
network.allowedlist in your workflow frontmatter:
network:
allowed:
- defaults
- "accounts.google.com"
- "android.clients.google.com"
- "clients2.google.com"
- "contentautofill.googleapis.com"
- "safebrowsingohttpgateway.googleapis.com"
- "www.google.com"See Network Configuration for more information.
💥 [THE END] — Illustrated by Smoke Claude · opus48 5.1M
| @@ -0,0 +1,5 @@ | |||
| --- | |||
| "gh-aw": patch | |||
There was a problem hiding this comment.
Smoke test review: changeset bump type looks correct (patch). ✅
| "gh-aw": patch | ||
| --- | ||
|
|
||
| Refactored the Copilot SDK driver into a standalone Node program launched by the harness with environment-based configuration. |
There was a problem hiding this comment.
Smoke test review: clear, concise changeset summary. Nice. 👍
|
Titles: Refactor copilot SDK driver into self-contained Node program | Add Warning Firewall blocked 6 domainsThe following domains were blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "accounts.google.com"
- "android.clients.google.com"
- "clients2.google.com"
- "contentautofill.googleapis.com"
- "safebrowsingohttpgateway.googleapis.com"
- "www.google.com"See Network Configuration for more information.
|
copilot_sdk_driver.cjswas a module-only export; the harness managed the sidecar and SDK session inline, receiving configuration through a JSON payload piped via stdin. This refactors the driver into a standalone program started by the harness like any other command, with configuration via environment variables — serving as a sample for how to create a Copilot SDK driver extension in agentic-workflows.Architecture change
Before:
Harness reads stdin JSON, starts sidecar, manages SDK session inline.
After:
node harness.cjs "$GH_AW_NODE_EXEC" copilot_sdk_driver.cjs copilotHarness starts the sidecar, then runs the driver subprocess as a pure SDK client. The driver connects to the already-running server, runs the SDK session, and exits.
Changes
copilot_sdk_driver.cjs— addsmain()entry point +require.main === moduleguard; readsGH_AW_PROMPT,COPILOT_SDK_URI,COPILOT_CONNECTION_TOKEN,COPILOT_MODELfrom env; connects to the harness-managed sidecar as a client only (no sidecar lifecycle management)copilot_harness.cjs— addscopilotSDKDriverMode(GH_AW_COPILOT_SDK_DRIVER=1); in driver mode, starts the sidecar using the copilot binary fromargs[1]andGH_AW_COPILOT_SDK_SERVER_ARGS; always generates and injectsCOPILOT_CONNECTION_TOKEN; always stops the sidecar in thefinallyblock; usesrunProcessto run the driver subprocesscopilot_engine_execution.go— removescopilotSDKStdinOptionsstruct and stdin-pipe command format; emits driver script path in command args; setsGH_AW_COPILOT_SDK_DRIVER=1andGH_AW_COPILOT_SDK_SERVER_ARGS(JSON-encoded sidecar argv) in step envengine_constants.go— addsCopilotSDKServerArgsEnvVarandCopilotSDKDriverEnvVarNew env vars
GH_AW_COPILOT_SDK_DRIVERGH_AW_COPILOT_SDK_SERVER_ARGSBackward compatibility
The original harness-managed SDK path (stdin JSON + inline sidecar) is preserved when
GH_AW_COPILOT_SDK_DRIVERis unset. All existing exports fromcopilot_sdk_driver.cjsare unchanged.Updated branch for run https://github.com/github/gh-aw/actions/runs/26877286775.
✨ PR Review Safe Output Test - Run 26879446391
Warning
Firewall blocked 6 domains
The following domains were blocked by the firewall during workflow execution:
accounts.google.comandroid.clients.google.comclients2.google.comcontentautofill.googleapis.comsafebrowsingohttpgateway.googleapis.comwww.google.comSee Network Configuration for more information.