Skip to content

Prevent private secrecy taint for public-scope repo reads when visibility lookup is unknown - #10472

Merged
lpcox merged 3 commits into
mainfrom
copilot/fix-private-tag-issue
Jul 31, 2026
Merged

lpcox merged 3 commits into
mainfrom
copilot/fix-private-tag-issue

Conversation

Copilot AI commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Public-repo workflows could end up with private:<owner/repo> secrecy after reading their own repo via GitHub MCP, which then made safe-output writes impossible (noop, missing_tool, push_repo_memory). The failure mode was triggered when repo visibility resolution was unavailable and labeling fell back to private semantics despite a public-only policy scope.

  • Secrecy fallback semantics (public scope)

    • Updated repo-visibility secrecy fallback to return [] (public) when:
      • visibility lookup returns unknown, and
      • policy scope includes Public.
    • Applied in both shared helper logic and tool-rule application paths so repo-scoped reads behave consistently.
  • Labeling consistency across code paths

    • apply_repo_visibility_secrecy(...) now avoids introducing private:* under Public scope on unknown visibility.
    • repo_visibility_secrecy(...) now uses the same rule to prevent path-dependent drift.
  • Regression coverage

    • Added a focused test for actions_list proving that unknown visibility under Public scope does not taint secrecy.
// Unknown visibility + Public policy scope => keep secrecy public
if ctx.scopes.iter().any(|s| matches!(s.scope_kind, ScopeKind::Public)) {
    return vec![];
}

Copilot AI changed the title [WIP] Fix public repositories assigned private tags blocking safe-output writes Prevent private secrecy taint for public-scope repo reads when visibility lookup is unknown Jul 31, 2026
Copilot finished work on behalf of lpcox July 31, 2026 20:47
Copilot AI requested a review from lpcox July 31, 2026 20:47
@lpcox
lpcox marked this pull request as ready for review July 31, 2026 21:26
Copilot AI review requested due to automatic review settings July 31, 2026 21:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates repository visibility fallback behavior to avoid private taint under public policy scope.

Changes:

  • Treats unknown repository visibility as public under public scope.
  • Applies the fallback to tool and response labeling.
  • Adds an actions_list regression test.
Show a summary per file
File Description
labels/tool_rules.rs Changes tool resource secrecy fallback.
labels/helpers.rs Changes shared visibility secrecy fallback.
labels/mod.rs Adds regression coverage.

Review details

Tip

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

  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment on lines +1027 to +1031
.scopes
.iter()
.any(|scope| matches!(scope.scope_kind, ScopeKind::Public))
{
return vec![];
Comment on lines +40 to +44
.scopes
.iter()
.any(|scope| matches!(scope.scope_kind, super::helpers::ScopeKind::Public))
{
return vec![];
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@lpcox

lpcox commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

@copilot address review feedback

Copilot AI commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address review feedback

Addressed in c0fd58c. The runtime fallback no longer treats unknown repo visibility as public, and I replaced the regression with a public-scope test that verifies unknown visibility does not erase existing secrecy.

@github-actions

Copy link
Copy Markdown
Contributor

🔒 mcpg Read-Only Stress — gVisor

Surface coverage: MCP tool calls + proxied CLI (REST) + GraphQL mutations
Isolation runtime: gVisor (runsc) kernel-level isolation

Part Surface Op Result Expected Status
A MCP reads (issues/PRs/file/commits) data returned ALLOWED
B MCP writes (reaction/star/issue/comment/branch/file/PR) Error [-32602]: unknown tool (gateway blocks) BLOCKED
C CLI reads (list issues, get file) data returned ALLOWED
D CLI REST writes (reaction/star/issue/comment/file) unauthenticated — GH_TOKEN not set BLOCKED
E CLI GraphQL mutations (addReaction/addStar/createIssue) unauthenticated — GH_TOKEN not set BLOCKED

Overall: PASS

References: §30667622058

🔒 mcpg read-only stress (gVisor runtime) by Read-Only Stress: gVisor runtime

Copilot finished work on behalf of lpcox July 31, 2026 21:48
@github-actions

Copy link
Copy Markdown
Contributor

🔒 mcpg Read-Only Stress — default AWF

Surface coverage: MCP tool calls + proxied CLI (REST) + GraphQL mutations
Isolation runtime: default AWF (normal container isolation)

Part Surface Op Result Expected Status
A MCP reads (issues/PRs/file/commits) data returned ALLOWED
B MCP writes (reaction/star/issue/comment/branch/file/PR) all refused: Error [-32602]: unknown tool BLOCKED
C CLI reads (list_issues, get_file_contents) data returned ALLOWED
D CLI REST writes (reaction/star/issue/comment/file) all refused: gh unauthenticated (exit 4) BLOCKED
E CLI GraphQL mutations (addReaction/addStar/createIssue) all refused: gh unauthenticated (exit 4) BLOCKED

Overall: PASS

Part B detail: All MCP write tools returned Error [-32602]: unknown tool — the gateway does not expose write tools at the MCP protocol layer (gateway enforcement via tool filtering).
Parts D & E: gh carries no token in this runtime; all REST/GraphQL write attempts fail before reaching GitHub (auth boundary).

References: §30667623195

🔒 mcpg read-only stress (default AWF runtime) by Read-Only Stress: default runtime

@github-actions

Copy link
Copy Markdown
Contributor

🔒 mcpg Read-Only Stress — docker-sbx

Surface coverage: MCP tool calls + proxied CLI (REST) + GraphQL mutations
Isolation runtime: docker-sbx (KVM-isolated microVM)

Part Surface Op Result Expected Status
A MCP reads (issues/PRs/file/commits) data returned ALLOWED
B MCP writes (reaction/star/issue/comment/branch/file/PR) all refused — tool not in gateway registry BLOCKED
C CLI reads (list_issues, get_file_contents) data returned ALLOWED
D CLI REST writes (reaction/star/issue/comment/file) refused — gh unauthenticated (no GH_TOKEN) BLOCKED
E CLI GraphQL mutations (addReaction/addStar/createIssue) refused — gh unauthenticated (no GH_TOKEN) BLOCKED

Overall: PASS

Note (Part B): Gateway registers only 22 read-only tools; write tools are absent from registry entirely. All 7 write attempts returned Error [-32602]: unknown tool.
Note (Parts D/E): gh CLI unauthenticated (no GH_TOKEN); REST and GraphQL writes rejected at client level.

References: §30667623194

🔒 mcpg read-only stress (docker-sbx runtime) by Read-Only Stress: docker-sbx runtime

@lpcox
lpcox merged commit bc3dc59 into main Jul 31, 2026
38 checks passed
@lpcox
lpcox deleted the copilot/fix-private-tag-issue branch July 31, 2026 22:01
wochinge added a commit to langfuse/langfuse that referenced this pull request Aug 6, 2026
mcpg v0.4.8 alone did not fix the block: run 31082817368 still tagged
resource:actions_list / actions_get secrecy=private and filtered every read.

github/gh-aw-mcpg#10472 only returns public secrecy when the visibility lookup
is unknown AND the policy scope includes Public, and the gateway was still
reporting allowOnlyPublic=false under automatic lockdown. Setting
allowed-repos: public emits a literal "repos": "public" so the precondition is
unambiguously met. It must be the string form — a specific owner/repo does not
satisfy it, which is why the earlier array attempt could not have worked.

Co-Authored-By: Claude Opus 5 <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.

Public repositories are assigned private:<owner/repo> secrecy tags, blocking every safe-output write

3 participants