Skip to content

Add permissions validator for GitHub MCP toolsets#2768

Merged
pelikhan merged 6 commits intomainfrom
copilot/add-permissions-validation-checker
Oct 30, 2025
Merged

Add permissions validator for GitHub MCP toolsets#2768
pelikhan merged 6 commits intomainfrom
copilot/add-permissions-validation-checker

Conversation

Copy link
Contributor

Copilot AI commented Oct 30, 2025

Permissions Validation Checker for GitHub MCP Toolsets

  • Create toolset-to-permission mapping based on GitHub MCP server documentation
  • Implement permissions validation checker in separate file (permissions_validator.go)
  • Check that permissions cover requested GitHub MCP toolsets (suggest missing permissions)
  • Check for over-provisioned permissions (warn or error in strict mode, suggest unnecessary permissions)
  • Reuse existing Permissions data structure
  • Add comprehensive unit tests (all passing)
  • Integrate validation into compilation process
  • Fix test workflows with required permissions
  • Refactor GitHub toolsets parsing to separate file (github_toolsets.go)
  • Add tests for GitHub toolsets parsing
  • Document the feature

Latest Changes (Refactoring)

New Files:

  • pkg/workflow/github_toolsets.go - GitHub MCP toolsets parsing logic
    • DefaultGitHubToolsets constant matching documented defaults
    • ParseGitHubToolsets() function for expanding "default" and "all"
  • pkg/workflow/github_toolsets_test.go - Comprehensive tests for toolsets parsing

Modified Files:

  • pkg/workflow/permissions_validator.go - Now uses exported functions from github_toolsets.go
  • pkg/workflow/permissions_validator_test.go - Removed duplicate test cases

Benefits:

  • Better code organization - GitHub-specific logic in dedicated file
  • Reusable parsing functions can be used by other components
  • More comprehensive test coverage
  • Clearer separation of concerns

All tests passing ✅

Original prompt

Add a permissions validation checker that verifies that permissions and github MCP toolsets are compatible:

  • create a mapping of toolset -> permission
  • check that the permissions set covers the requested github MCP toolsets. Suggest which permission is needed.
  • check that the permissions are not over-provisioning for the toolsets. Permissions should be minimal. Warning or error in strict mode. Suggest which permission is not needed

Place checker in separate .go file. Reuse Permissions data structure.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 4 commits October 30, 2025 04:04
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Add permissions validation checker for GitHub MCP toolsets Add permissions validator for GitHub MCP toolsets Oct 30, 2025
Copilot AI requested a review from pelikhan October 30, 2025 04:31
}

// defaultToolsets defines the toolsets that are enabled when "default" is specified
var defaultToolsets = []string{"context", "repos", "issues", "pull_requests", "users"}
Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot review GitHub mcp server for default toolsets constant

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Verified that DefaultGitHubToolsets matches the documented default toolsets in github-mcp-server.instructions.md (context, repos, issues, pull_requests, users). Moved to exported constant in github_toolsets.go (commit 63576b4).

}

// parseToolsets parses the toolsets string and expands "default" and "all"
func parseToolsets(toolsetsStr string) []string {
Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot move to separate github file and reuse existing GitHub MCP sever code, add tests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved GitHub toolsets parsing to github_toolsets.go with comprehensive tests in github_toolsets_test.go. The ParseGitHubToolsets function now reuses the existing toolsetPermissionsMap and is properly separated from the validator logic (commit 63576b4).

- Move defaultToolsets constant to DefaultGitHubToolsets in github_toolsets.go
- Move parseToolsets function to ParseGitHubToolsets in github_toolsets.go
- Add comprehensive tests in github_toolsets_test.go
- Update permissions_validator.go to use new exported functions
- Remove duplicate test cases from permissions_validator_test.go

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI requested a review from pelikhan October 30, 2025 04:42
@pelikhan pelikhan marked this pull request as ready for review October 30, 2025 04:46
Copilot AI review requested due to automatic review settings October 30, 2025 04:46
@github-actions
Copy link
Contributor

Agentic Changeset Generator triggered by this pull request.

@pelikhan pelikhan merged commit 11cfdb2 into main Oct 30, 2025
6 of 7 checks passed
@pelikhan pelikhan deleted the copilot/add-permissions-validation-checker branch October 30, 2025 04:46
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

This PR implements a comprehensive permissions validation system for GitHub MCP toolsets. The system validates that workflow permissions align with the configured GitHub MCP toolsets to ensure security best practices by detecting both missing and over-provisioned permissions.

Key changes:

  • Created GitHub toolsets parsing logic with support for "default" and "all" expansions
  • Implemented permissions validation that maps toolsets to required permissions
  • Integrated validation into the compilation process with appropriate error/warning handling

Reviewed Changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/workflow/permissions_validator.go Core permissions validation logic with toolset-to-permission mapping
pkg/workflow/permissions_validator_test.go Comprehensive test suite for validation functionality
pkg/workflow/github_toolsets.go GitHub toolsets parsing with "default" and "all" expansion
pkg/workflow/github_toolsets_test.go Tests for GitHub toolsets parsing logic
pkg/workflow/compiler.go Integration of permissions validation into compilation process
Various test files Updated test workflows with required permissions to fix test failures
.github/workflows/*.lock.yml Updated Node.js action versions in locked workflows

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

lines = append(lines, "Consider removing these permissions or adjusting your toolsets configuration.")

return strings.Join(lines, "\n")
}
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

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

The permissions validator module lacks comprehensive documentation. Consider adding package-level documentation explaining the validation system, toolset-to-permission mappings, and usage examples.

Copilot uses AI. Check for mistakes.
}
} else if toolset == "all" {
// Add all toolsets from the toolset permissions map
for t := range toolsetPermissionsMap {
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

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

The function depends on the global toolsetPermissionsMap variable which creates tight coupling. Consider passing the toolset map as a parameter or making it a method on a struct to improve testability and modularity.

Copilot uses AI. Check for mistakes.

// Check for excess permissions (only for specific toolsets, not "all")
// Note: "default" is expanded to specific toolsets, so excess checking should still happen
shouldCheckExcess := !containsAllToolset(toolsetsStr)
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

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

The excess permission checking logic uses the original toolsets string rather than the parsed toolsets. This creates inconsistency and could be confusing. Consider using a flag or checking the parsed toolsets instead.

Copilot uses AI. Check for mistakes.
Comment on lines +275 to +282
result.ExcessPermissions[scope] = grantedLevel
result.ExcessPermissionScopes = append(result.ExcessPermissionScopes, scope)
continue
}

// If write permission is granted but only read is required
if grantedLevel == PermissionWrite && requiredLevel == PermissionRead {
result.ExcessPermissions[scope] = PermissionWrite
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

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

The logic stores the excess permission as the granted level (PermissionWrite) rather than indicating what the excess is (Write when Read would suffice). This could be clearer for users trying to understand what needs to be changed.

Suggested change
result.ExcessPermissions[scope] = grantedLevel
result.ExcessPermissionScopes = append(result.ExcessPermissionScopes, scope)
continue
}
// If write permission is granted but only read is required
if grantedLevel == PermissionWrite && requiredLevel == PermissionRead {
result.ExcessPermissions[scope] = PermissionWrite
result.ExcessPermissions[scope] = fmt.Sprintf("granted: %s, required: none", grantedLevel)
result.ExcessPermissionScopes = append(result.ExcessPermissionScopes, scope)
continue
}
// If write permission is granted but only read is required
if grantedLevel == PermissionWrite && requiredLevel == PermissionRead {
result.ExcessPermissions[scope] = fmt.Sprintf("granted: %s, required: %s", grantedLevel, requiredLevel)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants