From 07fc7df200977e96c6b0bef5b19564d81ce6ddab Mon Sep 17 00:00:00 2001
From: Said Boudjelda
Date: Sat, 7 Nov 2026 08:22:37 +0100
Subject: [PATCH] fix(infra): polish README storefront, guard macOS codesign,
and fix weekly image rescan
---
.github/workflows/security.yml | 38 +++++++++++++++++++++++++++-------
Makefile | 8 ++++---
README.md | 7 ++++---
3 files changed, 39 insertions(+), 14 deletions(-)
diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml
index 7300e15cb..5dad76b2c 100644
--- a/.github/workflows/security.yml
+++ b/.github/workflows/security.yml
@@ -68,7 +68,6 @@ jobs:
timeout-minutes: 20
permissions:
contents: read
- issues: write # notify-scheduled-failure
strategy:
fail-fast: false
matrix:
@@ -92,29 +91,52 @@ jobs:
run: |
set -euo pipefail
case "${IMAGE}" in
- kates) tag=$(awk '/repository: ghcr.io\/bmscomp\/kates$/ {getline; print $2}' "${REF}" | tr -d '"'); ref="ghcr.io/bmscomp/kates:${tag}" ;;
+ kates) tag=$(awk '/repository: ghcr.io\/bmscomp\/kates$/ {found=1; next} found && /^[[:space:]]*tag:/ {print $2; exit}' "${REF}" | tr -d '"'); ref="ghcr.io/bmscomp/kates:${tag}" ;;
connect) ref=$(grep -m1 '^image:' "${REF}" | awk '{print $2}' | tr -d '"') ;;
kates-tester) ref=$(grep -m1 'ghcr.io/bmscomp/kates-tester:' "${REF}" | sed -E 's/.*(ghcr.io\/bmscomp\/kates-tester:[^"]+).*/\1/') ;;
esac
- if [ -z "${ref}" ] || [[ "${ref}" != *:* ]]; then
- echo "::error::could not resolve the ${IMAGE} image from ${REF}"
+ tag_part="${ref##*:}"
+ if [ -z "${ref}" ] || [[ "${ref}" != *:* ]] || [ -z "${tag_part}" ] || [[ "${tag_part}" == -* ]]; then
+ echo "::error::could not resolve a valid ${IMAGE} image tag from ${REF} (got '${ref}')"
exit 1
fi
echo "ref=${ref}" | tee -a "$GITHUB_OUTPUT"
- - name: Scan (Trivy)
+ # Same policy as ci.yml and the publish-*.yml workflows: HIGH is reported
+ # in the log, CRITICAL fails the weekly rescan.
+ - name: Report HIGH and CRITICAL vulnerabilities (Trivy)
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: image
image-ref: ${{ steps.pin.outputs.ref }}
scanners: vuln
severity: CRITICAL,HIGH
+ exit-code: "0"
+ ignore-unfixed: true
+ trivyignores: .trivyignore.yaml
+
+ - name: Gate on CRITICAL vulnerabilities (Trivy)
+ uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
+ with:
+ scan-type: image
+ image-ref: ${{ steps.pin.outputs.ref }}
+ scanners: vuln
+ severity: CRITICAL
exit-code: "1"
ignore-unfixed: true
trivyignores: .trivyignore.yaml
- - name: Open an issue for a failed weekly scan
- if: failure() && github.event_name == 'schedule'
- uses: ./.github/actions/notify-scheduled-failure
+ notify-failure:
+ name: Open an issue for a failed weekly scan
+ needs: [rescan-released]
+ if: always() && needs.rescan-released.result == 'failure' && github.event_name == 'schedule'
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ permissions:
+ contents: read
+ issues: write
+ steps:
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ - uses: ./.github/actions/notify-scheduled-failure
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/Makefile b/Makefile
index c2b0f1565..cddbbd483 100644
--- a/Makefile
+++ b/Makefile
@@ -493,9 +493,11 @@ cli-install: ## Build and install CLI on this machine (CLI_INSTALL_DIR to choos
fi; \
fi
sudo cp cli/dist/kates $(CLI_INSTALL_PATH)
- sudo xattr -dr com.apple.provenance $(CLI_INSTALL_PATH) 2>/dev/null || true
- sudo xattr -dr com.apple.quarantine $(CLI_INSTALL_PATH) 2>/dev/null || true
- sudo codesign -f -s - $(CLI_INSTALL_PATH)
+ @if [ "$$(uname -s)" = "Darwin" ]; then \
+ sudo xattr -dr com.apple.provenance $(CLI_INSTALL_PATH) 2>/dev/null || true; \
+ sudo xattr -dr com.apple.quarantine $(CLI_INSTALL_PATH) 2>/dev/null || true; \
+ sudo codesign -f -s - $(CLI_INSTALL_PATH); \
+ fi
@echo "✅ Installed:"
@# Run the file just written, by absolute path. Asking `kates` would
@# report whatever PATH resolves to, which is exactly the thing this
diff --git a/README.md b/README.md
index e7042b445..d8aeabdea 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@
+
@@ -22,7 +23,7 @@ You find out how a Kafka cluster handles a broker failure on the day a broker fa
Performance tests work against any Kafka cluster the Kates API can reach; fault injection targets Strimzi-managed brokers, by default the cluster `krafter` in namespace `kafka`. Kates has three parts: the `kates` CLI (Go), the Kates API (Quarkus) that runs the tests and faults and keeps the results in PostgreSQL, and the signed Helm charts that install Kafka and everything around it.
-**[The book](https://bmscomp.github.io/kates/)** · [Why Kates](#why-kates) · [Quick start](#quick-start) · [CLI at a glance](#cli-at-a-glance) · [GitHub Action](#github-action) · [Architecture](#architecture) · [Documentation](#documentation) · [Helm charts](#helm-charts) · [Building from source](#building-from-source) · [Contributing](#contributing)
+**[Website](https://katesplatform.io/)** · **[The book](https://bmscomp.github.io/kates/)** · [Why Kates](#why-kates) · [Quick start](#quick-start) · [CLI at a glance](#cli-at-a-glance) · [GitHub Action](#github-action) · [Architecture](#architecture) · [Documentation](#documentation) · [Helm charts](#helm-charts) · [Building from source](#building-from-source) · [Contributing](#contributing)
@@ -31,7 +32,7 @@ Performance tests work against any Kafka cluster the Kates API can reach; fault
## What it does
- **Performance tests.** Eight workload types (`LOAD`, `STRESS`, `SPIKE`, `ENDURANCE`, `VOLUME`, `CAPACITY`, `ROUND_TRIP`, `INTEGRITY`); `kates test types` lists every type the Kates API accepts. The default `native` benchmark backend runs Kafka producers and consumers inside the Kates API on virtual threads; `--backend trogdor` hands the workload to a Trogdor coordinator you run yourself. Reports give throughput, latency percentiles (`P50`, `P95`, `P99`) and error rate, and export as CSV, JUnit XML, Markdown, HTML or latency heatmaps.
-- **Fault injection.** Thirteen disruption types, from broker pod kills and network partitions to CPU, memory and I/O stress, DNS errors, disk fill and node drain (`kates disruption types`). The default install runs eleven of them through LitmusChaos. Network latency and disk fill time out, because the `kates-chaos` chart ships no Litmus experiment for them (see `experiments.definitions` in its values). The direct Kubernetes chaos provider covers eight.
+- **Fault injection.** Thirteen disruption types, from broker pod kills and network partitions to CPU, memory and I/O stress, DNS errors, disk fill and node drain (`kates disruption types`), run through LitmusChaos (eleven out of the box) or directly through the Kubernetes API (eight); [Chaos in practice](docs/book/07-chaos-practice.md) covers provider support and adding custom Litmus experiments.
- **Resilience runs and disruption plans.** `kates resilience run` pairs one load test with one fault and reports the before/after change and the recovery time. `kates disruption run` executes multi-step disruption plans; `kates disruption playbook list` shows the built-in playbooks. Plans get blast-radius checks, a dry run, ISR and consumer-lag tracking, and an A–F SLA grade against absolute latency, throughput and recovery-time thresholds.
- **Security audit.** `kates security audit` grades broker configuration A–F. Related commands map the checks to CIS, SOC 2 and PCI DSS, save a baseline and report drift from it.
- **CI gates.** `kates gate --min-grade B` runs a load test and exits non-zero below the performance grade, `kates test apply -f --wait` fails when a scenario violates its SLA gates, and `kates security gate` does the same for the security grade. Finished tests can notify webhooks (`kates webhook add`).
@@ -281,7 +282,7 @@ make kates-local # JVM image kates:local (quicker to build), loade
```
- `make` on its own lists every target.
-- On Linux, `make cli-install` ends with a `codesign` error, a macOS-only step, after the binary is already installed. The binary works, but the target stops before checking whether another `kates` comes earlier on your `PATH`.
+- On macOS, `make cli-install` also strips quarantine attributes and ad-hoc signs the installed binary so Gatekeeper does not block it.
- On Apple Silicon, local `./mvnw` builds need Rosetta 2 (`softwareupdate --install-rosetta`): the gRPC code generator this Quarkus version uses ships only an x86-64 macOS binary. Docker builds are not affected.
- `(cd kates && ./mvnw quarkus:dev)` runs the backend with API-key authentication off, but it still needs a reachable PostgreSQL (`QUARKUS_DATASOURCE_JDBC_URL`) and Kafka (`KATES_KAFKA_BOOTSTRAP_SERVERS`).
- Both Dockerfiles take the repository root as build context, as in `docker build -f kates/Dockerfile.native -t kates:native-local .`.