Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 35 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# syntax=docker/dockerfile:1.4
ARG base_image

################################################################################
# STAGE 1 — ZAP BUILDER: pull official ZAP bits (JDK & scripts bundled upstream)
################################################################################
Expand All @@ -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"]
CMD ["-daemon", "-r", "/zap/wrk/report.html", "-J", "/zap/wrk/report.json"]
1 change: 1 addition & 0 deletions ci/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down