Allow SHA-256 digests in container image references#3352
Conversation
Update containerPattern regex and JSON schema to accept optional @sha256:<64-hex-chars> suffix on container image references. This enables digest-pinned references like: - image:tag@sha256:abc123... - image@sha256:abc123... Add test cases for valid and invalid digest patterns. Agent-Logs-Url: https://github.com/github/gh-aw-mcpg/sessions/a36ac9ee-c2c2-4156-83d6-c836034383c3 Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates MCP Gateway configuration validation to allow digest-pinned container image references (@sha256:<digest>), enabling immutable image pinning for improved supply-chain security.
Changes:
- Extend the Go
containerPatternregex to accept an optional@sha256:<64-hex>suffix. - Mirror the same container regex update in the bundled JSON Schema.
- Add test cases covering valid digest-pinned references and invalid digest formats/algorithms.
Show a summary per file
| File | Description |
|---|---|
| internal/config/validation_schema.go | Expands containerPattern to accept @sha256: digests during extra string-pattern validation. |
| internal/config/schema/mcp-gateway-config.schema.json | Updates the schema’s container pattern to match the new digest-accepting format. |
| internal/config/validation_schema_test.go | Adds validateStringPatterns coverage for digest-pinned container references. |
| internal/config/validation_string_patterns_test.go | Adds comprehensive valid/invalid digest-pinned container pattern test cases. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 4/4 changed files
- Comments generated: 2
| var ( | ||
| // Compile regex patterns from schema for additional validation | ||
| containerPattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9./_-]*(:([a-zA-Z0-9._-]+|latest))?$`) | ||
| containerPattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9./_-]*(:([a-zA-Z0-9._-]+|latest))?(@sha256:[a-fA-F0-9]{64})?$`) |
There was a problem hiding this comment.
Now that digest-pinned references are accepted, the container validation error hint should include an example with an @sha256:<64-hex> suffix; otherwise users who provide a digest will still see guidance that implies only :tag is supported.
| @@ -76,7 +76,7 @@ | |||
| "type": "string", | |||
| "description": "Container image for the MCP server (e.g., 'ghcr.io/example/mcp-server:latest'). This field is required for stdio servers per MCP Gateway Specification section 4.1.2.", | |||
There was a problem hiding this comment.
The schema's container field description example still only shows :latest. Since the pattern now allows digest pinning, update the description examples to include an @sha256:<digest> form so users discover the feature via the schema/docs.
| "description": "Container image for the MCP server (e.g., 'ghcr.io/example/mcp-server:latest'). This field is required for stdio servers per MCP Gateway Specification section 4.1.2.", | |
| "description": "Container image for the MCP server (e.g., 'ghcr.io/example/mcp-server:latest' or 'ghcr.io/example/mcp-server@sha256:<digest>'). This field is required for stdio servers per MCP Gateway Specification section 4.1.2.", |
|
@copilot apply changes based on the comments in this thread |
…pport Agent-Logs-Url: https://github.com/github/gh-aw-mcpg/sessions/c0572733-6f1d-4e16-98d8-4d1cafd9413b Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Applied both review comments in
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
The
containerfield regex rejects@sha256:digest-pinned image references, blocking immutable container image pinning for supply-chain security.Changes
validation_schema.go): Append optional(@sha256:[a-fA-F0-9]{64})?group tocontainerPatternmcp-gateway-config.schema.json): Mirror the same pattern updateimage:tag@sha256:...,image@sha256:...) and invalid cases (short digest, wrong algorithm)Now accepts:
No launcher changes needed — Docker already resolves the full
image:tag@sha256:...reference passed through.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
example.com/tmp/go-build2438908248/b514/launcher.test /tmp/go-build2438908248/b514/launcher.test -test.testlogfile=/tmp/go-build2438908248/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s go_.�� @v1.1.3/internal-errorsas 64/src/debug/dwa-ifaceassert x_amd64/vet --gdwarf-5 nal/version -o x_amd64/vet -plu�� /sdk@v1.43.0/tra-errorsas /sdk@v1.43.0/tra-ifaceassert x_amd64/vet -plugin-opt=-pasdocker telabs/wazero/ininfo -plugin-opt=-pas-stringintconv x_amd64/vet(dns block)invalid-host-that-does-not-exist-12345.com/tmp/go-build2438908248/b496/config.test /tmp/go-build2438908248/b496/config.test -test.testlogfile=/tmp/go-build2438908248/b496/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build2438908248/b393/vet.cfg g_.a --debug-prefix-map x_amd64/vet -I 0218966/b157/ -I x_amd64/vet(dns block)nonexistent.local/tmp/go-build2438908248/b514/launcher.test /tmp/go-build2438908248/b514/launcher.test -test.testlogfile=/tmp/go-build2438908248/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s go_.�� @v1.1.3/internal-errorsas 64/src/debug/dwa-ifaceassert x_amd64/vet --gdwarf-5 nal/version -o x_amd64/vet -plu�� /sdk@v1.43.0/tra-errorsas /sdk@v1.43.0/tra-ifaceassert x_amd64/vet -plugin-opt=-pasdocker telabs/wazero/ininfo -plugin-opt=-pas-stringintconv x_amd64/vet(dns block)slow.example.com/tmp/go-build2438908248/b514/launcher.test /tmp/go-build2438908248/b514/launcher.test -test.testlogfile=/tmp/go-build2438908248/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s go_.�� @v1.1.3/internal-errorsas 64/src/debug/dwa-ifaceassert x_amd64/vet --gdwarf-5 nal/version -o x_amd64/vet -plu�� /sdk@v1.43.0/tra-errorsas /sdk@v1.43.0/tra-ifaceassert x_amd64/vet -plugin-opt=-pasdocker telabs/wazero/ininfo -plugin-opt=-pas-stringintconv x_amd64/vet(dns block)this-host-does-not-exist-12345.com/tmp/go-build2438908248/b523/mcp.test /tmp/go-build2438908248/b523/mcp.test -test.testlogfile=/tmp/go-build2438908248/b523/testlog.txt -test.paniconexit0 -test.timeout=10m0s -p g_.a -trimpath x_amd64/vet -I ernal/proxy -I x_amd64/vet -uns�� .cfg /tmp/go-build1090218966/b063/vet-ifaceassert x_amd64/vet -D GOAMD64_v1 -o x_amd64/vet(dns block)If you need me to access, download, or install something from one of these locations, you can either: