Skip to content

feat: add guard policies support#18589

Open
lpcox wants to merge 10 commits intomainfrom
claude/add-guard-policies-support
Open

feat: add guard policies support#18589
lpcox wants to merge 10 commits intomainfrom
claude/add-guard-policies-support

Conversation

@lpcox
Copy link
Collaborator

@lpcox lpcox commented Feb 27, 2026

Adds guard policies support to workflow tooling, enabling fine-grained access control at the MCP gateway level for GitHub MCP servers.

Changes Made

  • Flat frontmatter syntax: Guard policy fields (repos and min-integrity) are specified directly under github: — no wrapper needed:

    tools:
      github:
        repos: "all"        # "all", "public", or ["owner/repo", "owner/*"]
        min-integrity: reader   # "none", "reader", "writer", "merged"
  • Types: Added GitHubReposScope and GitHubIntegrityLevel to GitHubToolConfig as flat fields (Repos and MinIntegrity)

  • Validation: Validates repos (string or array of patterns, lowercase, valid format) and min-integrity (enum) with clear error messages; both fields are required when either is specified; accepts both []any (YAML-parsed) and []string (programmatic) arrays

  • MCP gateway rendering: Guard policy fields are propagated into the rendered MCP gateway config as a "guard-policies": { "allow-only": { "repos": ..., "min-integrity": ... } } block in both Docker and Remote GitHub MCP server render paths

  • Schema: Updated mcp-gateway-config.schema.json to include guard-policies field for stdio and HTTP server configs

  • Spec document: Added scratchpad/guard-policies-specification.md alongside existing MCP gateway and safe outputs specifications

  • Tests: Added TestValidateGitHubGuardPolicy and TestValidateReposScopeWithStringSlice covering valid/invalid repos scopes, min-integrity levels, pattern formats, and both []any/[]string input types


💡 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.

Claude AI and others added 7 commits February 27, 2026 00:00
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 27, 2026 00:25
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

Adds initial “guard policies” support to workflow tooling, starting with a GitHub-specific allowonly policy and a generic guard-policies field for MCP gateway server configs.

Changes:

  • Added GitHub allowonly policy types, parsing, and validation (repos scope + integrity level).
  • Added guard-policies passthrough support to MCPServerConfig and updated the MCP gateway JSON schema accordingly.
  • Wired guard policy validation into both file-based and string-based workflow compilation paths.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
pkg/workflow/tools_validation.go Adds validation for GitHub guard policy (allowonly) including repo pattern checks and integrity enum validation.
pkg/workflow/tools_types.go Introduces GitHubAllowOnlyPolicy / integrity types; adds GuardPolicies to MCPServerConfig and emits it in mcpServerConfigToMap.
pkg/workflow/tools_parser.go Parses tools.github.allowonly into structured config.
pkg/workflow/schemas/mcp-gateway-config.schema.json Extends MCP gateway schema to allow guard-policies on stdio/http server configs.
pkg/workflow/compiler_string_api.go Calls new guard policy validation during string-based workflow parsing.
pkg/workflow/compiler_orchestrator_workflow.go Calls new guard policy validation during file-based workflow parsing.
GUARD_POLICIES_PROPOSAL.md Adds a design/proposal document describing the intended framework and examples.
Comments suppressed due to low confidence (1)

pkg/workflow/tools_parser.go:240

  • allowonly is not currently permitted by the frontmatter JSON schema, so workflows that try to use this new config will fail schema validation before this parser ever sees it. In pkg/parser/schemas/main_workflow_schema.json, tools.github is an object with additionalProperties: false and does not define an allowonly property (see around the tools.github schema block near line ~2868). Add allowonly to the schema (and its nested shape) so the feature is usable.
		// Parse allowonly guard policy configuration
		if allowOnly, ok := configMap["allowonly"].(map[string]any); ok {
			config.AllowOnly = parseGitHubAllowOnlyPolicy(allowOnly)
		}

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

Comment on lines 237 to 241
// Parse allowonly guard policy configuration
if allowOnly, ok := configMap["allowonly"].(map[string]any); ok {
config.AllowOnly = parseGitHubAllowOnlyPolicy(allowOnly)
}

Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

allowonly is parsed and validated, but it is never propagated into the rendered MCP gateway config. A repo-wide search shows no references beyond parsing/types/validation, and mcp_renderer.go's GitHub MCP rendering does not emit any guard-policies / allowonly fields. If the intent is gateway-side enforcement, you likely need to translate tools.github.allowonly into a guard-policies entry in the GitHub MCP server config when rendering the MCP config.

This issue also appears on line 237 of the same file.

Suggested change
// Parse allowonly guard policy configuration
if allowOnly, ok := configMap["allowonly"].(map[string]any); ok {
config.AllowOnly = parseGitHubAllowOnlyPolicy(allowOnly)
}

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 94511cf. Added getGitHubGuardPolicies(githubTool) helper that extracts allow-only from the raw tool config and returns it as a map[string]any. Added GuardPolicies field to both GitHubMCPDockerOptions and GitHubMCPRemoteOptions, and a renderGuardPoliciesJSON helper that serializes it as a "guard-policies" block after the env section in both Docker and Remote render paths.

Comment on lines 145 to 176
// validateReposScope validates the repos field in allowonly policy
func validateReposScope(repos any, workflowName string) error {
// Case 1: String value ("all" or "public")
if reposStr, ok := repos.(string); ok {
if reposStr != "all" && reposStr != "public" {
toolsValidationLog.Printf("Invalid repos string '%s' in workflow: %s", reposStr, workflowName)
return errors.New("invalid guard policy: 'allowonly.repos' string must be 'all' or 'public'. Got: '" + reposStr + "'")
}
return nil
}

// Case 2: Array of patterns
if reposArray, ok := repos.([]any); ok {
if len(reposArray) == 0 {
toolsValidationLog.Printf("Empty repos array in workflow: %s", workflowName)
return errors.New("invalid guard policy: 'allowonly.repos' array cannot be empty. Provide at least one repository pattern")
}

for i, item := range reposArray {
pattern, ok := item.(string)
if !ok {
toolsValidationLog.Printf("Non-string item in repos array at index %d in workflow: %s", i, workflowName)
return errors.New("invalid guard policy: 'allowonly.repos' array must contain only strings")
}

if err := validateRepoPattern(pattern, workflowName); err != nil {
return err
}
}

return nil
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

validateReposScope only accepts []any, but GitHubReposScope is documented as "string or []string" and other code in this repo commonly uses []string as well as []any for parsed arrays (e.g., toolsets parsing explicitly supports both). This will incorrectly reject programmatically-constructed configs (and is inconsistent with the type comment). Consider accepting both []any and []string here.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 94511cf. Added a []string case to validateReposScope alongside the existing []any case, so programmatically-constructed configs using []string are accepted correctly.

Comment on lines 90 to 143
// validateGitHubGuardPolicy validates the GitHub guard policy configuration
func validateGitHubGuardPolicy(tools *Tools, workflowName string) error {
if tools == nil || tools.GitHub == nil {
return nil
}

// Validate allowonly policy if present
if tools.GitHub.AllowOnly != nil {
if err := validateGitHubAllowOnlyPolicy(tools.GitHub.AllowOnly, workflowName); err != nil {
return err
}
}

return nil
}

// validateGitHubAllowOnlyPolicy validates the allowonly guard policy configuration
func validateGitHubAllowOnlyPolicy(policy *GitHubAllowOnlyPolicy, workflowName string) error {
if policy == nil {
return nil
}

// Validate repos field (required)
if policy.Repos == nil {
toolsValidationLog.Printf("Missing repos in allowonly policy for workflow: %s", workflowName)
return errors.New("invalid guard policy: 'allowonly.repos' is required. Use 'all', 'public', or an array of repository patterns (e.g., ['owner/repo', 'owner/*'])")
}

// Validate repos format
if err := validateReposScope(policy.Repos, workflowName); err != nil {
return err
}

// Validate integrity field (required)
if policy.Integrity == "" {
toolsValidationLog.Printf("Missing integrity in allowonly policy for workflow: %s", workflowName)
return errors.New("invalid guard policy: 'allowonly.integrity' is required. Valid values: 'none', 'reader', 'writer', 'merged'")
}

// Validate integrity value
validIntegrityLevels := map[GitHubIntegrityLevel]bool{
GitHubIntegrityNone: true,
GitHubIntegrityReader: true,
GitHubIntegrityWriter: true,
GitHubIntegrityMerged: true,
}

if !validIntegrityLevels[policy.Integrity] {
toolsValidationLog.Printf("Invalid integrity level '%s' in workflow: %s", policy.Integrity, workflowName)
return errors.New("invalid guard policy: 'allowonly.integrity' must be one of: 'none', 'reader', 'writer', 'merged'. Got: '" + string(policy.Integrity) + "'")
}

return nil
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

New guard policy validation paths were added here, but there are no corresponding unit tests in pkg/workflow/tools_validation_test.go covering the allowonly policy (valid/invalid repos scopes, invalid patterns, invalid integrity, etc.). Since this package already has validation tests, please add coverage for these new branches to prevent regressions and to lock in error message quality.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

Added in 94511cf. Added TestValidateGitHubGuardPolicy (14 cases covering valid/invalid repos values, invalid integrity, missing fields) and TestValidateReposScopeWithStringSlice (4 cases covering []string and []any input types) to tools_validation_test.go.

Comment on lines 279 to 295
// GitHubReposScope represents the repository scope for guard policy enforcement
// Can be one of: "all", "public", or an array of repository patterns
type GitHubReposScope any // string or []string

// GitHubAllowOnlyPolicy represents the allowonly guard policy configuration
type GitHubAllowOnlyPolicy struct {
// Repos defines the access scope for policy enforcement
// Supports:
// - "all": all repositories
// - "public": public repositories only
// - array of patterns: ["owner/repo", "owner/*", "owner/re*"] (lowercase)
Repos GitHubReposScope `json:"repos" yaml:"repos"`

// Integrity defines the minimum integrity level required
// Valid values: "none", "reader", "writer", "merged"
Integrity GitHubIntegrityLevel `json:"integrity" yaml:"integrity"`
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

GitHubReposScope is declared as any and the comment says "string or []string", but parsing stores the raw YAML value (any), which is typically []any for arrays. Either adjust the comment to reflect the actual runtime shapes (string or []any), or introduce a dedicated type + custom unmarshal so this is truly string | []string.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 94511cf — updated the comment to // string or []any (YAML-parsed arrays are []any) to reflect the actual runtime type.


// Guard policies for access control at the MCP gateway level
// This is a general field that can hold server-specific policy configurations
// For GitHub: use GitHubGuardPolicy
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The comment on GuardPolicies says "For GitHub: use GitHubGuardPolicy", but no such type exists in this PR (the GitHub policy type added is GitHubAllowOnlyPolicy, attached to GitHubToolConfig). This is misleading documentation; update the comment to reference the actual intended GitHub policy representation (or add the missing type if that's the plan).

Suggested change
// For GitHub: use GitHubGuardPolicy
// For GitHub: policies are represented via GitHubAllowOnlyPolicy on GitHubToolConfig

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed in 94511cf — updated the comment to // For GitHub: policies are represented via GitHubAllowOnlyPolicy on GitHubToolConfig.

Copy link
Contributor

@pelikhan pelikhan left a comment

Choose a reason for hiding this comment

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

@copilot use dashes between words in yaml field names "allow-only". No underscores.

Copy link
Contributor

@pelikhan pelikhan left a comment

Choose a reason for hiding this comment

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

@copilot move guard spec .md next to the MCP gateway and safe outputs specifications files

…comments, add tests, propagate to renderer

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Feb 27, 2026

@copilot use dashes between words in yaml field names "allow-only". No underscores.

Done in 94511cf — renamed allowonly to allow-only in the YAML tag (yaml:"allow-only,omitempty"), the parser key lookup (configMap["allow-only"]), and all error messages.

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/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -ato�� -bool -buildtags /home/REDACTED/work/_temp/uv-python-dir/node -errorsas -ifaceassert -nilfunc node (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GO111MODULE 64/bin/go node /tmp�� /tmp/TestHashConsistency_GoAndJavaScript4181388732/001/test-empty-frontmatter.md-p go r,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,disp--show-toplevel ck &#39;scripts/**/*git flow 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw go /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel go (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha 9fMffp4s8 5779578/b053/vet.cfg tions/setup/js/node_modules/.bin/sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha -json GO111MODULE 7257330/b368/vet.cfg GOINSECURE GOMOD GOMODCACHE go env -json l /tmp/go-build2487257330/b001/gh-aw.test GOINSECURE GOMOD GOMODCACHE /tmp/go-build2487257330/b001/gh-aw.test (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel o fix.&#34;; \ exitrev-parse /usr/bin/git git rev-�� --show-toplevel git 1359339/b411/vet.cfg --show-toplevel node /usr/bin/git /tmp/go-build3381359339/b382/constants.test (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -policies-support (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha g_.a GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env 1858-47114/test-3179748465/.github/workflows GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE ortcfg (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --show-toplevel /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/link /usr/bin/git sistency_GoAndJagit stmain.go clusion,workflow--show-toplevel git rev-�� 2159-51091/test-3432821593/.github/workflows git /usr/bin/git bility_SameInputgit rev-parse /usr/bin/git git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha --exclude-standard --others tions/node_modules/.bin/sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha --exclude-standard .cfg tions/setup/node_modules/.bin/sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha npx prettier --write &#39;**/*.cjs&#39; &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json -tests /opt/pipx_bin/sh (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha set-url origin x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --noprofile (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --write **/*.cjs /opt/hostedtoolcache/node/24.13.1/x64/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/n--show-toplevel **/*.json --ignore-path ../../../.pretti--show-toplevel sh -c &#34;prettier&#34; --write &#39;../../../**/*.json&#39; &#39;!../../../pkg/workflow/js/**/*.json&#39; --ignore-path ../.git mkcert /home/REDACTED/work/_temp/ghcca-node/node/bin/bash (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --exclude-standard --others ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --exclude-standard --others de_modules/.bin/sh /lib/php/sessiongit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha npx prettier --write &#39;**/*.cjs&#39; &#39;**/*.ts&#39; &#39;**/*.json&#39; --ignore-path ../../../.pr**/*.json -tests /home/REDACTED/.config/composer/vendor/bin/sh (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --exclude-standard --others h (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha -json GO111MODULE 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/compile env g_.a GO111MODULE 7257330/b285/vet.cfg GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel gh /usr/bin/git k/gh-aw/gh-aw/.ggit --jq /usr/bin/git git rev-�� --show-toplevel git 1/x64/bin/node nt/action/git/regit rev-parse /usr/bin/git 1/x64/bin/node (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --exclude-standard --others ules/.bin/sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha vaScript4181388732/001/test-complex-frontmatter-with-tools.md GO111MODULE 7257330/b001=&gt; GOINSECURE GOMOD GOMODCACHE go env runs/20260227-011858-47114/test-994521727/.github/workflows GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go l GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --show-toplevel git 1/x64/bin/node k/gh-aw/gh-aw/.ggit rev-parse /usr/bin/git ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet t-ha�� ithub/workflows/brave.md git /usr/bin/git -aw/git/ref/tagsgit go /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 GOMOD 64/bin/go tierignore GO111MODULE 64/bin/go go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 go x_amd64/link -json GO111MODULE 7257330/b393/env--show-toplevel x_amd64/link rev-�� --show-toplevel 7257330/b393/envutil.test /usr/bin/git t0 GO111MODULE (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 gh ache/node/24.13.1/x64/bin/node /repos/actions/ggit --jq /usr/bin/git git _inc�� 2408-57178/test-798625619/.github/workflows git k/_temp/ghcca-node/node/bin/bash --show-toplevel git /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 scripts/**/*.js 64/bin/go .prettierignore GO111MODULE 64/bin/go go estl�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 go /usr/bin/git -json GO111MODULE ache/go/1.25.0/x--show-toplevel git rev-�� --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet /usr/bin/git -json GO111MODULE /opt/hostedtoolc--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 git ache/node/24.13.1/x64/bin/node /tmp/file-trackegit git ache/node/24.13.--show-toplevel git _inc�� --show-toplevel ache/node/24.13.1/x64/bin/node ache/node/24.13.1/x64/bin/node --show-toplevel git /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 scripts/**/*.js 64/bin/go .prettierignore GO111MODULE 64/bin/go go estl�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 go /usr/bin/git -json GO111MODULE 7257330/b001/gh---show-toplevel git rev-�� --show-toplevel 7257330/b001/gh-aw.test /usr/bin/infocmp t0 GO111MODULE (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 git ache/node/24.13.1/x64/bin/node 64/bin/go git /opt/hostedtoolc--show-toplevel git _inc�� 2408-57178/test-3139956878/.github/workflows node ache/node/24.13.1/x64/bin/node /home/REDACTED/worgit git 105/001/go/1.25.--show-toplevel git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 -f x_amd64/compile -- unsafe 64/bin/go x_amd64/compile env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 go /usr/bin/git -json GO111MODULE ingutil.test git estl�� --show-toplevel ingutil.test /usr/bin/git t0 GO111MODULE (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 node ache/node/24.13.1/x64/bin/node /home/REDACTED/worgit git /usr/bin/git git _inc�� --show-toplevel git /usr/bin/git --show-toplevel git /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 go 64/bin/go tierignore GO111MODULE 64/bin/go go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 go x_amd64/link -json GO111MODULE 7257330/b387/conuser.email x_amd64/link rev-�� --show-toplevel 7257330/b387/console.test /usr/bin/git t0 GO111MODULE (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 infocmp ache/node/24.13.1/x64/bin/node xterm-color git /usr/bin/git git _inc�� --show-toplevel git cal/bin/bash --show-toplevel git ache/node/24.13.--show-toplevel git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 GOCACHE 64/bin/go tierignore GO111MODULE 64/bin/go go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 go x_amd64/vet -json GO111MODULE 7257330/b390/con--git-dir x_amd64/vet rev-�� --show-toplevel 7257330/b390/constants.test /usr/bin/git t0 GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 node ache/node/24.13.1/x64/bin/node /home/REDACTED/worgit git /usr/bin/git git _inc�� --show-toplevel git sh --show-toplevel git /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 GOMOD 64/bin/go tierignore GO111MODULE 64/bin/go go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 0XVD7GS/mRL0tEU7remote.origin.url (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 go x_amd64/link -json GO111MODULE ache/go/1.25.0/x--show-toplevel x_amd64/link rev-�� --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/compile /usr/bin/git 7257330/b395/_pkgit GO111MODULE 7257330/b395=&gt; de/828cbCRwzgs6s6ZUr2mo/Sv-0AbT5NsLuWUzUJI6v (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 git ache/node/24.13.1/x64/bin/node --show-toplevel JbrieQ94-F8q /usr/bin/git docker _inc�� 2408-57178/test-636195199/.github/workflows git 1/x64/bin/node --show-toplevel git /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 GOMOD GOMODCACHE go env ck &#39;scripts/**/*GOSUMDB GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 GO111MODULE 64/bin/go x_amd64/compile env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha t credential.username x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE ache/go/1.25.0/x--show-toplevel git rev-�� --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet x_amd64/vet -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go x_amd64/vet (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha t credential.usern**/*.json x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env 2381276939/.github/workflows GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE les.test git estl�� --show-toplevel les.test /usr/bin/git -json GO111MODULE /opt/hostedtoolc--show-toplevel git (http block)
  • https://api.github.com/repos/nonexistent/repo/actions/runs/12345
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE x_amd64/link env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE HC/wPHmRHH07drGotDxh6_4/9rUbv3kNremote.origin.url (http block)
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion ingutil.test 7257330/b125/vetrev-parse ortcfg.link git rev-�� 2704849136/.github/workflows x2bykBD4rngcj-OdT7/mR_J8L3mpahD7X9qYVEv/eZay7NwYwCOxz1AFAzDu /usr/bin/git -json GO111MODULE g_.a git (http block)
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion nt/action/git/regit rev-parse /usr/bin/git git _lab�� --show-toplevel git /usr/bin/git 64/pkg/tool/linugit git /usr/bin/git git (http block)
  • https://api.github.com/repos/owner/repo/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo /usr/bin/git -json GO111MODULE x_amd64/compile git rev-�� --show-toplevel x_amd64/compile /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
  • https://api.github.com/repos/owner/repo/contents/file.md
    • Triggering command: /tmp/go-build2487257330/b381/cli.test /tmp/go-build2487257330/b381/cli.test -test.testlogfile=/tmp/go-build2487257330/b381/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /tmp/go-build3381359339/b001/cli.test /tmp/go-build3381359339/b001/cli.test -test.testlogfile=/tmp/go-build3381359339/b001/testlog.txt -test.paniconexit0 -test.timeout=10m0s remo�� -v /bin/sh /usr/bin/git GOPATH=$(go env git go 64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
    • Triggering command: /tmp/go-build2028169969/b361/cli.test /tmp/go-build2028169969/b361/cli.test -test.testlogfile=/tmp/go-build2028169969/b361/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp�� ${{github.actor}} git /usr/bin/git 6471/001/stabilinode go /usr/lib/git-core/git git rev-�� --show-toplevel /usr/lib/git-cor^remote\..*\.gh-resolved$ cal/bin/node run --auto /usr/bin/git git (http block)
  • https://api.github.com/repos/test-owner/test-repo/actions/secrets
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name --show-toplevel go 1/x64/bin/npm -json GO111MODULE 64/bin/go 1/x64/bin/npm rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name --show-toplevel git /usr/bin/git --show-toplevel V_9LLtYheNxUI/rcjs/fuzz_mentions_harness.cjs /bin/sh git rev-�� heckout/git/ref/tags/v4 /bin/sh /usr/bin/git git-upload-pack node git-upload-pack js/fuzz_sanitize_output_harness.cjs /usr/bin/git git (http block)

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

@github-actions

This comment has been minimized.

@pelikhan
Copy link
Contributor

@copilot flatten the frontmatter fields:

github:
  repos: ...
  integrity: ...

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Feb 27, 2026

@copilot move guard spec .md next to the MCP gateway and safe outputs specifications files

Done in 436875b — moved GUARD_POLICIES_PROPOSAL.md to scratchpad/guard-policies-specification.md, alongside scratchpad/github-mcp-access-control-specification.md and scratchpad/safe-outputs-specification.md.

@copilot flatten the frontmatter fields:

github:...

Done in 436875b. Removed the allow-only: wrapper — repos and integrity are now direct fields under github::

tools:
  github:
    repos: "all"
    integrity: reader

Removed GitHubAllowOnlyPolicy struct and AllowOnly field from GitHubToolConfig. The renderer still wraps them as allow-only in the MCP gateway JSON output.

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/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GOMOD GOMODCACHE go env -json GO111MODULE /home/REDACTED/.local/bin/bash GOINSECURE GOMOD GOMODCACHE bash (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha get cfg 64/pkg/tool/linux_amd64/vet credential.helpegit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha -json GO111MODULE 86_64/git GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha t^{commit} (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha den/fixtures/shared/github-mcp-app.md den/fixtures/shared/gh.md 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha -unreachable=false /tmp/go-build532245089/b012/vet.cfg 245089/b283/vet.cfg (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha estdata/wasm_golden/fixtures/shared/github-mcp-app.md estdata/wasm_golden/fixtures/shared/gh.md ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -unreachable=false /tmp/go-build532245089/b116/vet.cfg /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha den/fixtures/shared/github-mcp-app.md den/fixtures/shared/gh.md 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -unreachable=false /tmp/go-build532245089/b013/vet.cfg 245089/b244/vet.cfg (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -json GO111MODULE 64/bin/bash GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE n-dir/git GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha -json GO111MODULE n-dir/bash GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha pp.md irements.go 1/x64/bin/git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha run lint:cjs 64/bin/go GOSUMDB GOWORK run-script/lib/n94511cf49a5af99015f82f440e282f4793952e24:pkg/workflow/tools_types.go iptables -w -t security 64/bin/go -nxv git 64/bin/go go (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha run lint:cjs 64/bin/go GOSUMDB GOWORK 64/bin/go node /opt�� prettier --check 64/bin/go --ignore-path .prettierignore 64/bin/go go (http block)

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

@pelikhan
Copy link
Contributor

@copilot rename integrity to min-integrity

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Feb 27, 2026

@copilot rename integrity to min-integrity

Done in 1cba6cd — renamed integrity to min-integrity across the YAML tag (yaml:"min-integrity,omitempty"), parser key lookup, Go struct field (MinIntegrity), validation logic and error messages ('github.min-integrity'), MCP gateway renderer, tests, and the spec document.

@github-actions

This comment has been minimized.

@github-actions
Copy link
Contributor

Hey @lpcox 👋 — nice feature addition! The guard policies implementation for the MCP gateway is well-structured: flat frontmatter syntax under github: is intuitive, the dual-path []any/[]string validation in tools_validation.go is thoughtfully handled, and the 200+ lines of tests covering valid/invalid repos scopes, integrity levels, and edge cases are solid. A couple of things to address before this can merge:


⚠️ CI Is Unstable — Run make agent-finish

The PR's mergeable_state is currently unstable and the bot noted make agent-finish hasn't been run yet. This is a required step for every PR in this project — it runs build, test, lint, recompile, and fmt in one shot:

make agent-finish

Until that passes cleanly, the PR isn't ready to merge.


📄 Spec Doc Has a Stale "Pending" Tests Note

scratchpad/guard-policies-specification.md says in its Testing Strategy section:

Unit Tests (Pending) and Integration Tests (Pending)

…but the PR already includes TestValidateGitHubGuardPolicy and TestValidateReposScopeWithStringSlice. Update the spec doc to reflect that unit tests are done and only integration tests remain pending. There's also a typo: min-min-integrity in the Problem Statement section.


If you'd like a hand addressing these, assign this prompt to your coding agent:

In PR branch `claude/add-guard-policies-support` of github/gh-aw, do the following:

1. Run `make agent-finish` and fix any build, test, lint, recompile, or fmt failures it surfaces.

2. In `scratchpad/guard-policies-specification.md`:
   a. Update the "Testing Strategy" section: mark unit tests for `validateGitHubGuardPolicy` and `validateReposScope` as complete (tests exist in `pkg/workflow/tools_validation_test.go`). Note that integration tests for end-to-end workflow compilation are still pending.
   b. Fix the typo `min-min-integrity` → `min-integrity` in the Problem Statement section.

3. Do not change any Go source or test files unless `make agent-finish` requires it.

Generated by Contribution Check

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.

5 participants