Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/daily-issues-report.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions .github/workflows/daily-issues-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ permissions:
engine: codex
strict: true
tracker-id: daily-issues-report
features:
dangerous-permissions-write: true
tools:
github:
lockdown: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/daily-observability-report.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions .github/workflows/daily-observability-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ permissions:
engine: codex
strict: true
tracker-id: daily-observability-report
features:
dangerous-permissions-write: true
tools:
github:
toolsets: [default, discussions, actions]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/daily-performance-summary.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions .github/workflows/daily-performance-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ permissions:
engine: codex
strict: true
tracker-id: daily-performance-summary
features:
dangerous-permissions-write: true
tools:
github:
toolsets: [default, discussions]
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/example-permissions-warning.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 5 additions & 7 deletions .github/workflows/example-permissions-warning.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,18 @@ permissions:
tools:
github:
toolsets: [repos, issues, pull_requests]
read-only: false
strict: false
features:
dangerous-permissions-write: true
---

# Example: Properly Provisioned Permissions

This workflow demonstrates properly configured permissions for GitHub toolsets.

The workflow uses three GitHub toolsets with appropriate write permissions:
- The `repos` toolset requires `contents: write` for repository operations
- The `issues` toolset requires `issues: write` for issue management
- The `pull_requests` toolset requires `pull-requests: write` for PR operations
The GitHub MCP server always operates in read-only mode. The workflow uses three
GitHub toolsets with read permissions:
- The `repos` toolset uses `contents: read` for repository operations
- The `issues` toolset uses `issues: read` for issue management
- The `pull_requests` toolset uses `pull-requests: read` for PR operations

All required permissions are properly declared in the frontmatter, so this workflow
compiles without warnings and can execute successfully when dispatched.
2 changes: 1 addition & 1 deletion .github/workflows/org-health-report.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions .github/workflows/org-health-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ safe-outputs:
upload-asset:
timeout-minutes: 60
strict: true
features:
dangerous-permissions-write: true
network:
allowed:
- defaults
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/codemod_schema_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ on:
engine: copilot
permissions:
contents: read
issues: write
issues: read
---

# Complex Workflow
Expand Down
4 changes: 1 addition & 3 deletions pkg/cli/commands_compile_workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,10 @@ on:
schedule:
- cron: "0 9 * * 1"
permissions:
contents: write
contents: read
issues: read
pull-requests: read
strict: false
features:
dangerous-permissions-write: true
---

# Verbose Test Workflow
Expand Down
26 changes: 9 additions & 17 deletions pkg/cli/compile_security_benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ on:
types: [opened, synchronize]
permissions:
contents: read
pull-requests: write
pull-requests: read
engine: copilot
features:
dangerous-permissions-write: true
strict: false
tools:
github:
Expand Down Expand Up @@ -77,10 +75,8 @@ on:
types: [opened]
permissions:
contents: read
issues: write
issues: read
engine: claude
features:
dangerous-permissions-write: true
strict: false
tools:
github:
Expand Down Expand Up @@ -174,8 +170,8 @@ on:
types: [opened, synchronize, reopened]
permissions:
contents: read
issues: write
pull-requests: write
issues: read
pull-requests: read
engine:
id: copilot
max-turns: 5
Expand Down Expand Up @@ -243,10 +239,8 @@ on:
types: [opened, synchronize]
permissions:
contents: read
pull-requests: write
pull-requests: read
engine: copilot
features:
dangerous-permissions-write: true
strict: false
tools:
github:
Expand Down Expand Up @@ -295,10 +289,8 @@ on:
types: [opened]
permissions:
contents: read
issues: write
issues: read
engine: claude
features:
dangerous-permissions-write: true
strict: false
tools:
github:
Expand Down Expand Up @@ -366,9 +358,9 @@ on:
- production
permissions:
contents: read
issues: write
pull-requests: write
deployments: write
issues: read
pull-requests: read
deployments: read
engine:
id: copilot
max-turns: 10
Expand Down
4 changes: 2 additions & 2 deletions pkg/cli/update_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ Base content.`
on: push
permissions:
contents: read
issues: write
issues: read
source: test/repo/workflow.md@v1.0.0
---

Expand All @@ -327,7 +327,7 @@ Base content with local notes.`
on: push
permissions:
contents: read
pull-requests: write
pull-requests: read
---

# Test Workflow
Expand Down
2 changes: 0 additions & 2 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -624,8 +624,6 @@ const (
SafeInputsFeatureFlag FeatureFlag = "safe-inputs"
// MCPGatewayFeatureFlag is the feature flag name for enabling MCP gateway
MCPGatewayFeatureFlag FeatureFlag = "mcp-gateway"
// DangerousPermissionsWriteFeatureFlag is the feature flag name for allowing write permissions
DangerousPermissionsWriteFeatureFlag FeatureFlag = "dangerous-permissions-write"
// DisableXPIAPromptFeatureFlag is the feature flag name for disabling XPIA prompt
DisableXPIAPromptFeatureFlag FeatureFlag = "disable-xpia-prompt"
// CopilotRequestsFeatureFlag is the feature flag name for enabling copilot-requests mode.
Expand Down
1 change: 0 additions & 1 deletion pkg/constants/constants_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ func TestFeatureFlagConstants(t *testing.T) {
}{
{"SafeInputsFeatureFlag", SafeInputsFeatureFlag, "safe-inputs"},
{"MCPGatewayFeatureFlag", MCPGatewayFeatureFlag, "mcp-gateway"},
{"DangerousPermissionsWriteFeatureFlag", DangerousPermissionsWriteFeatureFlag, "dangerous-permissions-write"},
{"DisableXPIAPromptFeatureFlag", DisableXPIAPromptFeatureFlag, "disable-xpia-prompt"},
}

Expand Down
21 changes: 3 additions & 18 deletions pkg/parser/mcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ func processBuiltinMCPTool(toolName string, toolValue any, serverFilter string)
// Check for custom GitHub configuration to determine mode (local vs remote)
var useRemote bool
var customGitHubToken string
var readOnly bool

if toolConfig, ok := toolValue.(map[string]any); ok {
// Check if mode is specified (remote or local)
Expand All @@ -272,13 +271,6 @@ func processBuiltinMCPTool(toolName string, toolValue any, serverFilter string)
customGitHubToken = tokenStr
}
}

// Check for read-only mode
if readOnlyField, hasReadOnly := toolConfig["read-only"]; hasReadOnly {
if readOnlyBool, ok := readOnlyField.(bool); ok {
readOnly = readOnlyBool
}
}
}

var config MCPServerConfig
Expand All @@ -300,10 +292,8 @@ func processBuiltinMCPTool(toolName string, toolValue any, serverFilter string)
config.Env["GITHUB_TOKEN"] = customGitHubToken
}

// Add X-MCP-Readonly header if read-only mode is enabled
if readOnly {
config.Headers["X-MCP-Readonly"] = "true"
}
// Always enforce read-only mode for GitHub MCP server
config.Headers["X-MCP-Readonly"] = "true"
} else {
// Handle GitHub MCP server - use local/Docker by default
config = MCPServerConfig{
Expand All @@ -312,6 +302,7 @@ func processBuiltinMCPTool(toolName string, toolValue any, serverFilter string)
Command: "docker",
Args: []string{
"run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"-e", "GITHUB_READ_ONLY=1", // Always enforce read-only mode
"ghcr.io/github/github-mcp-server:" + string(constants.DefaultGitHubMCPServerVersion),
},
Env: make(map[string]string),
Expand All @@ -331,12 +322,6 @@ func processBuiltinMCPTool(toolName string, toolValue any, serverFilter string)

// Check for custom GitHub configuration
if toolConfig, ok := toolValue.(map[string]any); ok {
// Check for read-only mode (only applicable in local/Docker mode)
if !useRemote && readOnly {
// When read-only is true, inline GITHUB_READ_ONLY=1 in docker args
config.Args = append(config.Args[:5], append([]string{"-e", "GITHUB_READ_ONLY=1"}, config.Args[5:]...)...)
}

if allowed, hasAllowed := toolConfig["allowed"]; hasAllowed {
if allowedSlice, ok := allowed.([]any); ok {
for _, item := range allowedSlice {
Expand Down
30 changes: 29 additions & 1 deletion pkg/parser/mcp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestExtractMCPConfigurations(t *testing.T) {
},
},
{
name: "GitHub tool with read-only false",
name: "GitHub tool with read-only false (always enforced as read-only)",
frontmatter: map[string]any{
"tools": map[string]any{
"github": map[string]any{
Expand All @@ -61,6 +61,7 @@ func TestExtractMCPConfigurations(t *testing.T) {
Command: "docker",
Args: []string{
"run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"-e", "GITHUB_READ_ONLY=1",
"ghcr.io/github/github-mcp-server:" + string(constants.DefaultGitHubMCPServerVersion),
},
Env: map[string]string{
Expand All @@ -71,6 +72,27 @@ func TestExtractMCPConfigurations(t *testing.T) {
},
},
},
{
name: "GitHub tool with boolean true (shorthand)",
frontmatter: map[string]any{
"tools": map[string]any{
"github": true,
},
},
expected: []MCPServerConfig{
{BaseMCPServerConfig: types.BaseMCPServerConfig{Type: "docker",
Command: "docker",
Args: []string{
"run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"-e", "GITHUB_READ_ONLY=1",
"ghcr.io/github/github-mcp-server:" + string(constants.DefaultGitHubMCPServerVersion),
},
Env: map[string]string{
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN_REQUIRED}",
}}, Name: "github",
},
},
},
{
name: "GitHub tool without read-only (default behavior)",
frontmatter: map[string]any{
Expand All @@ -83,6 +105,7 @@ func TestExtractMCPConfigurations(t *testing.T) {
Command: "docker",
Args: []string{
"run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"-e", "GITHUB_READ_ONLY=1",
"ghcr.io/github/github-mcp-server:" + string(constants.DefaultGitHubMCPServerVersion),
},
Env: map[string]string{
Expand Down Expand Up @@ -119,6 +142,7 @@ func TestExtractMCPConfigurations(t *testing.T) {
Command: "docker",
Args: []string{
"run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"-e", "GITHUB_READ_ONLY=1",
"ghcr.io/github/github-mcp-server:" + string(constants.DefaultGitHubMCPServerVersion),
},
Env: map[string]string{"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN_REQUIRED}"}}, Name: "github",
Expand All @@ -142,6 +166,7 @@ func TestExtractMCPConfigurations(t *testing.T) {
Command: "docker",
Args: []string{
"run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"-e", "GITHUB_READ_ONLY=1",
"ghcr.io/github/github-mcp-server:latest",
},
Env: map[string]string{"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN_REQUIRED}"}}, Name: "github",
Expand All @@ -164,6 +189,7 @@ func TestExtractMCPConfigurations(t *testing.T) {
Command: "docker",
Args: []string{
"run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"-e", "GITHUB_READ_ONLY=1",
"ghcr.io/github/github-mcp-server:20",
},
Env: map[string]string{"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN_REQUIRED}"}}, Name: "github",
Expand All @@ -186,6 +212,7 @@ func TestExtractMCPConfigurations(t *testing.T) {
Command: "docker",
Args: []string{
"run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"-e", "GITHUB_READ_ONLY=1",
"ghcr.io/github/github-mcp-server:3.11",
},
Env: map[string]string{"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN_REQUIRED}"}}, Name: "github",
Expand Down Expand Up @@ -317,6 +344,7 @@ func TestExtractMCPConfigurations(t *testing.T) {
Command: "docker",
Args: []string{
"run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
"-e", "GITHUB_READ_ONLY=1",
"ghcr.io/github/github-mcp-server:" + string(constants.DefaultGitHubMCPServerVersion),
},
Env: map[string]string{"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN_REQUIRED}"}}, Name: "github",
Expand Down
Loading
Loading