Implement refusal-labels guard policy and align health specVersion with MCP Gateway v1.14.0#7700
Merged
Merged
Conversation
Copilot
AI
changed the title
[WIP] Update MCP Gateway compliance for refusal-labels and specVersion
Implement Jun 18, 2026
refusal-labels guard policy and align health specVersion with MCP Gateway v1.14.0
Contributor
There was a problem hiding this comment.
Pull request overview
This PR closes spec-drift gaps by adding end-to-end support for the refusal-labels allow-only policy (parsing/normalization, strict transport shaping, and Rust guard integrity evaluation) and by updating /health.specVersion to report MCP Gateway spec 1.14.0.
Changes:
- Update
/health.specVersionto1.14.0. - Extend Go guard policy model + JSON parsing/normalization + strict payload shaping to include
refusal-labels(array or comma/newline expression). - Extend Rust GitHub guard policy context and integrity post-adjustments to demote items to
nonewhen matching a configured refusal label, with precedence tests.
Show a summary per file
| File | Description |
|---|---|
| internal/server/unified.go | Bumps reported MCPGatewaySpecVersion to 1.14.0. |
| internal/guard/wasm_test.go | Adds strict payload transport tests covering refusal-labels success, expression normalization, and type errors. |
| internal/guard/wasm_payload.go | Allows refusal-labels key in strict allow-only payloads and normalizes it before WASM transport. |
| internal/config/guard_policy.go | Adds RefusalLabels to policy structs and supports JSON unmarshal from list or expression string. |
| internal/config/guard_policy_validation.go | Normalizes/dedups refusal-labels alongside other allow-only list fields. |
| internal/config/guard_policy_test.go | Adds unit tests for refusal-label normalization and JSON unmarshal behavior. |
| guards/github-guard/rust-guard/src/tools.rs | Formatting-only alignment in write operation list. |
| guards/github-guard/rust-guard/src/lib.rs | Wires refusal_labels into Rust AllowOnlyPolicy and PolicyContext used by label_agent. |
| guards/github-guard/rust-guard/src/labels/tool_rules.rs | Formatting-only refactors in imports/tests. |
| guards/github-guard/rust-guard/src/labels/response_paths.rs | Formatting-only refactors in match arms and control flow. |
| guards/github-guard/rust-guard/src/labels/response_items.rs | Formatting-only refactors in match arms and control flow. |
| guards/github-guard/rust-guard/src/labels/mod.rs | Exposes refusal-label helpers for tests and adds refusal-label precedence tests. |
| guards/github-guard/rust-guard/src/labels/helpers.rs | Adds refusal-label matching + demotion and integrates it into the post-integrity adjustment pipeline. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 12/13 changed files
- Comments generated: 3
Comment on lines
+192
to
+197
| if arr, ok := raw.([]interface{}); ok { | ||
| if err := config.ValidateStringArrayField(field, arr, false); err != nil { | ||
| return nil, err | ||
| } | ||
| return arr, nil | ||
| } |
| let integrity = ensure_integrity_baseline(repo_full_name, integrity, ctx); | ||
|
|
||
| // Steps 2–4: approval-label promotion → endorsement promotion → disapproval demotion. | ||
| // Post-adjustments: refusal demotion → approval/promotion/endorsement → demotions. |
| let integrity = ensure_integrity_baseline(repo_full_name, integrity, ctx); | ||
|
|
||
| // Steps 2–4: approval-label promotion → endorsement promotion → disapproval demotion. | ||
| // Post-adjustments: refusal demotion → approval/promotion/endorsement → demotions. |
Collaborator
|
@copilot address review feedback |
Contributor
Author
Addressed in 84ba250.
|
This was referenced Jun 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Compliance review found two spec-drift gaps:
refusal-labelswas not implemented end-to-end in guard policy handling, and/healthreported an outdated gateway spec version. This PR wiresrefusal-labelsthrough policy parsing/validation and integrity evaluation, and updates reportedspecVersionto1.14.0.Guard policy model + normalization (Go)
refusal-labelstoAllowOnlyPolicyandNormalizedGuardPolicy.refusal-labelsas:refusal-labelscase-insensitively (same pattern as existing label/user fields).WASM policy transport validation (Go)
refusal-labelsto strict allow-only key allowlist.refusal-labelsin payload shaping, including expression-string expansion into normalized label arrays.Effective integrity computation (Rust guard)
refusal_labelsto RustAllowOnlyPolicyinput andPolicyContext.blocked-usersremains highest precedence,refusal-labelsdemotes tononeand overrides trusted-user / approval-label promotion paths.Health contract alignment
MCPGatewaySpecVersionfrom1.9.0to1.14.0so/health.specVersionreflects current implemented spec target.Coverage updates
refusal-labelsparse/normalize paths,blocked-users>refusal-labels> approval/trusted-user promotions).{ "allow-only": { "repos": "public", "min-integrity": "approved", "refusal-labels": "unsafe, needs-triage\nblocked" } }