Skip to content

Commit ccfd98b

Browse files
committed
Jepsen: Supply-chain harden the CI workflow
Pin everything the job fetches and builds so a CI run is reproducible and a re-tagged or force-pushed upstream cannot change what executes. - Pin the five container images (MinIO, mc, Toxiproxy, the Erlang broker base, the Clojure control base) by digest instead of mutable tags - Pin the upstream rabbitmq-server clone to a commit SHA and shallow-fetch it directly, rather than building the streams-tiered- storage branch tip; bump the SHA periodically to track the branch - Set persist-credentials: false on the plugin checkout so the GITHUB_TOKEN is not left in .git/config for the build, the lein dependency download and the cluster to read The workflow already SHA-pins its actions and runs with `permissions: contents: read`.
1 parent 563b67d commit ccfd98b

4 files changed

Lines changed: 29 additions & 6 deletions

File tree

.github/workflows/jepsen.yaml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,28 @@ jobs:
7070
otp-version: ${{ matrix.otp-version }}
7171
elixir-version: ${{ matrix.elixir-version }}
7272
- name: Clone rabbitmq-server
73-
run: git clone --depth 1 --branch ${{ matrix.rmq-version }} https://github.com/amazon-mq/upstream-to-rabbitmq-server.git ${{ github.workspace }}/rabbitmq-server
73+
# The server is built and run as part of the cluster, so pin it to a
74+
# commit SHA rather than the mutable streams-tiered-storage branch tip:
75+
# a CI run then builds exactly the server it was tested against, and a
76+
# force-push to the branch cannot change what executes here. Bump this
77+
# SHA periodically to track the branch (that re-introduces server-drift
78+
# coverage at a controlled point). Shallow-fetch the SHA directly so the
79+
# checkout keeps working once the branch tip has moved past the pin.
80+
env:
81+
RMQ_SERVER_SHA: 91051d3c678faa6cc68a75d6b561ceca05e12025
82+
run: |
83+
git init -q "${{ github.workspace }}/rabbitmq-server"
84+
git -C "${{ github.workspace }}/rabbitmq-server" remote add origin \
85+
https://github.com/amazon-mq/upstream-to-rabbitmq-server.git
86+
git -C "${{ github.workspace }}/rabbitmq-server" fetch -q --depth 1 origin "$RMQ_SERVER_SHA"
87+
git -C "${{ github.workspace }}/rabbitmq-server" checkout -q "$RMQ_SERVER_SHA"
7488
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
7589
with:
7690
path: rabbitmq-server/deps/rabbitmq_stream_s3
91+
# The job then runs a full server build plus a lein dependency
92+
# download and a RabbitMQ cluster; do not leave the token in .git/config
93+
# for that third-party code to read.
94+
persist-credentials: false
7795
- name: Run Jepsen
7896
working-directory: rabbitmq-server/deps/rabbitmq_stream_s3
7997
run: jepsen/ci/run-jepsen.sh

jepsen/docker/Dockerfile-control

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Jepsen control node: runs `lein run test ...` and drives the DB nodes over
22
# SSH. Needs a JDK (for the Stream Java client + jepsen), leiningen, and an
33
# SSH client.
4-
FROM clojure:temurin-21-lein
4+
# Pinned by digest for supply-chain reproducibility (clojure:temurin-21-lein).
5+
FROM clojure@sha256:f5ef76151930464b31b97d518469b802de1c82507d6205d6ecf96cf6cb6d17d2
56

67
RUN apt-get update && apt-get install -y --no-install-recommends \
78
git openssh-client sshpass iputils-ping dnsutils gnuplot graphviz \

jepsen/docker/Dockerfile-node

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
# plus the bits jepsen needs: sshd for control access and iptables/sudo for
33
# the partition nemesis. The broker itself is installed at run time by db.clj
44
# from /shared/rabbitmq.tar.xz (the generic-unix tarball).
5-
FROM erlang:27
5+
# Pinned by digest for supply-chain reproducibility (erlang:27).
6+
FROM erlang@sha256:b439336c5035e414008770118719907d08b12c23e576b34a5efc6516653de0f4
67

78
RUN apt-get update && apt-get install -y --no-install-recommends \
89
openssh-server sudo iproute2 iptables procps ca-certificates \

jepsen/docker/docker-compose.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ services:
5252
n5: {<<: *node, hostname: n5, container_name: n5}
5353

5454
minio:
55-
image: minio/minio:latest
55+
# Pinned by digest for supply-chain reproducibility (was minio/minio:latest).
56+
image: minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e
5657
environment:
5758
MINIO_ROOT_USER: jepsenjepsen
5859
MINIO_ROOT_PASSWORD: jepsenjepsenjepsen
@@ -69,7 +70,8 @@ services:
6970
jepsen:
7071

7172
toxiproxy:
72-
image: ghcr.io/shopify/toxiproxy:latest
73+
# Pinned by digest (was ghcr.io/shopify/toxiproxy:latest).
74+
image: ghcr.io/shopify/toxiproxy@sha256:9378ed52a28bc50edc1350f936f518f31fa95f0d15917d6eb40b8e376d1a214e
7375
# The toxiproxy image is FROM scratch (no shell), so the passthrough proxy
7476
# is declared in a config file loaded at startup rather than created by an
7577
# init container. -host=0.0.0.0 exposes the admin API (8474) for S3 fault
@@ -91,7 +93,8 @@ services:
9193
# comes from MC_HOST_j, and we talk path-style to minio:443 with --insecure
9294
# (the cert is for *.s3.jepsen.local, not "minio"). restart: on-failure
9395
# retries until MinIO is accepting connections, then exits 0.
94-
image: minio/mc:latest
96+
# Pinned by digest (was minio/mc:latest).
97+
image: minio/mc@sha256:a7fe349ef4bd8521fb8497f55c6042871b2ae640607cf99d9bede5e9bdf11727
9598
environment:
9699
MC_HOST_j: "https://jepsenjepsen:jepsenjepsenjepsen@minio:443"
97100
entrypoint: ["mc"]

0 commit comments

Comments
 (0)