diff --git a/Dockerfile b/Dockerfile index 35ccd97..295c819 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ # syntax=docker/dockerfile:1.4 ARG base_image + ################################################################################ # STAGE 1 — ZAP BUILDER: pull official ZAP bits (JDK & scripts bundled upstream) ################################################################################ @@ -14,45 +15,63 @@ RUN test -x /zap/zap-baseline.py # Optional add-on update RUN if [ "${ENABLE_ADDON_UPDATE}" = "true" ]; then \ - /zap/zap.sh -cmd -silent -addonupdate ; \ + /zap/zap.sh -cmd -silent -addonupdate; \ else \ - echo "Skipping ZAP add-on update" ; \ + echo "Skipping ZAP add-on update"; \ fi ################################################################################ -# STAGE 2 — FINAL IMAGE: your hardened Ubuntu base (no STIG steps needed here) +# STAGE 2 — FINAL IMAGE: your hardened Ubuntu base with Java 21 LTS ################################################################################ FROM ${base_image} + +# Use root for installation USER root -WORKDIR /zap ARG DEBIAN_FRONTEND=noninteractive +WORKDIR /zap -# Copy ZAP from builder +# Copy ZAP installation from builder stage COPY --from=zap-builder /zap /zap -# Install runtime tools, API client, then harden only under /zap +# Install Java 21 LTS and necessary tooling, then harden under /zap RUN apt-get update && \ apt-get install -y --no-install-recommends \ - curl jq python3-pip && \ + openjdk-21-jre-headless \ + curl \ + jq \ + python3-pip && \ pip3 install --no-cache-dir zaproxy && \ - # Harden: strip setuid/setgid only in /zap, ignore /proc, /sys, etc. - find /zap -xdev -perm /6000 -type f -exec chmod a-s {} + 2>/dev/null && \ - # Clean up - apt-get purge -y curl jq && \ + find /zap -xdev -perm /6000 -type f -exec chmod a-s {} + && \ + apt-get purge -y curl jq python3-pip && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man -# Create and switch to non-root user -RUN useradd -u 1000 -m -s /bin/bash zap && chown -R zap:zap /zap +# Create non-root zap user and set permissions +RUN useradd -u 1000 -m -s /bin/bash zap && \ + chown -R zap:zap /zap + +# Switch to non-root for runtime USER zap -# Environment & health-check -ENV PATH="/usr/lib/jvm/java-17-openjdk-amd64/bin:/zap:$PATH" \ +# Configure environment for ZAP +ENV JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64 \ + PATH=${JAVA_HOME}/bin:/zap:${PATH} \ ZAP_PORT=8080 \ IS_CONTAINERIZED=true +# Embed metadata via OCI labels +LABEL org.opencontainers.image.title="zap-runner" \ + org.opencontainers.image.description="Containerized OWASP ZAP baseline scanner" \ + org.opencontainers.image.version="2.16.0" \ + org.opencontainers.image.created="2025-07-11T00:00:00Z" \ + org.opencontainers.image.source="https://github.com/cloud-gov/zap-runner" \ + org.opencontainers.image.licenses="CC0-1.0" \ + org.opencontainers.image.authors="Cloud.gov Office of Cybersecurity" + +# Healthcheck for ZAP daemon HEALTHCHECK --interval=30s --timeout=5s \ CMD curl -fs http://localhost:${ZAP_PORT}/ || exit 1 +# Default entrypoint and command ENTRYPOINT ["zap-baseline.py"] -CMD ["-daemon", "-r", "/zap/wrk/report.html", "-J", "/zap/wrk/report.json"] \ No newline at end of file +CMD ["-daemon", "-r", "/zap/wrk/report.html", "-J", "/zap/wrk/report.json"] diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 7cec47c..39a511d 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -47,6 +47,7 @@ resources: uri: https://github.com/cloud-gov/((repo_name)) branch: main commit_verification_keys: ((cloud-gov-pgp-keys)) + ignore_paths: ["Dockerfile"] # - name: daily # type: time