Skip to content

fix(scanner): scan Docker-image servers in Trivy image mode (MCP-2398)#666

Merged
Dumbris merged 1 commit into
mainfrom
fix/mcp-2398-docker-image-trivy-scan
Jun 14, 2026
Merged

fix(scanner): scan Docker-image servers in Trivy image mode (MCP-2398)#666
Dumbris merged 1 commit into
mainfrom
fix/mcp-2398-docker-image-trivy-scan

Conversation

@Dumbris

@Dumbris Dumbris commented Jun 14, 2026

Copy link
Copy Markdown
Member

Problem

A server wired as a direct Docker invocation — e.g.

{ "name": "fetch", "command": "docker", "args": ["run", "-i", "--rm", "mcp/fetch"] }

is not an mcpproxy-managed container. The source resolver only looks for
mcpproxy-<name>-* containers, found none, and fell through to
source_method=tool_definitions_only. Trivy then ran fs /scan/source against
an empty temp dir → 0 results. Docker-image MCP servers got effectively
zero vulnerability scanning.

Fix

Detect the image reference from a docker/podman run command and resolve it
as a new container_image source method. Scanners that declare the
container_image input and provide an ImageCommand template (Trivy) now run
in image mode (trivy image <ref>), with {{IMAGE}} substituted at runtime.

Trivy resolves the image via the local daemon/containerd/podman and falls back
to pulling from the remote registry (network is already enabled for Trivy), so
no Docker socket mount is required — registry images like mcp/fetch work
out of the box.

Changes (all in internal/security/scanner/, backend lane)

  • source_resolver.goResolvedSource.ContainerImage + dockerImageFromCommand (docker CLI arg grammar: value-flags, --flag=value / attached forms, combined short booleans, docker container run). Wired into both Resolve (Pass 1) and ResolveFullSource (Pass 2).
  • types.go / registry_bundled.goScannerPlugin.ImageCommand; Trivy gets image --format sarif {{IMAGE}}.
  • engine.goScanRequest.ContainerImage + effectiveScannerCommand selects image-mode vs source-mode per scanner.
  • service.go — carry the image into the scan request, preserve the container_image method past the tool-definitions temp dir, and don't abort image scans even with 0 tools exported.
  • docs/cli/security-commands.md — document the new resolution step (ENG-9).

Non-image scanners (Semgrep, Cisco) are unchanged — they keep scanning the
exported tool definitions. The Web UI already renders source_method and a
container_image badge generically, so no frontend change is required.

Tests (TDD)

New image_scan_test.go:

  • TestDockerImageFromCommand — 11 cases (docker/podman, value flags, attached =, combined booleans, container run, negatives).
  • TestResolveDockerRunImageResolve returns container_image + image ref.
  • TestScannerCommandForImage — Trivy → image command w/ substitution; no image → source command; non-image scanner unchanged.

Verification

go test ./internal/security/... -race            # ok
go test ./internal/httpapi/... -race             # ok
golangci-lint run --config .github/.golangci.yml ./internal/security/scanner/...  # 0 issues
go build ./...                                    # ok

Note: go build -tags server ./... fails in internal/teams/broker (undefined CredentialStore/UpstreamCredential) — pre-existing on origin/main (PR #602 dependency), unrelated to this change and outside this lane.

Related MCP-2398

Servers wired as `docker run <image>` (e.g. `command: docker`,
`args: [run, -i, --rm, mcp/fetch]`) were not mcpproxy-managed
containers, so the source resolver found no `mcpproxy-<name>-*`
container and fell through to source_method=tool_definitions_only.
Trivy then ran `fs /scan/source` on an empty temp dir (0 results) —
Docker-image servers got effectively zero scanning.

Detect the image reference from a `docker`/`podman run` command and
resolve it as a new `container_image` source method. Scanners that
declare the `container_image` input and provide an `ImageCommand`
template (Trivy) now run in image mode (`trivy image <ref>`) with
`{{IMAGE}}` substituted at runtime. Trivy resolves the image via the
local daemon/containerd/podman and falls back to pulling from the
remote registry, so no Docker socket mount is required.

- source_resolver: ResolvedSource.ContainerImage + dockerImageFromCommand,
  wired into both Resolve (Pass 1) and ResolveFullSource (Pass 2)
- types/registry: ScannerPlugin.ImageCommand; Trivy image-mode template
- engine: ScanRequest.ContainerImage + effectiveScannerCommand selection
- service: carry the image, preserve the container_image method past the
  tool-definitions temp dir, and don't abort image scans with 0 tools

Related MCP-2398
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9043db0
Status: ✅  Deploy successful!
Preview URL: https://a3ccb216.mcpproxy-docs.pages.dev
Branch Preview URL: https://fix-mcp-2398-docker-image-tr.mcpproxy-docs.pages.dev

View logs

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 48.48485% with 34 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/security/scanner/service.go 0.00% 19 Missing ⚠️
internal/security/scanner/source_resolver.go 61.76% 12 Missing and 1 partial ⚠️
internal/security/scanner/engine.go 84.61% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions

Copy link
Copy Markdown

📦 Build Artifacts

Workflow Run: View Run
Branch: fix/mcp-2398-docker-image-trivy-scan

Available Artifacts

  • archive-darwin-amd64 (28 MB)
  • archive-darwin-arm64 (25 MB)
  • archive-linux-amd64 (16 MB)
  • archive-linux-arm64 (14 MB)
  • archive-windows-amd64 (28 MB)
  • archive-windows-arm64 (25 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (21 MB)
  • installer-dmg-darwin-arm64 (19 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 27501680978 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

@mcpproxy-gatekeeper mcpproxy-gatekeeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Approved via Claude Code review (Codex out): docker Trivy image-mode (MCP-2398). Reviewer verified fix + tests + CI green; VERDICT ACCEPT.

@Dumbris Dumbris enabled auto-merge (squash) June 14, 2026 14:56
@Dumbris Dumbris merged commit 35d2f35 into main Jun 14, 2026
38 checks passed
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.

2 participants