Skip to content

Allow SHA-256 digests in container image references#3352

Merged
lpcox merged 3 commits intomainfrom
copilot/allow-sha256-digests
Apr 8, 2026
Merged

Allow SHA-256 digests in container image references#3352
lpcox merged 3 commits intomainfrom
copilot/allow-sha256-digests

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 8, 2026

The container field regex rejects @sha256: digest-pinned image references, blocking immutable container image pinning for supply-chain security.

Changes

  • Regex pattern (validation_schema.go): Append optional (@sha256:[a-fA-F0-9]{64})? group to containerPattern
  • JSON schema (mcp-gateway-config.schema.json): Mirror the same pattern update
  • Tests: Add valid cases (image:tag@sha256:..., image@sha256:...) and invalid cases (short digest, wrong algorithm)

Now accepts:

ghcr.io/github/github-mcp-server:v0.32.0@sha256:2763823c67a0adca...
ghcr.io/github/github-mcp-server@sha256:2763823c67a0adca...

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
    • Triggering command: /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
    • Triggering command: /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
    • Triggering command: /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
    • Triggering command: /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
    • Triggering command: /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:

Copilot AI linked an issue Apr 8, 2026 that may be closed by this pull request
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>
Copilot AI changed the title [WIP] Allow SHA-256 digests in container image references Allow SHA-256 digests in container image references Apr 8, 2026
Copilot AI requested a review from lpcox April 8, 2026 00:51
Copilot finished work on behalf of lpcox April 8, 2026 00:51
@lpcox lpcox marked this pull request as ready for review April 8, 2026 00:58
Copilot AI review requested due to automatic review settings April 8, 2026 00:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 containerPattern regex 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})?$`)
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
@@ -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.",
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
"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 uses AI. Check for mistakes.
@lpcox
Copy link
Copy Markdown
Collaborator

lpcox commented Apr 8, 2026

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 8, 2026

@copilot apply changes based on the comments in this thread

Applied both review comments in 86b59ae:

  • Updated the validation error hint in validation_schema.go to include @sha256:<digest> example
  • Updated the JSON schema container field description to mention digest pinning

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
    • Triggering command: /tmp/go-build2490239025/b514/launcher.test /tmp/go-build2490239025/b514/launcher.test -test.testlogfile=/tmp/go-build2490239025/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s go_.�� 5.0/deviceauth.g-errorsas 5.0/oauth2.go x_amd64/vet go nal/encoding/def-atomic /usr/local/bin/g-bool x_amd64/vet dock�� g_.a git x_amd64/vet go (dns block)
  • invalid-host-that-does-not-exist-12345.com
    • Triggering command: /tmp/go-build673647265/b001/config.test /tmp/go-build673647265/b001/config.test -test.paniconexit0 -test.timeout=10m0s -test.count=1 /tmp/go-build673647265/b146/vet.cfg go user.email 64/pkg/tool/linu-lang=go1.25 ame (dns block)
    • Triggering command: /tmp/go-build2490239025/b496/config.test /tmp/go-build2490239025/b496/config.test -test.testlogfile=/tmp/go-build2490239025/b496/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build2490239025/b382/vet.cfg g_.a -I x_amd64/vet --gdwarf-5 --64 -o x_amd64/vet -o 1.80.0/grpclog/i-errorsas 1.80.0/grpclog/i-ifaceassert x_amd64/vet -p github.com/githu-atomic -lang=go1.25 x_amd64/vet (dns block)
  • nonexistent.local
    • Triggering command: /tmp/go-build2490239025/b514/launcher.test /tmp/go-build2490239025/b514/launcher.test -test.testlogfile=/tmp/go-build2490239025/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s go_.�� 5.0/deviceauth.g-errorsas 5.0/oauth2.go x_amd64/vet go nal/encoding/def-atomic /usr/local/bin/g-bool x_amd64/vet dock�� g_.a git x_amd64/vet go (dns block)
  • slow.example.com
    • Triggering command: /tmp/go-build2490239025/b514/launcher.test /tmp/go-build2490239025/b514/launcher.test -test.testlogfile=/tmp/go-build2490239025/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s go_.�� 5.0/deviceauth.g-errorsas 5.0/oauth2.go x_amd64/vet go nal/encoding/def-atomic /usr/local/bin/g-bool x_amd64/vet dock�� g_.a git x_amd64/vet go (dns block)
  • this-host-does-not-exist-12345.com
    • Triggering command: /tmp/go-build2490239025/b523/mcp.test /tmp/go-build2490239025/b523/mcp.test -test.testlogfile=/tmp/go-build2490239025/b523/testlog.txt -test.paniconexit0 -test.timeout=10m0s /usr�� wnRn4isFk 8119778/b286/ x_amd64/vet go singleflight/sin/usr/bin/runc (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot finished work on behalf of lpcox April 8, 2026 02:16
@lpcox lpcox merged commit 6333a1c into main Apr 8, 2026
13 checks passed
@lpcox lpcox deleted the copilot/allow-sha256-digests branch April 8, 2026 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow SHA-256 digests in container image references

3 participants