Remediate six confirmed security issues: deployment-only config keys, bounded provider responses, short-lived registration sessions, private init file mode, FedWiki workflow authorization, and switch preview gates. - Add DeploymentOnly config key declaration; refuse runtime overrides for keys that decide where secrets are sent - Create httplimit package; bound all provider response reads at 8 MiB - Set fifteen-minute deadline on /register sessions - Write mc-config.yaml with 0600 permissions - Derive FedWiki workflow IDs from site IDs; re-authorize sites before mutating activities - Apply switch authorization gates to the proration preview
91 lines
4.7 KiB
Docker
91 lines
4.7 KiB
Docker
# Auditor image: a disposable environment holding two coding agents (opencode,
|
|
# Codex CLI) plus a deterministic security toolchain. No host credentials are
|
|
# baked in; the one secret reaching a running container is the credential of
|
|
# the harness that lane runs, mounted at runtime (see harness.sh).
|
|
#
|
|
# Everything that needs the network is fetched HERE, at build time, where the
|
|
# daemon has normal egress. At RUN time the container sits on an internal
|
|
# network whose only exit is the allowlist proxy, so the scanners must be
|
|
# fully offline: hence the baked Go vulnerability database and semgrep rules.
|
|
# 1.27.1 to match the project's go.mod directive (staticcheck needs 1.26+;
|
|
# GOTOOLCHAIN=local, so the base version is the version you get.
|
|
FROM golang:1.27.1-bookworm
|
|
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
git ripgrep ca-certificates curl unzip jq python3 python3-venv \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# opencode via the vendor install script (a platform binary, so no Node runtime).
|
|
RUN curl -fsSL https://opencode.ai/install | bash
|
|
# GOPATH is /go in the official images, so `go install` lands in /go/bin.
|
|
# Login shells reset PATH from /etc/profile, so the tools are also symlinked
|
|
# into /usr/local/bin below — never rely on this ENV alone.
|
|
ENV PATH="/root/.opencode/bin:/go/bin:${PATH}"
|
|
|
|
# Go security tooling.
|
|
# gosec — Go-specific insecure patterns (G1xx-G7xx), fully offline
|
|
# govulncheck — known CVEs filtered by symbol-level reachability
|
|
# staticcheck — correctness bugs (nil derefs, races) behind security bugs
|
|
# gitleaks — committed secrets
|
|
RUN go install github.com/securego/gosec/v2/cmd/gosec@latest \
|
|
&& go install golang.org/x/vuln/cmd/govulncheck@latest \
|
|
&& go install honnef.co/go/tools/cmd/staticcheck@latest \
|
|
&& go install github.com/zricethezav/gitleaks/v8@latest \
|
|
&& ln -s /go/bin/gosec /go/bin/govulncheck /go/bin/staticcheck /go/bin/gitleaks \
|
|
/usr/local/bin/
|
|
|
|
# semgrep plus its rule corpus, cloned for offline use (--config auto would
|
|
# hit the registry and report the project URL upstream; we never use it).
|
|
RUN python3 -m venv /opt/semgrep \
|
|
&& /opt/semgrep/bin/pip install --no-cache-dir --quiet semgrep \
|
|
&& ln -s /opt/semgrep/bin/semgrep /usr/local/bin/semgrep \
|
|
&& git clone --depth 1 https://github.com/semgrep/semgrep-rules /opt/semgrep-rules
|
|
|
|
# Offline Go vulnerability database: any file:// directory implements the API,
|
|
# so govulncheck runs with no network at all.
|
|
RUN curl -sL https://vuln.go.dev/vulndb.zip -o /tmp/vulndb.zip \
|
|
&& mkdir -p /opt/vulndb \
|
|
&& unzip -q /tmp/vulndb.zip -d /opt/vulndb \
|
|
&& rm /tmp/vulndb.zip
|
|
|
|
# Bake the project's module cache so govulncheck and staticcheck can load
|
|
# packages with no network at run time. prepare.sh exports .code/ before it
|
|
# builds, so these files are present in the build context.
|
|
COPY .code/go.mod .code/go.sum /build/
|
|
RUN cd /build && go mod download
|
|
|
|
# Codex CLI, pinned to the version signed in on the host (`codex --version`):
|
|
# the server hands each client version its own model list, so the slugs and
|
|
# reasoning levels the host shows are the ones this build gets. Two static
|
|
# musl binaries are taken from the npm platform package: codex itself and the
|
|
# code-mode host it spawns beside itself to run the model's commands (without
|
|
# it every tool call fails closed). The package's voice, zsh and bubblewrap
|
|
# resources serve the interactive sandbox, not a container. Last layer on
|
|
# purpose: a version bump rebuilds nothing above it.
|
|
ARG CODEX_VERSION=0.155.1
|
|
ARG TARGETARCH
|
|
RUN arch="${TARGETARCH:-$(dpkg --print-architecture)}" \
|
|
&& case "$arch" in \
|
|
amd64) npm_arch=x64; triple=x86_64-unknown-linux-musl ;; \
|
|
arm64) npm_arch=arm64; triple=aarch64-unknown-linux-musl ;; \
|
|
*) echo "no Codex CLI build for $arch" >&2; exit 1 ;; \
|
|
esac \
|
|
&& curl -fsSL "https://registry.npmjs.org/@openai/codex/-/codex-${CODEX_VERSION}-linux-${npm_arch}.tgz" \
|
|
| tar -xz -C /usr/local/bin --strip-components=4 \
|
|
"package/vendor/$triple/bin/codex" "package/vendor/$triple/bin/codex-code-mode-host" \
|
|
&& codex --version
|
|
|
|
# A Node runtime, for the Codex Security plugin's MCP server (a Node bundle
|
|
# that a codex lane ships in its CODEX_HOME; see harness.sh). Only the
|
|
# binary; the launcher finds it on PATH.
|
|
ARG NODE_VERSION=24.10.0
|
|
RUN arch="${TARGETARCH:-$(dpkg --print-architecture)}" \
|
|
&& case "$arch" in amd64) node_arch=x64 ;; arm64) node_arch=arm64 ;; esac \
|
|
&& curl -fsSL "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.gz" \
|
|
| tar -xz -C /usr/local/bin --strip-components=2 "node-v${NODE_VERSION}-linux-${node_arch}/bin/node" \
|
|
&& node --version
|
|
|
|
ENV SEMGREP_SEND_METRICS=off
|
|
WORKDIR /src
|
|
CMD ["opencode", "--version"]
|