Summary
The GitHub guard covers all 80 tools currently in github-mcp-server with both write-classification and DIFC-labeling rules. However, 3 GitHub CLI write operations have no pre-emptive guard entry — meaning if a corresponding MCP tool is added to the GitHub MCP server, or if an agent invokes these operations via gh CLI, the guard would not classify them.
- MCP tools scanned: 80 (from
pkg/github/__toolsnaps__/)
- CLI write commands scanned: ~63
- Guard-covered write tools (tools.rs): 50 (42 WRITE_OPERATIONS + 8 READ_WRITE_OPERATIONS)
- Tools with explicit DIFC rules (tool_rules.rs): 80 (complete coverage)
- MCP classification gaps: 0
- MCP DIFC labeling gaps: 0
- New CLI-only gaps found this run: 3
GitHub CLI-Only Gaps
These write operations are reachable via the GitHub CLI but have no corresponding MCP tool today and no pre-emptive guard entry. If GitHub MCP server adds a matching tool, the guard would not intercept it.
| CLI Command |
REST/GraphQL Endpoint |
GitHub API Action |
Suggested Guard Name |
Risk |
gh repo edit |
PATCH /repos/{owner}/{repo} |
Modifies repo settings: visibility (private↔public), default branch, security features, merge options |
edit_repository |
High — can expose private code by changing visibility |
gh pr revert |
GraphQL revertPullRequest mutation |
Creates a new branch + PR that reverts a merged PR's changes |
revert_pull_request |
Medium — creates new branch and PR |
gh repo deploy-key add |
POST /repos/{owner}/{repo}/keys |
Adds an SSH deploy key with optional write access to the repository |
add_deploy_key |
High — grants persistent SSH write access |
Detail: gh repo edit → edit_repository
gh repo edit uses PATCH /repos/{owner}/{repo} and can change:
visibility: public/private (can accidentally expose private code)
default_branch: changes the default merge target
delete_branch_on_merge, allow_auto_merge, security settings
This is a HIGH-risk operation because changing visibility from private to public would expose all repository contents. The guard already has pre-emptive entries for other irreversible repo operations (archive_repository, rename_repository, transfer_repository) but edit_repository is missing.
Detail: gh pr revert → revert_pull_request
gh pr revert uses the GraphQL revertPullRequest mutation. It creates a new branch (from the revert commit) and opens a new PR. This is semantically similar to create_pull_request + create_branch, both of which are already in WRITE_OPERATIONS, but the combined operation is not pre-emptively covered.
Detail: gh repo deploy-key add → add_deploy_key
gh repo deploy-key add uses POST /repos/{owner}/{repo}/keys to register an SSH key as a deploy key. With --write flag, the key gets push access to the repository. This is a HIGH-risk persistent access grant. Note: delete_deploy_key would also need coverage since delete_* is NOT an automatic pattern in the guard (only lock_* and unlock_* are pattern-matched).
Suggested Fix for tools.rs
Add pre-emptive entries to WRITE_OPERATIONS in guards/github-guard/rust-guard/src/tools.rs:
pub const WRITE_OPERATIONS: &[&str] = &[
// ... existing entries ...
// Pre-emptive: gh repo edit (PATCH /repos/{owner}/{repo}) — can change visibility, security settings
"edit_repository",
// Pre-emptive: gh pr revert (GraphQL revertPullRequest) — creates revert branch + PR
"revert_pull_request",
// Pre-emptive: gh repo deploy-key add/delete — SSH key with optional write access
"add_deploy_key",
"delete_deploy_key",
];
Suggested Fix for tool_rules.rs
Add match arms to apply_tool_labels in guards/github-guard/rust-guard/src/labels/tool_rules.rs:
// === Repository settings edit (can change visibility) ===
"edit_repository" => {
// Can change repo visibility, security settings, default branch.
// S = S(repo); I = writer (requires admin access)
secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
integrity = writer_integrity(repo_id, ctx);
}
// === PR revert (creates revert branch + PR) ===
"revert_pull_request" => {
// Creates a new branch + PR reverting a merged PR.
// S = S(repo); I = writer
secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
integrity = writer_integrity(repo_id, ctx);
}
// === Deploy key management (SSH key with optional write access) ===
"add_deploy_key" | "delete_deploy_key" => {
// Manages SSH deploy keys — `add_deploy_key` may grant persistent write access.
// S = private:owner/repo (deploy key secrets should be restricted)
// I = writer (requires admin access)
secrecy = policy_private_scope_label(&owner, &repo, repo_id, ctx);
integrity = writer_integrity(repo_id, ctx);
}
Coverage Architecture Note
The guard's is_delete_operation() and is_merge_operation() functions are used only to select integrity levels within already-classified write operations — NOT to auto-classify new tools. Only lock_* and unlock_* are auto-classified by pattern. This means any new delete_* or merge_* tool added to the MCP server will NOT be automatically guarded unless explicitly added to WRITE_OPERATIONS.
References
Generated by GitHub Guard Coverage Checker (MCP + CLI) · ● 1.8M · ◷
Summary
The GitHub guard covers all 80 tools currently in github-mcp-server with both write-classification and DIFC-labeling rules. However, 3 GitHub CLI write operations have no pre-emptive guard entry — meaning if a corresponding MCP tool is added to the GitHub MCP server, or if an agent invokes these operations via
ghCLI, the guard would not classify them.pkg/github/__toolsnaps__/)GitHub CLI-Only Gaps
These write operations are reachable via the GitHub CLI but have no corresponding MCP tool today and no pre-emptive guard entry. If GitHub MCP server adds a matching tool, the guard would not intercept it.
gh repo editPATCH /repos/{owner}/{repo}edit_repositorygh pr revertrevertPullRequestmutationrevert_pull_requestgh repo deploy-key addPOST /repos/{owner}/{repo}/keysadd_deploy_keyDetail:
gh repo edit→edit_repositorygh repo editusesPATCH /repos/{owner}/{repo}and can change:visibility: public/private (can accidentally expose private code)default_branch: changes the default merge targetdelete_branch_on_merge,allow_auto_merge, security settingsThis is a HIGH-risk operation because changing
visibilityfromprivatetopublicwould expose all repository contents. The guard already has pre-emptive entries for other irreversible repo operations (archive_repository,rename_repository,transfer_repository) butedit_repositoryis missing.Detail:
gh pr revert→revert_pull_requestgh pr revertuses the GraphQLrevertPullRequestmutation. It creates a new branch (from the revert commit) and opens a new PR. This is semantically similar tocreate_pull_request+create_branch, both of which are already inWRITE_OPERATIONS, but the combined operation is not pre-emptively covered.Detail:
gh repo deploy-key add→add_deploy_keygh repo deploy-key addusesPOST /repos/{owner}/{repo}/keysto register an SSH key as a deploy key. With--writeflag, the key gets push access to the repository. This is a HIGH-risk persistent access grant. Note:delete_deploy_keywould also need coverage sincedelete_*is NOT an automatic pattern in the guard (onlylock_*andunlock_*are pattern-matched).Suggested Fix for tools.rs
Add pre-emptive entries to
WRITE_OPERATIONSinguards/github-guard/rust-guard/src/tools.rs:Suggested Fix for tool_rules.rs
Add match arms to
apply_tool_labelsinguards/github-guard/rust-guard/src/labels/tool_rules.rs:Coverage Architecture Note
The guard's
is_delete_operation()andis_merge_operation()functions are used only to select integrity levels within already-classified write operations — NOT to auto-classify new tools. Onlylock_*andunlock_*are auto-classified by pattern. This means any newdelete_*ormerge_*tool added to the MCP server will NOT be automatically guarded unless explicitly added toWRITE_OPERATIONS.References