Skip to content

feat: add write-sink guard policy to all non-GitHub MCP servers configured by gateway#21005

Merged
lpcox merged 3 commits intomainfrom
copilot/update-gh-aw-renderer-config
Mar 15, 2026
Merged

feat: add write-sink guard policy to all non-GitHub MCP servers configured by gateway#21005
lpcox merged 3 commits intomainfrom
copilot/update-gh-aw-renderer-config

Conversation

Copy link
Contributor

Copilot AI commented Mar 15, 2026

Summary

Extends the write-sink guard policy (currently applied only to safe-outputs) to ALL non-GitHub MCP servers exposed by the MCP gateway. The policy is derived from the same GitHub guard-policy parameters (repos/min-integrity), ensuring that as guard policies are rolled out, only GitHub inputs will be filtered while outputs to non-GitHub servers are not restricted.

Background

Previously, only safe-outputs had a write-sink guard policy automatically derived from the GitHub guard-policy. This change makes this the default configuration for all non-GitHub MCP servers, as described in the issue: "Just as safeoutputs is configured as a write-sink to allow all github data to pass, this must also be the default configuration for any non-github mcp server exposed by the gateway."

Changes

New infrastructure

  • deriveWriteSinkGuardPolicyFromWorkflow - Helper that derives write-sink guard policies from workflow's GitHub guard-policy configuration (same logic as deriveSafeOutputsGuardPolicyFromGitHub)
  • MCPRendererOptions.WriteSinkGuardPolicies - New field that propagates derived guard policies to all built-in server renderers
  • MCPConfigRenderer.GuardPolicies - New field that propagates guard policies through renderSharedMCPConfig for custom tools

Servers updated (both JSON and TOML formats)

  • playwright - renderPlaywrightMCPConfigWithOptions + TOML wrapper
  • serena - renderSerenaMCPConfigWithOptions + TOML wrapper
  • mcp-scripts - renderMCPScriptsMCPConfigWithOptions + TOML wrapper
  • agentic-workflows - renderAgenticWorkflowsMCPConfigWithOptions + TOML wrapper
  • web-fetch - renderMCPFetchServerConfig (JSON + TOML)
  • custom tools - renderSharedMCPConfig (handles both JSON and TOML in one place)

Engine wiring

All 4 engines (Claude, Copilot, Codex, Gemini) now pass WriteSinkGuardPolicies when creating renderers.

Behavior

Simple case: repos: all or repos: public

When repos is all or public, all non-GitHub MCP servers receive accept: ["*"] (allow all write operations):

tools:
  github:
    repos: all           # or: repos: public
    min-integrity: none
  playwright: ...        # → gets write-sink: {accept: ["*"]}
  my-custom-tool: ...    # → gets write-sink: {accept: ["*"]}

Array case: repos as a list of patterns

When repos is an array, the accept patterns are derived per-entry and combined. Transformation rules per entry:

  • owner/*private:owner (owner wildcard: strips the /* suffix)
  • owner/prefix-*private:owner/prefix-* (prefix wildcard: keeps as-is with private: prefix)
  • owner/repoprivate:owner/repo (specific repo: keeps as-is with private: prefix)
tools:
  github:
    repos:
      - "myorg/*"           # all repos in myorg
      - "myorg/service-*"   # repos matching prefix
      - "otherorg/specific" # one specific repo
    min-integrity: approved
  playwright: ...
  my-custom-tool: ...

Produces on every non-GitHub MCP server (TOML format):

[mcp_servers.playwright."guard-policies"]

[mcp_servers.playwright."guard-policies".write-sink]
accept = ["private:myorg", "private:myorg/service-*", "private:otherorg/specific"]

And in JSON format (used by the gateway for Claude/Copilot/Gemini/Codex):

"guard-policies": {
  "write-sink": {
    "accept": ["private:myorg", "private:myorg/service-*", "private:otherorg/specific"]
  }
}

When no GitHub guard policy is configured, no write-sink guard policies are added (existing behavior unchanged).

Testing

Added non_github_mcp_guard_policy_test.go with 21 new tests covering:

  • deriveWriteSinkGuardPolicyFromWorkflow helper
  • Custom tool rendering (JSON + TOML) with and without guard policies
  • Each built-in server (playwright, serena, mcp-scripts, agentic-workflows, web-fetch)
  • End-to-end via MCPConfigRendererUnified
  • Positive and negative cases (with/without GitHub guard policy)

Security Summary

No new security vulnerabilities introduced. The write-sink guard policy is a passthrough configuration that allows data to flow to non-GitHub servers. CodeQL analysis found no issues with the changes.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits March 15, 2026 00:25
…gured by gateway

Extend the write-sink guard policy (currently applied only to safe-outputs) to ALL
non-GitHub MCP servers exposed by the MCP gateway. The policy is derived from the
same GitHub guard-policy parameters (repos/min-integrity), ensuring that as guard
policies are rolled out, only GitHub inputs will be filtered while outputs to
non-GitHub servers are not restricted.

Servers updated: playwright, serena, mcp-scripts, agentic-workflows, web-fetch,
and all custom user-defined MCP tools.

Both JSON format (for gateway/Claude/Copilot/Gemini) and TOML format (for Codex)
are updated with guard policy rendering.

Also adds a deriveWriteSinkGuardPolicyFromWorkflow helper and a comprehensive test
file covering the new behavior.

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
@lpcox
Copy link
Collaborator

lpcox commented Mar 15, 2026

@copilot update the pr to give an example for behavior when repos is an array of values, not just public or all

Copy link
Contributor Author

Copilot AI commented Mar 15, 2026

@copilot update the pr to give an example for behavior when repos is an array of values, not just public or all

The PR description now explains the array case. When repos is a list of patterns, each entry is transformed independently and all results are combined into the accept array on every non-GitHub MCP server:

tools:
  github:
    repos:
      - "myorg/*"           # owner wildcard
      - "myorg/service-*"   # prefix wildcard  
      - "otherorg/specific" # specific repo
    min-integrity: approved
  playwright: ...
  my-custom-tool: ...

Produces on every non-GitHub MCP server (TOML format):

[mcp_servers.playwright."guard-policies"]

[mcp_servers.playwright."guard-policies".write-sink]
accept = ["private:myorg", "private:myorg/service-*", "private:otherorg/specific"]

And in JSON format (gateway/Claude/Copilot/Gemini):

"guard-policies": {
  "write-sink": {
    "accept": ["private:myorg", "private:myorg/service-*", "private:otherorg/specific"]
  }
}

Transformation rules per entry:

  • owner/*private:owner (strips /* wildcard)
  • owner/prefix-*private:owner/prefix-* (keeps prefix wildcard, adds private:)
  • owner/repoprivate:owner/repo (specific repo, adds private:)

Note: GitHub's API is not accessible from this environment so the PR description itself couldn't be updated via API — the example is captured here in the comment.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/github/gh-aw/pulls/21005
    • Triggering command: /usr/bin/curl curl -s -X PATCH -H Authorization: token ****** -H Accept: application/vnd.github.v3&#43;json -H Content-Type: application/json -d @/tmp/pr_payload.json REDACTED (http block)
    • Triggering command: `/usr/bin/gh gh api -X PATCH /repos/github/gh-aw/pulls/21005 -f body=## Summary

Extends the write-sink guard policy (currently applied only to safe-outputs) to ALL non-GitHub MCP servers exposed by the MCP gateway. The policy is derived from the same GitHub guard-policy parameters (repos/min-integrity), ensur` (http block)

If you need me to access, download, or install something from one of these locations, you can either:

…1010)

* Initial plan

* fix: fix TypeScript type error in json_object_to_markdown.cjs

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
@lpcox lpcox marked this pull request as ready for review March 15, 2026 01:43
Copilot AI review requested due to automatic review settings March 15, 2026 01:43
@lpcox lpcox merged commit 50e4991 into main Mar 15, 2026
50 checks passed
@lpcox lpcox deleted the copilot/update-gh-aw-renderer-config branch March 15, 2026 01:43
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

Extends write-sink guard policies to all non-GitHub MCP servers configured by the gateway, ensuring non-GitHub outputs aren't restricted when GitHub guard policies are rolled out.

Changes:

  • New deriveWriteSinkGuardPolicyFromWorkflow helper and new fields (WriteSinkGuardPolicies, GuardPolicies) to propagate guard policies through renderers
  • All built-in MCP server renderers (playwright, serena, mcp-scripts, agentic-workflows, web-fetch) and custom tool rendering updated to emit guard policies in both JSON and TOML formats
  • All four engines (Claude, Copilot, Codex, Gemini) wired to derive and pass guard policies
  • Minor JSDoc type annotation cleanup in json_object_to_markdown.cjs

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pkg/workflow/mcp_github_config.go New deriveWriteSinkGuardPolicyFromWorkflow helper
pkg/workflow/mcp_renderer_types.go New WriteSinkGuardPolicies field on renderer options
pkg/workflow/mcp_config_types.go New GuardPolicies field on MCPConfigRenderer
pkg/workflow/mcp_renderer_builtin.go TOML/JSON guard policy rendering for built-in servers
pkg/workflow/mcp_config_playwright_renderer.go Guard policy support in playwright JSON renderer
pkg/workflow/mcp_config_serena_renderer.go Guard policy support in serena JSON renderer
pkg/workflow/mcp_scripts_renderer.go Guard policy support in mcp-scripts JSON renderer
pkg/workflow/mcp_config_builtin.go Guard policy support in agentic-workflows JSON renderer
pkg/workflow/fetch.go Guard policy support in web-fetch renderer (JSON+TOML)
pkg/workflow/mcp_config_custom.go Guard policy support in custom tool renderer
pkg/workflow/claude_mcp.go Wire guard policies in Claude engine
pkg/workflow/copilot_mcp.go Wire guard policies in Copilot engine
pkg/workflow/codex_mcp.go Wire guard policies in Codex engine
pkg/workflow/gemini_mcp.go Wire guard policies in Gemini engine
pkg/workflow/non_github_mcp_guard_policy_test.go 21 new tests for guard policy derivation and rendering
pkg/workflow/mcp_config_comprehensive_test.go Update existing tests for new function signatures
pkg/workflow/mcp_config_refactor_test.go Update existing tests for new function signatures
pkg/workflow/fetch_test.go Update existing tests for new function signatures
actions/setup/js/json_object_to_markdown.cjs Minor JSDoc type cleanup

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

You can also share your feedback on Copilot code review. Take the survey.

Format: "toml",
IsLast: isLast,
ActionMode: GetActionModeFromWorkflowData(workflowData),
WriteSinkGuardPolicies: deriveWriteSinkGuardPolicyFromWorkflow(workflowData),
github-actions bot added a commit that referenced this pull request Mar 15, 2026
…expansion

- cli.md: note that gh aw audit and add-wizard auto-detect the GHES host
  from the git remote (from #20973), so GH_HOST is not required manually
- github-tools.md: update Safe Outputs Integration section to reflect
  that write-sink guard policies are now derived for ALL non-GitHub MCP
  servers (playwright, serena, mcp-scripts, agentic-workflows, web-fetch,
  custom tools), not only safe-outputs (from #21005)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants