Skip to content

[compliance] Compliance Gap: gateway.opentelemetry schema missing fields (headers blocked, sampleRate doc regression) — commit 27fc0d0 #7009

Closed

Description

@github-actions

MCP Gateway Compliance Review — 2026-06-04

Summary

Found 2 compliance issues introduced or exposed by commit 27fc0d0 (Reconcile configuration/docs semantics and Go version guidance with current implementation). Both relate to the gateway.opentelemetry block in JSON stdin configuration.

Commit Reviewed


Important Issues (SHOULD violations)

Issue 1: gateway.opentelemetry.headers silently blocked by JSON schema

Specification Section: 4.1.3.6 OpenTelemetry Configuration
Deep Link: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/mcp-gateway.md#4136-opentelemetry-tracing

Requirement:

The gateway SHOULD support all documented configuration fields in the JSON stdin format.

Current State:

The embedded JSON schema (internal/config/schema/mcp-gateway-config.schema.json, v0.64.4) defines opentelemetryConfig with additionalProperties: false and only four properties: endpoint, traceId, spanId, serviceName. The headers field is absent from this schema definition.

However:

  • StdinOpenTelemetryConfig in internal/config/config_stdin.go:55 does have a Headers field
  • The stdin converter in internal/config/config_tracing.go:133–139 does copy Headers into TracingConfig
  • docs/CONFIGURATION.md:448 documents headers as a valid JSON stdin field

Because validateJSONSchema() in internal/config/validation_schema.go:394 runs the full JSON against the embedded schema before the struct is populated, any JSON stdin config that includes gateway.opentelemetry.headers will be rejected with a schema validation error:

additional property "headers" is not allowed (at gateway.opentelemetry)

Gap:

  • internal/config/schema/mcp-gateway-config.schema.json — opentelemetryConfig definition is missing headers
  • internal/config/validation_schema.go — fixSchemaBytes() adds missing fields to other definitions (e.g., trustedBots, keepaliveInterval, guard-policies) but does not add headers to opentelemetryConfig

Severity: Important (SHOULD violation — documented field is blocked by schema)

File References:

  • internal/config/schema/mcp-gateway-config.schema.json — definitions.opentelemetryConfig (line ~200)
  • internal/config/validation_schema.go:218–245 — fixSchemaBytes() patching logic
  • internal/config/config_stdin.go:55 — Headers field present in struct
  • internal/config/config_tracing.go:133–139 — converter copies Headers
  • docs/CONFIGURATION.md:448 — documents headers as valid JSON stdin field

Suggested Fix — Option A (preferred): Add a fix in fixSchemaBytes() in internal/config/validation_schema.go to inject the headers property into opentelemetryConfig, similar to how keepaliveInterval and trustedBots are injected into gatewayConfig:

// Add headers to opentelemetryConfig (supported by implementation but absent from schema v0.64.4)
if opentelemetryConfig, ok := definitions["opentelemetryConfig"].(map[string]interface{}); ok {
    if props, ok := opentelemetryConfig["properties"].(map[string]interface{}); ok {
        props["headers"] = map[string]interface{}{
            "type":        "string",
            "description": "Comma-separated key=value HTTP headers for OTLP export requests. Supports ${VAR} expansion.",
        }
        logSchema.Print("Added headers field to opentelemetryConfig")
    }
}

Suggested Fix — Option B: Update the bundled schema file directly to add headers to opentelemetryConfig.


Minor Issues (documentation regressions)

Issue 2: sampleRate documented as JSON stdin field but not implemented (regression from #6998)

Specification Section: 4.1.3.6 OpenTelemetry Configuration
Deep Link: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/mcp-gateway.md#4136-opentelemetry-tracing

Requirement:

Documentation MUST accurately reflect the supported configuration interface.

Current State:

Commit 27fc0d0 updated docs/CONFIGURATION.md:451 to say:

sample_rate (TOML) / sampleRate (JSON stdin) | Fraction of traces sampled and exported (0.0–1.0). Also available via CLI --otlp-sample-rate.

However, sampleRate in JSON stdin does not work:

  1. Schema blocks it: opentelemetryConfig has additionalProperties: false, so providing sampleRate in gateway.opentelemetry via JSON stdin causes schema validation failure.
  2. StdinOpenTelemetryConfig has no field: internal/config/config_stdin.go:48–65 — StdinOpenTelemetryConfig has no SampleRate field, so even if the schema were fixed, the value would not be parsed.
  3. Converter does not copy it: internal/config/config_tracing.go:133–139 — the RegisterStdinConverter does not set SampleRate when building TracingConfig from StdinOpenTelemetryConfig.

sampleRate does work via:

  • TOML: [gateway.opentelemetry] sample_rate = 0.5 (uses TracingConfig.SampleRate with TOML tag)
  • CLI: --otlp-sample-rate 0.5

Gap: The CONFIGURATION.md entry sampleRate (JSON stdin) is inaccurate — this was a documentation regression introduced in commit 27fc0d0.

Severity: Minor (documentation regression — feature described in docs does not work)

File References:

Suggested Fix: Either:

  • (A) Remove sampleRate (JSON stdin) from the CONFIGURATION.md table and note that sampleRate is TOML/CLI-only (simplest, accurate)
  • (B) Implement JSON stdin support: add SampleRate *float64 \json:"sampleRate,omitempty"`toStdinOpenTelemetryConfig, copy it in the converter, and inject the field into the schema via fixSchemaBytes()`

Compliance Status

Section Status Notes
Configuration Format (§4.1) ✅ Compliant Required fields validated, variable expansion works
Containerization (§3.2.1) ✅ Compliant TOML validates command=docker; JSON stdin requires container
Protocol Behavior (§5) ✅ Compliant /mcp/{server}, health, JSON-RPC 2.0
Server Isolation (§6) ✅ Compliant Each server containerized
Authentication (§7) ✅ Compliant API key in Authorization header (not Bearer), health exempt
Health Monitoring (§8) ✅ Compliant /health endpoint, spec 8.1.1 response structure
Error Handling (§9) ✅ Compliant Exit code 1 on startup failure
OpenTelemetry Config (§4.1.3.6) ⚠️ Partial headers schema mismatch; sampleRate docs regression
Rate Limit Config ✅ Compliant Correctly documented as TOML-only
tool_response_filters ✅ Compliant Correctly documented as snake_case only

Suggested Remediation Tasks

Task 1: Inject headers into opentelemetryConfig in fixSchemaBytes()

Description: Add a patch in internal/config/validation_schema.go's fixSchemaBytes() to add the headers field to the opentelemetryConfig schema definition, mirroring the pattern used for keepaliveInterval and trustedBots in gatewayConfig. Also add a test that headers in gateway.opentelemetry passes LoadFromStdin().
Files: internal/config/validation_schema.go, internal/config/load_from_stdin_coverage_test.go (or validation_otel_test.go)
Specification Reference: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/mcp-gateway.md#4136-opentelemetry-tracing
Estimated Effort: Small (1–2 hours)

Task 2: Resolve sampleRate JSON stdin discrepancy

Description: Either remove sampleRate (JSON stdin) from CONFIGURATION.md (simplest fix, requires only a docs change) or implement full JSON stdin support for sampleRate (requires: add field to StdinOpenTelemetryConfig, copy in converter, add schema injection, add tests).
Files: docs/CONFIGURATION.md (required); optionally internal/config/config_stdin.go, internal/config/config_tracing.go, internal/config/validation_schema.go
Specification Reference: https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/mcp-gateway.md#4136-opentelemetry-tracing
Estimated Effort: Small (30 min for docs-only fix; 2–3 hours for full implementation)

References

  • MCP Gateway Specification
  • Commit reviewed: 27fc0d0 (grafted, HEAD → main)
  • Previous review: all other aspects passing (cache from 2026-06-03)

Note

🔒 Integrity filter blocked 1 item

The following item was blocked because it doesn't meet the GitHub integrity level.

  • get_file_contents get_file_contents: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

Generated by Daily Compliance Checker · sonnet46 6.5M · ◷

Activity

  1. github-actions commented on Jun 5, 2026

    @github-actions
    ContributorAuthor

    🤖 This is an automated response from Repo Assist.

    Thanks for the detailed compliance report. I've reviewed the code and can confirm both findings are accurate.

    Issue 1 (headers schema mismatch) — confirmed real bug.

    The pipeline is:

    1. validateJSONSchema() in validation_schema.go runs the full JSON through the bundled schema before struct parsing
    2. opentelemetryConfig has additionalProperties: false with only endpoint, traceId, spanId, serviceName defined — headers is absent
    3. Result: any JSON stdin config with gateway.opentelemetry.headers fails schema validation with "additional property not allowed"

    Yet StdinOpenTelemetryConfig.Headers is correctly declared at config_stdin.go:55 and config_tracing.go:135 correctly copies it into TracingConfig.Headers. The feature is fully implemented — only the schema gate blocks it.

    Option A is the right fix: add headers to opentelemetryConfig in fixSchemaBytes() in validation_schema.go, exactly mirroring the keepaliveInterval patch added in the same function (~line 239). The entry should be:

    if opentelemetryConfig, ok := definitions["opentelemetryConfig"].(map[string]interface{}); ok {
        if props, ok := opentelemetryConfig["properties"].(map[string]interface{}); ok {
            props["headers"] = map[string]interface{}{
                "type":        "string",
                "description": "Comma-separated key=value HTTP headers for OTLP export requests. Supports ${VAR} expansion.",
            }
        }
    }

    A companion test in config_stdin_test.go (or validation_schema_test.go) that passes gateway.opentelemetry.headers through LoadFromStdin() and asserts it reaches TracingConfig.Headers would pin this permanently.

    Issue 2 (sampleRate docs regression) — confirmed. StdinOpenTelemetryConfig has no SampleRate field, the converter doesn't set it, and the schema would reject it anyway. The CONFIGURATION.md column is inaccurate. Option A (remove the JSON stdin column from docs) is the least-risk fix; Option B (implement it) would be the complete fix but requires more work (StdinOpenTelemetryConfig.SampleRate *float64, converter update, schema injection, test).

    Both fixes are small and low-risk. Happy to submit a PR if that would be helpful.

    Warning

    Firewall blocked 1 domain

    The following domain was blocked by the firewall during workflow execution:

    • proxy.golang.org

    To allow these domains, add them to the network.allowed list in your workflow frontmatter:

    network:
      allowed:
        - defaults
        - "proxy.golang.org"

    See Network Configuration for more information.

    Generated by Repo Assist · sonnet46 6.1M · ◷

    Add this agentic workflows to your repo

    To install this agentic workflow, run

    gh aw add githubnext/agentics/workflows/repo-assist.md@851905c06e905bf362a9f6cc54f912e3df747d55
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions