# Copyright 2026 Richard Andresik. SPDX-License-Identifier: Apache-2.0 # Build context: this public repository, never a parent application directory. FROM docker.io/library/node:24.21.0-trixie-slim@sha256:8ec5d7557396cfe32d21c3f9c13072355ceab22b584578ca4bb28af31120cffe LABEL org.opencontainers.image.title="IcyZip E2EE review lab" \ org.opencontainers.image.description="Offline protocol tests, synthetic mutation fuzzing and inspection tools for the public IcyZip browser encryption code." \ org.opencontainers.image.version="0.4.0" \ org.opencontainers.image.url="https://icyzip.com/open-source" \ org.opencontainers.image.source="https://icyzip.com/open-source/icyzip-e2ee.git" \ org.opencontainers.image.licenses="Apache-2.0" \ org.opencontainers.image.authors="Richard Andresik " # Both the base and the signed package repositories are immutable inputs. # Node's built-in Mozilla roots bootstrap HTTPS until Debian installs its CA file. # Debian's signed Release/package verification stays enabled throughout. # Copyright files from Debian and Node remain available in the image. RUN printf '%s\n' \ 'deb [check-valid-until=no] https://snapshot.debian.org/archive/debian/20260924T000000Z trixie main' \ 'deb [check-valid-until=no] https://snapshot.debian.org/archive/debian/20260924T000000Z trixie-updates main' \ 'deb [check-valid-until=no] https://snapshot.debian.org/archive/debian-security/20260924T000000Z trixie-security main' \ > /etc/apt/sources.list \ && rm /etc/apt/sources.list.d/debian.sources \ && node -e 'require("fs").writeFileSync("/tmp/icyzip-bootstrap-ca.pem", require("tls").rootCertificates.join("\n"))' \ && apt-get -o APT::Update::Error-Mode=any -o Acquire::https::CaInfo=/tmp/icyzip-bootstrap-ca.pem update \ && DEBIAN_FRONTEND=noninteractive apt-get -o Acquire::https::CaInfo=/tmp/icyzip-bootstrap-ca.pem install -y --no-install-recommends ca-certificates \ && rm /tmp/icyzip-bootstrap-ca.pem \ && DEBIAN_FRONTEND=noninteractive apt-get upgrade -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ ca-certificates coreutils file git jq openssl python3 ripgrep strace tini \ && apt-get clean WORKDIR /opt/icyzip-e2ee COPY [".gitignore", ".dockerignore", "Dockerfile", "CONTAINER.md", "container-lock.json", "LICENSE", "PROTOCOL.md", "PROVENANCE.json", "PROVENANCE.md", "README.md", "SECURITY.md", "TESTING.md", "THREAT-MODEL.md", "package.json", "./"] COPY ["src/e2ee.js", "src/snapshot.js", "./src/"] COPY ["test/crypto.test.mjs", "test/endpoint.mjs", "test/file-receive.test.mjs", "test/minimal.test.mjs", "test/provenance.test.mjs", "test/security-regressions.test.mjs", "test/container.test.mjs", "./test/"] COPY ["tools/snapshot.mjs", "tools/fuzz.mjs", "tools/inspect.mjs", "tools/lab.mjs", "tools/sbom.mjs", "./tools/"] # npm is a bundled tool, not an application dependency. Upgrade its complete # vendored distribution from the exact authenticated archive in the lock file. RUN node --input-type=module -e 'import fs from "node:fs"; import assert from "node:assert/strict"; import {createHash} from "node:crypto"; const lock=JSON.parse(fs.readFileSync("container-lock.json")); const response=await fetch(lock.npm.url,{redirect:"error",signal:AbortSignal.timeout(60000)}); assert.ok(response.ok); const bytes=Buffer.from(await response.arrayBuffer()); assert.ok(bytes.length<8*1024*1024); assert.equal("sha512-"+createHash("sha512").update(bytes).digest("base64"),lock.npm.integrity); fs.writeFileSync("/tmp/icyzip-npm.tgz",bytes);' \ && npm install --global --ignore-scripts --no-audit --no-fund /tmp/icyzip-npm.tgz \ && rm /tmp/icyzip-npm.tgz \ && node tools/sbom.mjs /opt/icyzip-inventory ENV ICYZIP_LAB_CONTAINER=1 \ NPM_CONFIG_CACHE=/tmp/icyzip-npm \ NPM_CONFIG_UPDATE_NOTIFIER=false USER 1000:1000 ENTRYPOINT ["/usr/bin/tini", "--"] CMD ["node", "tools/lab.mjs"]