Skip to content

[guard-coverage] Guard coverage gap: 34 write operations from github-mcp-server lack DIFC label rules #4292

@github-actions

Description

@github-actions

Summary

The GitHub guard's tool classification (tools.rs) is comprehensive — all 102 tools currently exposed by github-mcp-server are correctly classified as write, read-write, or read. However, 34 write/mutating tools have no explicit match arm in apply_tool_labels (tool_rules.rs) and fall through to the _ => { // Default: inherit provided labels } case. This means their secrecy tags and integrity levels are inherited from caller-provided labels rather than being explicitly enforced, which can produce incorrect DIFC labeling for repo-scoped writes.

  • MCP tools scanned: 102 (from pkg/github/__toolsnaps__/ on main)
  • CLI write commands scanned: ~45 (all major write groups in pkg/cmd/)
  • Guard-covered write tools (tools.rs): 60 in WRITE_OPERATIONS + 30 in READ_WRITE_OPERATIONS
  • Tools with explicit DIFC rules (tool_rules.rs): ~68 match arms (covering ~38 tool names from upstream)
  • Classification gaps (tools.rs): 0 — all upstream tools are correctly classified ✅
  • New DIFC labeling gaps (tool_rules.rs): 34 — write/mutating tools fall through to default

MCP Tool Classification Gaps (tools.rs)

None. All 102 upstream MCP tools are correctly classified. ✅


MCP Tool DIFC Labeling Gaps (tool_rules.rs)

These 34 write/mutating MCP tools exist in the upstream server, are correctly classified in tools.rs, but have no explicit match arm in apply_tool_labels. They fall through to _ => { // Default: inherit provided labels }, meaning secrecy and integrity are not explicitly enforced.

High-priority (repo-scoped writes, high risk)

Tool Name Classification Data Scope Risk
merge_pull_request READ_WRITE repo-scoped High — irreversible code merge; should enforce writer_integrity(repo_id)
create_pull_request WRITE repo-scoped High — creates a PR targeting a branch; should enforce repo-scoped secrecy + writer integrity
fork_repository WRITE user-scoped Medium — creates a fork under a user/org; should set user-scoped labels
create_repository WRITE user-scoped Medium — creates a new repo; should set user-scoped labels
update_pull_request_branch READ_WRITE repo-scoped Medium — updates PR branch (git write); should enforce repo-scoped labels

PR review operations (PR-scoped)

Tool Name Classification Notes
pull_request_review_write READ_WRITE Composite review write; no label arm
add_comment_to_pending_review WRITE Adds to pending review
add_pull_request_review_comment READ_WRITE Posts inline review comment
add_reply_to_pull_request_comment WRITE Replies to review thread
create_pull_request_review READ_WRITE Creates a review
delete_pending_pull_request_review READ_WRITE Deletes pending review
request_pull_request_reviewers READ_WRITE Requests reviewers
resolve_review_thread READ_WRITE Resolves a review thread
submit_pending_pull_request_review READ_WRITE Submits the review
unresolve_review_thread READ_WRITE Unresolves a thread

Granular PR update tools (PR-scoped)

Tool Name Classification Notes
update_pull_request READ_WRITE General PR update
update_pull_request_body READ_WRITE Updates PR description
update_pull_request_draft_state READ_WRITE Converts to/from draft
update_pull_request_state READ_WRITE Opens/closes PR
update_pull_request_title READ_WRITE Updates PR title

Sub-issue tools (issue-scoped)

Tool Name Classification Notes
add_sub_issue READ_WRITE Adds sub-issue link
remove_sub_issue READ_WRITE Removes sub-issue link
reprioritize_sub_issue READ_WRITE Reorders sub-issues
set_issue_fields READ_WRITE Sets custom field values on an issue

Granular issue update tools (issue-scoped)

Tool Name Classification Notes
update_issue_body READ_WRITE Updates issue description
update_issue_labels READ_WRITE Updates issue labels
update_issue_milestone READ_WRITE Updates issue milestone
update_issue_state READ_WRITE Opens/closes issue
update_issue_title READ_WRITE Updates issue title
update_issue_type READ_WRITE Updates issue type

Notification management (notification/repo-scoped)

Tool Name Classification Notes
dismiss_notification WRITE Dismisses a notification
manage_notification_subscription WRITE Subscribe/unsubscribe to a thread
manage_repository_notification_subscription WRITE Subscribe/unsubscribe to a repo
mark_all_notifications_read WRITE Marks all notifications read

Suggested fixes for tool_rules.rs

Add explicit match arms for each group. Follow the pattern of existing similar tools:

// === PR merge (high-risk: irreversible code write) ===
"merge_pull_request" => {
    // Merging a PR writes code to the target branch.
    // S = S(repo); I = writer(repo)
    secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
    integrity = writer_integrity(repo_id, ctx);
}

// === PR creation / update (repo-scoped writes) ===
"create_pull_request" | "update_pull_request" | "update_pull_request_body"
| "update_pull_request_title" | "update_pull_request_state"
| "update_pull_request_draft_state" | "update_pull_request_branch" => {
    // PR writes are repo-scoped.
    // S = S(repo); I = writer(repo)
    secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
    integrity = writer_integrity(repo_id, ctx);
}

// === PR review operations (PR-scoped writes) ===
"pull_request_review_write"
| "add_comment_to_pending_review"
| "add_pull_request_review_comment"
| "add_reply_to_pull_request_comment"
| "create_pull_request_review"
| "delete_pending_pull_request_review"
| "request_pull_request_reviewers"
| "resolve_review_thread" | "unresolve_review_thread"
| "submit_pending_pull_request_review" => {
    // PR review writes are repo-scoped.
    // S = S(repo); I = writer(repo)
    secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
    integrity = writer_integrity(repo_id, ctx);
}

// === Repository creation / fork (user-scoped writes) ===
"create_repository" | "fork_repository" => {
    // Creating or forking a repo is user-scoped.
    // S = public (no private data in response); I = writer(github)
    baseline_scope = "github".to_string();
    integrity = writer_integrity("github", ctx);
}

// === Granular issue updates (issue-scoped writes) ===
"update_issue_body" | "update_issue_labels" | "update_issue_milestone"
| "update_issue_state" | "update_issue_title" | "update_issue_type" => {
    // Issue field updates are repo-scoped writes.
    // S = S(repo); I = writer(repo)
    secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
    integrity = writer_integrity(repo_id, ctx);
}

// === Sub-issue management (issue-scoped writes) ===
"add_sub_issue" | "remove_sub_issue" | "reprioritize_sub_issue" | "set_issue_fields" => {
    // Sub-issue writes are repo-scoped.
    // S = S(repo); I = writer(repo)
    secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
    integrity = writer_integrity(repo_id, ctx);
}

// === Notification management (notification-scoped) ===
"dismiss_notification" | "manage_notification_subscription"
| "manage_repository_notification_subscription" | "mark_all_notifications_read" => {
    // Notification management; response carries no repo-sensitive data.
    // S = public (empty); I = project:github
    secrecy = vec![];
    baseline_scope = "github".to_string();
    integrity = project_github_label(ctx);
}

GitHub CLI-Only Gaps

None found. All major GitHub CLI write operations (gh pr, gh issue, gh repo, gh gist, gh release, gh workflow, gh run, gh label, gh project, gh secret, gh variable) have corresponding entries in WRITE_OPERATIONS or READ_WRITE_OPERATIONS (including pre-emptive entries). ✅


Stale Guard Entries (bonus)

No stale entries. Pre-emptive entries in tools.rs (e.g., archive_repository, enable_workflow, set_secret) are intentional forward-looking entries, not stale — they are explicitly annotated as such. ✅


References

Generated by GitHub Guard Coverage Checker (MCP + CLI) · ● 1.3M ·

  • expires on May 5, 2026, 8:20 PM UTC

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions