diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aad0f7f..a32a259 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -123,6 +123,19 @@ jobs: - name: Build run: docker build -t candidate:ci ./services/api + - name: The image imports its app + # It carries no build tools (setuptools, wheel); prove the service needs none. + run: docker run --rm --entrypoint python candidate:ci -c "import app.main" + + - name: Scan the image + # Trivy, pinned by digest: HIGH or CRITICAL problems that already have a fix fail here, + # before the image can be published. + run: | + docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ + aquasec/trivy:0.75.0@sha256:af6acf9a6b85dfe389a1941505c0ce9efef52a4719635e1a962f022a3d855daa \ + image --quiet --scanners vuln --ignore-unfixed --severity HIGH,CRITICAL \ + --exit-code 1 candidate:ci + - name: Search it for anything secret run: | found=$(docker run --rm --entrypoint sh candidate:ci -c \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e1d047..39e249c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ a decision with visible consequences. ## Unreleased +## 0.5.1 + +- The image no longer carries the base image's setuptools and wheel. The service never + imports them, and their vendored copies had published advisories (wheel 0.45.1, + jaraco.context 5.3.0) that the new image scan found. CI now checks that the built image + still imports its app. + ## 0.5.0 - Honor a message from the owner that starts "remember that ..." or "don't remember ..." diff --git a/dashboard/Dockerfile b/dashboard/Dockerfile index 5efd0ef..67dab98 100644 --- a/dashboard/Dockerfile +++ b/dashboard/Dockerfile @@ -8,7 +8,10 @@ RUN npm run build FROM python:3.11-slim WORKDIR /app -RUN pip install --no-cache-dir fastapi==0.138.2 uvicorn==0.49.0 +# The base image's setuptools and wheel are build tools the service never imports; removing +# them keeps their vendored copies (and their advisories) out of the running image. +RUN pip install --no-cache-dir fastapi==0.138.2 uvicorn==0.49.0 \ + && pip uninstall --yes setuptools wheel COPY server.py ./server.py COPY --from=build /app/dist ./dist EXPOSE 8021 diff --git a/services/api/Dockerfile b/services/api/Dockerfile index ed1ab4a..5986a58 100644 --- a/services/api/Dockerfile +++ b/services/api/Dockerfile @@ -2,7 +2,10 @@ FROM python:3.11-slim WORKDIR /app ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 COPY requirements.txt . -RUN pip install --no-cache-dir -r requirements.txt +# The base image's setuptools and wheel are build tools the service never imports; removing +# them keeps their vendored copies (and their advisories) out of the running image. +RUN pip install --no-cache-dir -r requirements.txt \ + && pip uninstall --yes setuptools wheel COPY app ./app EXPOSE 8020 CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8020"] diff --git a/services/api/app/main.py b/services/api/app/main.py index c8fff92..ec5e19e 100644 --- a/services/api/app/main.py +++ b/services/api/app/main.py @@ -44,7 +44,7 @@ log = logging.getLogger("memorygate") -SERVICE_VERSION = "0.5.0" +SERVICE_VERSION = "0.5.1" app = FastAPI(title="MemoryGate", version=SERVICE_VERSION)