Skip to content

Add --add-dir for Copilot plugin discovery in sandbox mode#14296

Merged
pelikhan merged 3 commits intomainfrom
copilot/fix-copilot-plugin-discovery
Feb 7, 2026
Merged

Add --add-dir for Copilot plugin discovery in sandbox mode#14296
pelikhan merged 3 commits intomainfrom
copilot/fix-copilot-plugin-discovery

Conversation

Copy link
Contributor

Copilot AI commented Feb 7, 2026

Plugins installed via copilot plugin install are stored at ~/.copilot/plugins/, but the Copilot CLI cannot discover them in sandbox mode because ~/.copilot/ is not included in the --add-dir arguments that control directory access permissions.

Changes

pkg/workflow/copilot_engine_execution.go

  • Add --add-dir /home/runner/.copilot/ when workflowData.Plugins is non-empty and sandbox mode (AWF or SRT) is enabled
  • Placed after workspace directory addition to maintain consistent ordering

pkg/workflow/copilot_engine_test.go

  • Add TestCopilotEnginePluginDiscoveryInSandboxMode: validates flag presence/absence across 4 scenarios (plugins with/without firewall, with/without sandbox)
  • Add TestCopilotEnginePluginDiscoveryWithSRT: validates SRT-specific behavior

Example

When a workflow declares plugins with firewall enabled:

---
plugins:
  - github/auto-agentics
network:
  firewall: true
---

The compiled workflow now includes:

copilot --add-dir /tmp/gh-aw/ --add-dir "${GITHUB_WORKSPACE}" --add-dir /home/runner/.copilot/ ...

Why /home/runner/.copilot/ vs /home/runner/.copilot/plugins/

The CLI requires access to the parent directory to read plugin-index.json for plugin discovery. The directory also contains mcp-config.json already referenced by the installer script.

Original prompt

Problem

When a workflow declares plugins: in its frontmatter (e.g., plugins: [github/auto-agentics]), the compiled lock file correctly generates a copilot plugin install step that installs the plugin to ~/.copilot/plugins/. However, when the Copilot CLI is later launched inside the AWF sandbox, it cannot discover the installed plugins because ~/.copilot/ is not included in the --add-dir arguments passed to the Copilot CLI.

The --add-dir flag tells the Copilot CLI which directories it's allowed to scan for agent files, skills, and plugins. Currently in sandbox mode, only /tmp/gh-aw/ and ${GITHUB_WORKSPACE} are added:

// In pkg/workflow/copilot_engine_execution.go, lines 48-55
copilotArgs = []string{"--add-dir", "/tmp/gh-aw/", "--log-level", "all", "--log-dir", logsFolder}
copilotArgs = append(copilotArgs, "--add-dir", "\"${GITHUB_WORKSPACE}\"")

Plugins installed via copilot plugin install are stored at ~/.copilot/plugins/ (which resolves to /home/runner/.copilot/plugins/ on GitHub Actions runners). Without --add-dir pointing to this directory, the Copilot CLI won't scan it for installed plugin content (skills, agents, MCP configs).

Solution

In pkg/workflow/copilot_engine_execution.go, when workflowData.Plugins is non-empty and we're in sandbox mode, add --add-dir for the Copilot config home directory (/home/runner/.copilot/) to the Copilot CLI arguments. This should be added in the sandbox-enabled block where the other --add-dir flags are constructed.

Use /home/runner/.copilot/ (not just /home/runner/.copilot/plugins/) because:

  1. The CLI also reads plugin-index.json from ~/.copilot/ to discover installed plugins
  2. The MCP config is already written to /home/runner/.copilot/mcp-config.json
  3. The gh-aw installer script already hardcodes COPILOT_DIR="/home/runner/.copilot" in actions/setup/sh/install_copilot_cli.sh

The change should look something like:

if sandboxEnabled {
    copilotArgs = []string{"--add-dir", "/tmp/gh-aw/", "--log-level", "all", "--log-dir", logsFolder}
    copilotArgs = append(copilotArgs, "--add-dir", "\"${GITHUB_WORKSPACE}\"")
    
    // Add Copilot config directory when plugins are declared so the CLI can discover installed plugins
    if len(workflowData.Plugins) > 0 {
        copilotArgs = append(copilotArgs, "--add-dir", "/home/runner/.copilot/")
        copilotExecLog.Print("Added Copilot config directory to --add-dir for plugin discovery")
    }
    
    copilotExecLog.Print("Using firewall mode with simplified arguments")
}

Testing

Add tests in the appropriate test file (likely pkg/workflow/copilot_engine_test.go or pkg/workflow/copilot_engine_execution_test.go or similar) to verify:

  1. When workflowData.Plugins is non-empty and sandbox is enabled, the generated command includes --add-dir /home/runner/.copilot/
  2. When workflowData.Plugins is empty, the command does NOT include --add-dir /home/runner/.copilot/
  3. The behavior is correct in both AWF (firewall) and non-sandbox modes

Context

  • Plugin install path confirmed via DeepWiki analysis of copilot-cli: ~/.copilot/plugins/
  • The gh-aw install script already uses COPILOT_DIR="/home/runner/.copilot"
  • Session state is copied from $HOME/.copilot/session-state (see pkg/workflow/copilot_logs.go)
  • AWF --enable-chroot gives full host filesystem access, so the files ARE on disk — it's just the Copilot CLI's --add-dir permission check that blocks discovery

This pull request was created from Copilot chat.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits February 7, 2026 06:31
Co-authored-by: patrickcarnahan <17889693+patrickcarnahan@users.noreply.github.com>
Co-authored-by: patrickcarnahan <17889693+patrickcarnahan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix plugin discovery in Copilot CLI sandbox mode Add --add-dir for Copilot plugin discovery in sandbox mode Feb 7, 2026
Copilot AI requested a review from patrickcarnahan February 7, 2026 06:39
@github-actions github-actions bot added cli enhancement New feature or request mcp labels Feb 7, 2026
@pelikhan pelikhan marked this pull request as ready for review February 7, 2026 13:22
Copilot AI review requested due to automatic review settings February 7, 2026 13:23
@pelikhan pelikhan merged commit bd06387 into main Feb 7, 2026
123 of 125 checks passed
@pelikhan pelikhan deleted the copilot/fix-copilot-plugin-discovery branch February 7, 2026 13:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes GitHub Copilot CLI plugin discovery when workflows run in sandboxed modes (AWF firewall or SRT). Since plugins installed via copilot plugin install live under ~/.copilot/, the Copilot CLI needs that directory explicitly allowlisted via --add-dir in sandbox mode.

Changes:

  • Add --add-dir /home/runner/.copilot/ to Copilot CLI arguments when sandbox mode is enabled and workflowData.Plugins is non-empty.
  • Add unit tests covering flag presence/absence across firewall/non-firewall and SRT scenarios, including ordering after the workspace --add-dir.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
pkg/workflow/copilot_engine_execution.go Adds sandbox-mode --add-dir for /home/runner/.copilot/ when plugins are declared so Copilot can discover installed plugins.
pkg/workflow/copilot_engine_test.go Adds tests validating the new --add-dir behavior for AWF (firewall) and SRT sandboxes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 7, 2026

🛡️ Security Posture Analysis

This PR contains changes that may affect the security posture. Please review the following concerns:

🟠 Network/Sandbox Boundary Expansion: Mounting Copilot config dir

Location: pkg/workflow/copilot_engine_execution.go:56-63

Change Detected:

@@
-	copilotArgs = append(copilotArgs, "--add-dir", "\"${GITHUB_WORKSPACE}\"")
-	copilotExecLog.Print("Added workspace directory to --add-dir")
+	copilotArgs = append(copilotArgs, "--add-dir", "\"${GITHUB_WORKSPACE}\"")
+	copilotExecLog.Print("Added workspace directory to --add-dir")
+
+	// Add Copilot config directory when plugins are declared so the CLI can discover installed plugins
+	if len(workflowData.Plugins) > 0 {
+		copilotArgs = append(copilotArgs, "--add-dir", "/home/runner/.copilot/")
+		copilotExecLog.Printf("Added Copilot config directory to --add-dir for plugin discovery (%d plugins)", len(workflowData.Plugins))
+	}

Security Impact: GetExecutionSteps is invoked inside AWF/SRT sandbox mode, which by default only exposes /tmp/gh-aw/ and the workspace. With this change, any plugin-enabled workflow now also mounts the runner’s /home/runner/.copilot/ directory into the sandbox. The Copilot installer (actions/setup/sh/install_copilot_cli.sh, lines 24‑34) explicitly manages that directory because it stores the Copilot CLI configuration, including the authenticated GitHub token. Granting sandboxed plugin code read access to /home/runner/.copilot/ leaks those credentials to any plugin that runs during the workflow.

Recommendation: Avoid mounting the full Copilot config directory into the sandbox. Instead, expose only the minimal plugin metadata files (e.g., the plugin index) through a controlled copy or pass COPILOT_PLUGIN_PATH explicitly, so sandboxed plugin runs cannot read the stored authentication tokens.


Summary

Category Severity Count
Sandbox/Network Boundary 🟠 1

Note: This is an automated analysis. Please verify these findings and determine if the changes are intentional and justified.

AI generated by Security Guard Agent 🛡️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli enhancement New feature or request mcp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants