Build the -mcp image from a production-only dependency install instead of copying the dev-inclusive deps stage tree.
The mcp stage copies node_modules from deps (npm ci, devDependencies included) because its entrypoint is tsx, a devDependency. That ships the entire lint/test toolchain in a published image, including the unfixable dev-only advisory chain eslint-config-next -> @next/eslint-plugin-next -> fast-glob -> micromatch -> braces (GHSA-vfj7-8cjw-p6xm, documented in SECURITY-ACCEPTED-RISKS.md as accepted dev-only risk, #1166). It is inert there (the MCP server never invokes micromatch), but it enlarges the attack surface and every future CVE report against this image.
Expected approach: give the mcp stage its own npm ci --omit=dev install plus tsx (e.g. a tsx-only install layer or promoting tsx to a production dependency), and verify the MCP handshake still passes.
Expected files to touch: Dockerfile (the deps/mcp stages), .github/workflows/image.yaml (the docker-mcp job's Validate MCP handshake step already exercises the image).
Context: found while reviewing #1172; see also SECURITY-ACCEPTED-RISKS.md "Dev-Only Advisories".
Build the
-mcpimage from a production-only dependency install instead of copying the dev-inclusivedepsstage tree.The
mcpstage copiesnode_modulesfromdeps(npm ci, devDependencies included) because its entrypoint istsx, a devDependency. That ships the entire lint/test toolchain in a published image, including the unfixable dev-only advisory chaineslint-config-next -> @next/eslint-plugin-next -> fast-glob -> micromatch -> braces(GHSA-vfj7-8cjw-p6xm, documented inSECURITY-ACCEPTED-RISKS.mdas accepted dev-only risk, #1166). It is inert there (the MCP server never invokes micromatch), but it enlarges the attack surface and every future CVE report against this image.Expected approach: give the
mcpstage its ownnpm ci --omit=devinstall plustsx(e.g. atsx-only install layer or promotingtsxto a production dependency), and verify the MCP handshake still passes.Expected files to touch:
Dockerfile(thedeps/mcpstages),.github/workflows/image.yaml(thedocker-mcpjob's Validate MCP handshake step already exercises the image).Context: found while reviewing #1172; see also
SECURITY-ACCEPTED-RISKS.md"Dev-Only Advisories".