-
Notifications
You must be signed in to change notification settings - Fork 352
feat: add integrity-reactions feature flag for MCPG reaction-based integrity promotion/demotion
#25948
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add integrity-reactions feature flag for MCPG reaction-based integrity promotion/demotion
#25948
Changes from 3 commits
f8ae92c
85b43d9
7ae5c5c
c637ceb
0884b7e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -150,6 +150,15 @@ func (c *Compiler) ParseWorkflowString(content string, virtualPath string) (*Wor | |
| return nil, fmt.Errorf("%s: %w", cleanPath, err) | ||
| } | ||
|
|
||
| // Validate integrity-reactions feature configuration | ||
| var gatewayConfig *MCPGatewayRuntimeConfig | ||
| if workflowData.SandboxConfig != nil { | ||
| gatewayConfig = workflowData.SandboxConfig.MCP | ||
| } | ||
| if err := validateIntegrityReactions(workflowData.ParsedTools, workflowData.Name, workflowData, gatewayConfig); err != nil { | ||
| return nil, fmt.Errorf("%s: %w", cleanPath, err) | ||
| } | ||
|
Comment on lines
+153
to
+160
|
||
|
|
||
| // Setup action cache and resolver | ||
| actionCache, actionResolver := c.getSharedActionResolver() | ||
| workflowData.ActionCache = actionCache | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -68,6 +68,7 @@ import ( | |||||||||||
|
|
||||||||||||
| "github.com/github/gh-aw/pkg/constants" | ||||||||||||
| "github.com/github/gh-aw/pkg/logger" | ||||||||||||
| "github.com/github/gh-aw/pkg/semverutil" | ||||||||||||
| ) | ||||||||||||
|
|
||||||||||||
| var githubConfigLog = logger.New("workflow:mcp_github_config") | ||||||||||||
|
|
@@ -287,6 +288,63 @@ func getGitHubGuardPolicies(githubTool any) map[string]any { | |||||||||||
| return nil | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // injectIntegrityReactionFields adds endorsement-reactions, disapproval-reactions, | ||||||||||||
| // disapproval-integrity, and endorser-min-integrity into an existing allow-only policy | ||||||||||||
| // map when the integrity-reactions feature flag is enabled and the MCPG version supports it. | ||||||||||||
| // - policy is the inner allow-only map (not the outer allow-only wrapper). | ||||||||||||
| // - toolConfig is the raw github tool configuration map. | ||||||||||||
| // - data contains workflow data including feature flags used to check if integrity-reactions is enabled. | ||||||||||||
| // - gatewayConfig contains MCP gateway version configuration used to version-gate the injection. | ||||||||||||
| // | ||||||||||||
| // No-op when the feature flag is disabled or the MCPG version is too old. | ||||||||||||
| func injectIntegrityReactionFields(policy map[string]any, toolConfig map[string]any, data *WorkflowData, gatewayConfig *MCPGatewayRuntimeConfig) { | ||||||||||||
| if !isFeatureEnabled(constants.IntegrityReactionsFeatureFlag, data) { | ||||||||||||
| return | ||||||||||||
| } | ||||||||||||
| if !mcpgSupportsIntegrityReactions(gatewayConfig) { | ||||||||||||
| return | ||||||||||||
| } | ||||||||||||
| if endorsement, ok := toolConfig["endorsement-reactions"]; ok { | ||||||||||||
| policy["endorsement-reactions"] = endorsement | ||||||||||||
| } | ||||||||||||
| if disapproval, ok := toolConfig["disapproval-reactions"]; ok { | ||||||||||||
| policy["disapproval-reactions"] = disapproval | ||||||||||||
| } | ||||||||||||
| if disapprovalIntegrity, ok := toolConfig["disapproval-integrity"]; ok { | ||||||||||||
| policy["disapproval-integrity"] = disapprovalIntegrity | ||||||||||||
| } | ||||||||||||
| if endorserMinIntegrity, ok := toolConfig["endorser-min-integrity"]; ok { | ||||||||||||
| policy["endorser-min-integrity"] = endorserMinIntegrity | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // mcpgSupportsIntegrityReactions returns true when the effective MCPG version supports | ||||||||||||
| // endorsement-reactions and disapproval-reactions in the allow-only policy (>= v0.2.18). | ||||||||||||
| // | ||||||||||||
| // Special cases: | ||||||||||||
| // - gatewayConfig is nil or has no Version: use DefaultMCPGatewayVersion for comparison. | ||||||||||||
| // - "latest": always returns true (latest is always a new release). | ||||||||||||
| // - Any semver string >= MCPGIntegrityReactionsMinVersion: returns true. | ||||||||||||
| // - Any semver string < MCPGIntegrityReactionsMinVersion: returns false. | ||||||||||||
| // - Non-semver string (e.g. a branch name): returns false (conservative). | ||||||||||||
| func mcpgSupportsIntegrityReactions(gatewayConfig *MCPGatewayRuntimeConfig) bool { | ||||||||||||
| var version string | ||||||||||||
| if gatewayConfig != nil && gatewayConfig.Version != "" { | ||||||||||||
| version = gatewayConfig.Version | ||||||||||||
| } else { | ||||||||||||
| // No override → use the default version for comparison. | ||||||||||||
| version = string(constants.DefaultMCPGatewayVersion) | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // "latest" means the newest release — always supports the field. | ||||||||||||
| if strings.EqualFold(version, "latest") { | ||||||||||||
| return true | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
|
||||||||||||
| if !semverutil.IsValid(version) { | |
| return false | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validateIntegrityReactions runs before features from imports are merged (MergeFeatures is later). This can reject workflows that enable integrity-reactions through an imported workflow because isFeatureEnabled() won’t observe the merged feature flags yet. Run this validation after feature merging (or validate against the merged feature map).