Skip to content
Merged
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
29 changes: 20 additions & 9 deletions internal/config/validation_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,18 @@ var (
// This URL points to the source of truth for the MCP Gateway configuration schema.
//
// Schema Version Pinning:
// The schema is fetched from the main branch to get the latest version with guard-policies support.
// This ensures the gateway supports the latest configuration features including guard policies.
// The schema is fetched from the main branch to get the latest version.
//
// To update to a specific pinned version:
// 1. Check the latest gh-aw release: https://github.com/github/gh-aw/releases
// 2. Update the URL below to use a version tag instead of main
// 3. Run tests to ensure compatibility: make test
// 4. Update this comment with the version number
//
// Current schema version: main (latest with guard-policies support)
// Current schema version: main (latest)
//
// Alternative: Embed the schema using go:embed directive for zero network dependency.
schemaURL = "https://raw.githubusercontent.com/github/gh-aw/main/pkg/workflow/schemas/mcp-gateway-config.schema.json"
schemaURL = "https://raw.githubusercontent.com/github/gh-aw/main/docs/public/schemas/mcp-gateway-config.schema.json"

// Schema caching to avoid recompiling the JSON schema on every validation
// This improves performance by compiling the schema once and reusing it
Expand Down Expand Up @@ -156,27 +155,39 @@ func fetchAndFixSchema(url string) ([]byte, error) {
}
}

// Add registry field to stdioServerConfig and httpServerConfig
// Spec Section 4.1.2 defines registry as a valid optional field for both server types
// Temporary workaround until the upstream schema is updated
// Add registry and guard-policies fields to stdioServerConfig and httpServerConfig.
// These are workarounds for fields supported by this gateway implementation that are
// not present in the upstream schema:
// - registry: Spec Section 4.1.2 defines this as a valid optional field.
// - guard-policies: Actively used in this implementation for server-level access control.
// The upstream schema previously included this field and may add it back in a future version.
if definitions, ok := schema["definitions"].(map[string]interface{}); ok {
// Define the registry property schema
registryProperty := map[string]interface{}{
"type": "string",
"description": "URI to the installation location when MCP is installed from a registry. This is an informational field used for documentation and tooling discovery.",
}

// Add registry to stdioServerConfig
// Define the guard-policies property schema
guardPoliciesProperty := map[string]interface{}{
"type": "object",
"description": "Guard policies for access control at the MCP gateway level. The structure of guard policies is server-specific.",
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The injected guard-policies property description says it applies "at the MCP gateway level", but the field is being added under each server config (stdioServerConfig/httpServerConfig). Update the description/comment to reflect that it applies to access control for an individual server entry within the gateway config, to avoid confusing schema consumers.

Suggested change
"description": "Guard policies for access control at the MCP gateway level. The structure of guard policies is server-specific.",
"description": "Guard policies for access control for this server entry within the MCP gateway configuration. The structure of guard policies is server-specific.",

Copilot uses AI. Check for mistakes.
"additionalProperties": true,
}

// Add registry and guard-policies to stdioServerConfig
if stdioConfig, ok := definitions["stdioServerConfig"].(map[string]interface{}); ok {
if props, ok := stdioConfig["properties"].(map[string]interface{}); ok {
props["registry"] = registryProperty
props["guard-policies"] = guardPoliciesProperty
}
}

// Add registry to httpServerConfig
// Add registry and guard-policies to httpServerConfig
if httpConfig, ok := definitions["httpServerConfig"].(map[string]interface{}); ok {
if props, ok := httpConfig["properties"].(map[string]interface{}); ok {
props["registry"] = registryProperty
props["guard-policies"] = guardPoliciesProperty
}
}
}
Comment on lines +158 to 193
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

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

The new guard-policies schema injection in fetchAndFixSchema is not covered by existing tests (validation_schema_fetch_test.go currently asserts other transformations but doesn't check for guard-policies/registry being added). Add a focused test that ensures guard-policies is injected into both stdioServerConfig and httpServerConfig so schema validation doesn't regress when the upstream schema changes again.

Copilot uses AI. Check for mistakes.
Expand Down