diff --git a/dev.Dockerfile b/dev.Dockerfile index fec9a942..99cd8e2b 100644 --- a/dev.Dockerfile +++ b/dev.Dockerfile @@ -1,17 +1,18 @@ ARG ALPINE_IMAGE=alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d +ARG UV_IMAGE=astral/uv:0.12.7-alpine3.23@sha256:d0d7c7a05e4d9270b97392da2204371581b431287f2ae959e4aef715c86f9efc -FROM astral/uv:alpine AS build +FROM ${UV_IMAGE} AS build WORKDIR /root/cloudsmith-cli RUN apk add --no-cache binutils -ADD bin bin -ADD cloudsmith_cli cloudsmith_cli -ADD packaging packaging -ADD pyproject.toml pyproject.toml -ADD uv.lock uv.lock -ADD VERSION VERSION +COPY bin bin +COPY cloudsmith_cli cloudsmith_cli +COPY packaging packaging +COPY pyproject.toml pyproject.toml +COPY uv.lock uv.lock +COPY VERSION VERSION ARG CLOUDSMITH_CLI_VERSION ARG PYTHON_VERSION=3.14 diff --git a/pyproject.toml b/pyproject.toml index 061b1496..f397e862 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,16 +47,22 @@ dependencies = [ "keyring>=25.4.1", "keyrings-alt>=5.0.2", "keyrings-cryptfile>=1.3.9", + # Security floors for MCP's runtime dependency graph. Keep these explicit: + # downstream installers do not consume uv.lock and could otherwise select + # vulnerable transitive versions allowed by MCP's broader constraints. + "cryptography>=50.0.0", "mcp==1.28.1", + "pydantic-settings>=2.14.2", # The crypto extra must be declared here: the OIDC flow verifies JWT # signatures, and a bare PyJWT requirement would let the # standalone-binary build resolve without the cryptography wheels. - "PyJWT[crypto]>=2.0.0", + "PyJWT[crypto]>=2.13.0", "python-toon==0.1.2", "requests>=2.18.4", "requests_toolbelt>=1.0.0", "rich>=13.0.0", "semver>=2.7.9", + "starlette>=1.3.1", "urllib3>=2.5", "tomlkit>=0.15.0", ] diff --git a/uv.lock b/uv.lock index cbcf4000..c2a096a7 100644 --- a/uv.lock +++ b/uv.lock @@ -530,17 +530,20 @@ dependencies = [ { name = "click-didyoumean" }, { name = "click-spinner" }, { name = "cloudsmith-api" }, + { name = "cryptography" }, { name = "json5" }, { name = "keyring" }, { name = "keyrings-alt" }, { name = "keyrings-cryptfile" }, { name = "mcp" }, + { name = "pydantic-settings" }, { name = "pyjwt", extra = ["crypto"] }, { name = "python-toon" }, { name = "requests" }, { name = "requests-toolbelt" }, { name = "rich" }, { name = "semver" }, + { name = "starlette" }, { name = "tomlkit" }, { name = "urllib3" }, ] @@ -587,17 +590,20 @@ requires-dist = [ { name = "click-didyoumean", specifier = ">=0.0.3" }, { name = "click-spinner", specifier = ">=0.1.7" }, { name = "cloudsmith-api", specifier = ">=2.0.31,<3.0" }, + { name = "cryptography", specifier = ">=50.0.0" }, { name = "json5", specifier = ">=0.9.0" }, { name = "keyring", specifier = ">=25.4.1" }, { name = "keyrings-alt", specifier = ">=5.0.2" }, { name = "keyrings-cryptfile", specifier = ">=1.3.9" }, { name = "mcp", specifier = "==1.28.1" }, - { name = "pyjwt", extras = ["crypto"], specifier = ">=2.0.0" }, + { name = "pydantic-settings", specifier = ">=2.14.2" }, + { name = "pyjwt", extras = ["crypto"], specifier = ">=2.13.0" }, { name = "python-toon", specifier = "==0.1.2" }, { name = "requests", specifier = ">=2.18.4" }, { name = "requests-toolbelt", specifier = ">=1.0.0" }, { name = "rich", specifier = ">=13.0.0" }, { name = "semver", specifier = ">=2.7.9" }, + { name = "starlette", specifier = ">=1.3.1" }, { name = "tomlkit", specifier = ">=0.15.0" }, { name = "urllib3", specifier = ">=2.5" }, ]