diff --git a/.mise/config.toml b/.mise/config.toml index 96959da3..48dc2edd 100644 --- a/.mise/config.toml +++ b/.mise/config.toml @@ -126,17 +126,17 @@ ripgrep = "latest" "github:vladkens/macmon" = { version = "0.7.2", os = ["macos"] } # NVIDIA GPU Prometheus exporter (nvidia-smi) for the o2-nvidia task; Linux-only, so os-scoped. # Windows GPU coverage is windows_exporter's gpu collector; Apple Silicon is macmon. -"github:utkuozdemir/nvidia_gpu_exporter" = { version = "1.10.0", os = ["linux"] } +"github:utkuozdemir/nvidia_gpu_exporter" = { version = "1.17.0", os = ["linux"] } # Windows host + GPU Prometheus exporter for the o2-winmetrics task; Windows-only, so os-scoped. "github:prometheus-community/windows_exporter" = { version = "0.31.7", os = ["windows"] } # OpenTelemetry Collector (contrib distro) binary for the native, non-Docker o2-winmetrics-native / o2-winperf tasks. # The releases repo ships several distros in one tag; matching=contrib selects the contrib archive -- the only one # carrying the prometheus/hostmetrics/windowsperfcounters receivers + basicauth extension those configs use. -"github:open-telemetry/opentelemetry-collector-releases[matching=contrib]" = { version = "0.163.1" } +"github:open-telemetry/opentelemetry-collector-releases[matching=contrib]" = { version = "0.164.0" } # NATS server with JetStream, the broker several hub instances share as their backplane. # A hub routes through it when `WS_BACKPLANE` names it, and the horizontal-scaling tests start one of their own. # Upstream ships prebuilt archives for all five platforms. -"github:nats-io/nats-server" = { version = "2.15.1" } +"github:nats-io/nats-server" = { version = "2.15.2" } # uutils findutils on aarch64-linux, built from source rather than taken from the github: entry further down. # Its 0.8.0 release had no asset for that platform, so it builds via cargo: on the same pin as the github: entry, # so every platform runs the same version. @@ -224,7 +224,7 @@ protoc = "latest" # mise installs python under a per-tool dir named after the request and only symlinks the `3.x` minor alias # -- and that symlink isn't created on the Windows runner, so the py3_* interpreter paths must resolve to the # exact `3.x.y` dir. Bump in lockstep with py3_unix/py3_win/pylib. -python = "3.13.16" +python = "3.13.18" rclone = "latest" typos = "latest" uv = "0.13.3" @@ -647,7 +647,7 @@ et_cli = "{{ vars.config_root_fwd }}/{{ vars.a_et_cli_target_dir }}/{{ vars.a_et macos_min_sdk = "26.0" # mise-managed CPython's bin dir (Linux/macOS), named to sort ahead of py3_unix, which builds on it. # The key order is the formatter's, and a var can only reference one defined above it. -py3_bin_unix = "{{ vars.a_home }}/.local/share/mise/installs/python/3.13.16/bin" +py3_bin_unix = "{{ vars.a_home }}/.local/share/mise/installs/python/3.13.18/bin" # mise-managed CPython (Linux/macOS); the PYO3_PYTHON default below. # Windows overrides PYO3_PYTHON with its own py3_win in config.windows.toml. The version # segment must equal the `python` [tools] pin (conftest enforces both). @@ -658,7 +658,7 @@ rpath_flag = "-C link-arg=-Wl,-rpath,{{ vars.conda_openssl }}/lib" # This lets the et-ws-pyo3-runner binary find libpython at runtime (libpython3.13.so on Linux, # libpython3.13.dylib on macOS via its @rpath install name). Points at the exact `3.x.y` install dir (the # `python` pin), since the minor-version alias dir isn't created everywhere. -pylib_flag = "-C link-arg=-Wl,-rpath,{{ vars.a_home }}/.local/share/mise/installs/python/3.13.16/lib" +pylib_flag = "-C link-arg=-Wl,-rpath,{{ vars.a_home }}/.local/share/mise/installs/python/3.13.18/lib" wasm_rustflags = "-C target-cpu=mvp -C target-feature=+mutable-globals,+sign-ext,+nontrapping-fptoint,+reference-types" # Instrumentation flags (leaf var) shared by the wasm coverage builds. # The nightly -Z flag adds branch regions to the covmap so the lcov exports carry BRDA records. `a_` prefix so @@ -988,6 +988,7 @@ depends = [ "taplo-check", "taplo-fmt-check", "trivy-check", + "trivy-tools-check", "typos-check", "verification-check", "zizmor-check", @@ -1407,7 +1408,7 @@ description = "Run conftest OPA/Rego policies over the TOML config + lock files" # TOML rule namespaces are listed explicitly, so the per-file `gha` (YAML) namespace is never evaluated against this # combined TOML input. run = """ -ns_list="cross cargo mise mise_lock pyproject checksums advisories" +ns_list="cross cargo mise mise_lock pyproject checksums" named=".cargo/config.toml Cargo.lock config/cargo-features.toml config/upstream-cache/data.toml config/deny.toml" named="$named config/pyrefly.toml" # Both lists rely on word-splitting when they expand. @@ -1417,6 +1418,11 @@ ns=$(for n in $ns_list; do echo -n " --namespace $n"; done) # shellcheck disable=SC2086 git ls-files '*Cargo.toml' '.mise/config*.toml' '.mise/mise*.lock' '*pyproject.toml' $named | xargs conftest test --combine --parser toml $ns -p config/conftest/policy +# The advisory dates span TOML and YAML files, so that pass lets conftest pick each file's parser. +dated="config/deny.toml config/trivyignore-tools.yaml config/trivyignore.yaml" +# $dated is a space-separated path list. +# shellcheck disable=SC2086 +conftest test --combine --namespace advisories -p config/conftest/policy $dated # The trailing-backslash ban holds for every TOML file, not only the ones the namespaces above are written for. {{ vars.toml_files }} | xargs -0 conftest test --combine --parser toml --namespace no_trailing_backslash -p config/conftest/policy @@ -2551,6 +2557,51 @@ trivy config --quiet --exit-code 1 --ignorefile config/trivyignore.yaml "$@" . """ shell = "{{ vars.task_shell }}" +# Vulnerability scan of the tools mise installs for this repository, which no lockfile scan here can see. +# It reads the Go modules, crates, npm and Python packages compiled into or bundled with each prebuilt binary. Those +# tools are also the bulk of what the root Dockerfiles put in their images, so scanning the installs directly covers +# that content without building an image. +# +# One scan of the whole installs directory rather than one per tool, so each finding is reported at a path that +# starts with the tool's install directory, which is what lets config/trivyignore.yaml scope an accepted finding +# to the one tool it was reviewed for. Every install the current config does not select is skipped: older +# versions left behind by a bump, the version-alias symlinks, tools from a `MISE_ENV` that is not loaded, and the +# operator's own global tools. So the scan sees exactly the tool set `mise install` produced for this checkout, +# and loading more envs (`MISE_ENV`, as `install-all` does) widens it to their tools. +# +# Only HIGH and CRITICAL fail it, and only the vulnerability scanner runs: the secret scanner reports the test +# keys every toolchain ships in its own test suites, none of which is a credential of ours. Known findings are +# accepted in config/trivyignore-tools.yaml, apart from `trivy-check`'s ignore file, so a finding accepted for a +# Dockerfile can never hide one in a tool or the reverse, and anything not listed there fails. +# +# Part of `check`, so it runs on every OS lane against that lane's own installs. A new advisory against an installed +# tool therefore fails the next build anywhere, which is the point: it is either fixed by a bump or accepted in the +# ignore file, not left to be noticed later. +[tasks.trivy-tools-check] +description = "Fail on HIGH or CRITICAL vulnerabilities inside the mise-installed tools" +run = """ +ignorefile="$PWD/config/trivyignore-tools.yaml" +# The root is mise's config_root rather than `$PWD`, which bash spells `/c/...` on Windows. +keep=$(mise ls --current --installed --json | yq -p json -o tsv '.[] | .[] | [.install_path, .source.path]' | + repo_root='{{ config_root }}' goawk -f .mise/trivy-tools-check.awk) +if [ -z "$keep" ]; then + echo "trivy-tools-check: mise reports no installed tool from this repository's config" >&2 + exit 1 +fi +first=$(echo "$keep" | coreutils head -n 1) +tool_dir=$(coreutils dirname "$first") +installs=$(coreutils dirname "$tool_dir") +set -- --quiet --exit-code 1 --scanners vuln --severity HIGH,CRITICAL --ignorefile "$ignorefile" +cd "$installs" +for dir in */*; do + if ! echo "$keep" | rg -qxF "$installs/$dir"; then + set -- "$@" --skip-dirs "$dir" + fi +done +trivy rootfs "$@" . +""" +shell = "{{ vars.task_shell }}" + [tasks.repo-check] description = "Repository-wide checks that need to read git itself (commit hashes, ...)" run = "cargo run -q -p et-int-repo-check" diff --git a/.mise/config.windows.toml b/.mise/config.windows.toml index 0e2d0cd3..5541b6da 100644 --- a/.mise/config.windows.toml +++ b/.mise/config.windows.toml @@ -157,9 +157,9 @@ mise_installs = '''{% if env?.MISE_INSTALLS_DIR -%} winsh = '{{ vars.mise_installs }}\http-busybox\1.37.0\ash.exe' # mise-managed CPython, pinned to the exact `3.x.y` dir (the python [tools] pin). # This is needed since mise's minor-version alias symlink isn't created on the Windows runner. -py3_win = '{{ vars.mise_installs }}\python\3.13.16\python.exe' +py3_win = '{{ vars.mise_installs }}\python\3.13.18\python.exe' # Forward-slashed py3_win for bash task bodies (backslash-form paths mangle in busybox ash). -py3_win_fwd = "{{ vars.a_mise_installs_fwd }}/python/3.13.16/python.exe" +py3_win_fwd = "{{ vars.a_mise_installs_fwd }}/python/3.13.18/python.exe" # Windows install root for the github:microsoft/onnxruntime tool. # ORT_LIB_LOCATION in config.toml [env] picks this on Windows. Version segment must match the # [tools] pin (conftest's version_drift enforces this). diff --git a/.mise/mise.lock b/.mise/mise.lock index e5e4c783..1d992551 100644 --- a/.mise/mise.lock +++ b/.mise/mise.lock @@ -1583,34 +1583,39 @@ url = "https://github.com/microsoft/onnxruntime/releases/download/v1.22.0/onnxru url_api = "https://api.github.com/repos/microsoft/onnxruntime/releases/assets/253300435" [[tools."github:nats-io/nats-server"]] -version = "2.15.1" +version = "2.15.2" backend = "github:nats-io/nats-server" -specifiers = ["2.15.1"] +specifiers = ["2.15.2"] [tools."github:nats-io/nats-server"."platforms.linux-arm64"] -checksum = "sha256:e2fbab4cad7d3c76e3052eb959570393c9d73ba756b70bf8e9eea61e9ae6d49c" -url = "https://github.com/nats-io/nats-server/releases/download/v2.15.1/nats-server-v2.15.1-linux-arm64.tar.gz" -url_api = "https://api.github.com/repos/nats-io/nats-server/releases/assets/624386630" +checksum = "sha256:bc2c788dcbf2849af749564e06a0d48c19bced851f2d68a2e21c54d078949b28" +checksum_source = "mise-versions" +url = "https://github.com/nats-io/nats-server/releases/download/v2.15.2/nats-server-v2.15.2-linux-arm64.tar.gz" +url_api = "https://api.github.com/repos/nats-io/nats-server/releases/assets/678804508" [tools."github:nats-io/nats-server"."platforms.linux-x64"] -checksum = "sha256:bf5edc7b1ce98e885c368cb43a886eb148dc5d0551d99f3cf6141fb5e1954c70" -url = "https://github.com/nats-io/nats-server/releases/download/v2.15.1/nats-server-v2.15.1-linux-amd64.tar.gz" -url_api = "https://api.github.com/repos/nats-io/nats-server/releases/assets/624386524" +checksum = "sha256:67cb8e10bc6f0c4b47f75a728529a20953dbae2a4f9a4a52ae8517d65ae303ff" +checksum_source = "mise-versions" +url = "https://github.com/nats-io/nats-server/releases/download/v2.15.2/nats-server-v2.15.2-linux-amd64.tar.gz" +url_api = "https://api.github.com/repos/nats-io/nats-server/releases/assets/678804536" [tools."github:nats-io/nats-server"."platforms.macos-arm64"] -checksum = "sha256:ed0fe39222ec2e317c4d0e1a9cdc16c63ec523d94f9355d24a902a4db2655ffd" -url = "https://github.com/nats-io/nats-server/releases/download/v2.15.1/nats-server-v2.15.1-darwin-arm64.tar.gz" -url_api = "https://api.github.com/repos/nats-io/nats-server/releases/assets/624386583" +checksum = "sha256:cbd2219d01502c38733485ac684269da585ee479fa3b1377264beecdefdf9e9d" +checksum_source = "mise-versions" +url = "https://github.com/nats-io/nats-server/releases/download/v2.15.2/nats-server-v2.15.2-darwin-arm64.tar.gz" +url_api = "https://api.github.com/repos/nats-io/nats-server/releases/assets/678804503" [tools."github:nats-io/nats-server"."platforms.macos-x64"] -checksum = "sha256:3cba5976a4fbd022669d3401cab4147faeb2b4c079712c882edb9ae4e52feb06" -url = "https://github.com/nats-io/nats-server/releases/download/v2.15.1/nats-server-v2.15.1-darwin-amd64.tar.gz" -url_api = "https://api.github.com/repos/nats-io/nats-server/releases/assets/624386590" +checksum = "sha256:9c45b23c19498692e81cd39c75e8382f0e6ff59c0d5b9470e32fe6640afa4446" +checksum_source = "mise-versions" +url = "https://github.com/nats-io/nats-server/releases/download/v2.15.2/nats-server-v2.15.2-darwin-amd64.tar.gz" +url_api = "https://api.github.com/repos/nats-io/nats-server/releases/assets/678804420" [tools."github:nats-io/nats-server"."platforms.windows-x64"] -checksum = "sha256:4f7edfa376750b2720463bd22766ed469a5f13f378a643097866fcd953cbf7e3" -url = "https://github.com/nats-io/nats-server/releases/download/v2.15.1/nats-server-v2.15.1-windows-amd64.zip" -url_api = "https://api.github.com/repos/nats-io/nats-server/releases/assets/624386633" +checksum = "sha256:f6398d5d11093778f870db70242cb50d20a58134c937c805ba8d114e7e398766" +checksum_source = "mise-versions" +url = "https://github.com/nats-io/nats-server/releases/download/v2.15.2/nats-server-v2.15.2-windows-amd64.zip" +url_api = "https://api.github.com/repos/nats-io/nats-server/releases/assets/678804534" [[tools."github:nextest-rs/nextest"]] version = "0.9.151" @@ -1686,34 +1691,39 @@ url = "https://github.com/noemaforge/vimanam/releases/download/v2.1.0/vimanam-x8 url_api = "https://api.github.com/repos/noemaforge/vimanam/releases/assets/707281192" [[tools."github:open-telemetry/opentelemetry-collector-releases"]] -version = "0.163.1" +version = "0.164.0" backend = "github:open-telemetry/opentelemetry-collector-releases" -specifiers = ["0.163.1"] +specifiers = ["0.164.0"] [tools."github:open-telemetry/opentelemetry-collector-releases"."platforms.linux-arm64"] -checksum = "sha256:9d8da7723adb5ab005bcab0caff7f5538a8219128492033ea52f26635def3809" -url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.163.1/otelcol_0.163.1_linux_arm64.tar.gz" -url_api = "https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/assets/648510005" +checksum = "sha256:5214414828cc6b72d8738c947839e3b9652693222a23006d529bfea96b03e639" +checksum_source = "mise-versions" +url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.164.0/otelcol_0.164.0_linux_arm64.tar.gz" +url_api = "https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/assets/679872589" [tools."github:open-telemetry/opentelemetry-collector-releases"."platforms.linux-x64"] -checksum = "sha256:13e8983077dbfcd2fda38e842262b6bf7539b9310f48d981239989f78264445c" -url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.163.1/otelcol_0.163.1_linux_amd64.tar.gz" -url_api = "https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/assets/648509779" +checksum = "sha256:5db7cf88c2e73a7fdce02b5fa967fcd5dc73bab00b871d947481918dc5093861" +checksum_source = "mise-versions" +url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.164.0/otelcol_0.164.0_linux_amd64.tar.gz" +url_api = "https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/assets/679872516" [tools."github:open-telemetry/opentelemetry-collector-releases"."platforms.macos-arm64"] -checksum = "sha256:664047e6ffd98ffaaf90d282bb481ffad46b1e8456f0b2f65e42d627d665d8d3" -url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.163.1/otelcol_0.163.1_darwin_arm64.tar.gz" -url_api = "https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/assets/648509463" +checksum = "sha256:8d8acf4ffce7fe1af35932d573d877d6a5ef395c29a18fda760711b800757e7d" +checksum_source = "mise-versions" +url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.164.0/otelcol_0.164.0_darwin_arm64.tar.gz" +url_api = "https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/assets/679872436" [tools."github:open-telemetry/opentelemetry-collector-releases"."platforms.macos-x64"] -checksum = "sha256:320719cc08d21ca3ab1a3440686f3d825c4c45ff533ca9ef62135baeb5cf01c3" -url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.163.1/otelcol_0.163.1_darwin_amd64.tar.gz" -url_api = "https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/assets/648509436" +checksum = "sha256:e757fdf5fbb76ebcdb266bdf88337247d6fc85c0955ce00b98ba7df46f556d2d" +checksum_source = "mise-versions" +url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.164.0/otelcol_0.164.0_darwin_amd64.tar.gz" +url_api = "https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/assets/679872430" [tools."github:open-telemetry/opentelemetry-collector-releases"."platforms.windows-x64"] -checksum = "sha256:ff0a49d2a361bd9b41082105773b202a83142a37ea1b028695ac0a4a0c4edac4" -url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.163.1/otelcol_0.163.1_windows_amd64.tar.gz" -url_api = "https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/assets/648419383" +checksum = "sha256:ff9a3d79687cca7863bfbea1198542ca0c1800841289541913211d75ab6fea38" +checksum_source = "mise-versions" +url = "https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.164.0/otelcol_0.164.0_windows_amd64.tar.gz" +url_api = "https://api.github.com/repos/open-telemetry/opentelemetry-collector-releases/releases/assets/679871324" [[tools."github:owenlamont/ryl"]] version = "0.29.0" @@ -1866,19 +1876,21 @@ url_api = "https://api.github.com/repos/taiki-e/cargo-hack/releases/assets/69852 provenance = "github-attestations" [[tools."github:utkuozdemir/nvidia_gpu_exporter"]] -version = "1.10.0" +version = "1.17.0" backend = "github:utkuozdemir/nvidia_gpu_exporter" -specifiers = ["1.10.0"] +specifiers = ["1.17.0"] [tools."github:utkuozdemir/nvidia_gpu_exporter"."platforms.linux-arm64"] -checksum = "sha256:9c8f049eb75d2ec8e046003a2e605d4f6c49035ab45810e31cee6cbf7a68cfb0" -url = "https://github.com/utkuozdemir/nvidia_gpu_exporter/releases/download/v1.10.0/nvidia_gpu_exporter_1.10.0_linux_arm64.tar.gz" -url_api = "https://api.github.com/repos/utkuozdemir/nvidia_gpu_exporter/releases/assets/467484914" +checksum = "sha256:7bfb3a5cca5a3e5873839c5a45d574dc45030881846b04ddd76cebce69714fce" +url = "https://github.com/utkuozdemir/nvidia_gpu_exporter/releases/download/v1.17.0/nvidia_gpu_exporter_1.17.0_linux_arm64.tar.gz" +url_api = "https://api.github.com/repos/utkuozdemir/nvidia_gpu_exporter/releases/assets/699892210" +provenance = "github-attestations" [tools."github:utkuozdemir/nvidia_gpu_exporter"."platforms.linux-x64"] -checksum = "sha256:bb7c603d923beb57481652ac9848d1aa89da674b56ed99f99b6631418fbd9e56" -url = "https://github.com/utkuozdemir/nvidia_gpu_exporter/releases/download/v1.10.0/nvidia_gpu_exporter_1.10.0_linux_x86_64.tar.gz" -url_api = "https://api.github.com/repos/utkuozdemir/nvidia_gpu_exporter/releases/assets/467484915" +checksum = "sha256:c0d0843e3c3659d6613373353f6552c041226f3627eab0e4892e45dfb03a6e02" +url = "https://github.com/utkuozdemir/nvidia_gpu_exporter/releases/download/v1.17.0/nvidia_gpu_exporter_1.17.0_linux_x86_64.tar.gz" +url_api = "https://api.github.com/repos/utkuozdemir/nvidia_gpu_exporter/releases/assets/699892169" +provenance = "github-attestations" [[tools."github:uutils/coreutils"]] version = "0.6.0" @@ -2406,33 +2418,33 @@ url = "https://github.com/protocolbuffers/protobuf/releases/download/v36.2/proto url_api = "https://api.github.com/repos/protocolbuffers/protobuf/releases/assets/570742465" [[tools.python]] -version = "3.13.16" +version = "3.13.18" backend = "core:python" -specifiers = ["3.13.16"] +specifiers = ["3.13.18"] [tools.python."platforms.linux-arm64"] -checksum = "sha256:83621f7b2b1e5da63cae0b4c67612974547b14262676608e830e246cb832d07d" -url = "https://github.com/astral-sh/python-build-standalone/releases/download/20261020/cpython-3.13.16+20261020-aarch64-unknown-linux-gnu-install_only_stripped.tar.gz" +checksum = "sha256:55c00325f7c1fddf325dfc621aabdfbbac4dc54adda224af88ec411dc12db239" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20261110/cpython-3.13.18+20261110-aarch64-unknown-linux-gnu-install_only_stripped.tar.gz" provenance = "github-attestations" [tools.python."platforms.linux-x64"] -checksum = "sha256:f326b7a386bf22def82e55dc3b95d2bef8b7c938b4c98ec32dd65433e7720b50" -url = "https://github.com/astral-sh/python-build-standalone/releases/download/20261020/cpython-3.13.16+20261020-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz" +checksum = "sha256:f2d2199eb25880e07863b391cf7124e7ffa1338b0d65600dfcec117c4223a7fb" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20261110/cpython-3.13.18+20261110-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz" provenance = "github-attestations" [tools.python."platforms.macos-arm64"] -checksum = "sha256:88b362e2e9754787c07f2847b717b127e60f77976e20847a0489f3043c925f2c" -url = "https://github.com/astral-sh/python-build-standalone/releases/download/20261020/cpython-3.13.16+20261020-aarch64-apple-darwin-install_only_stripped.tar.gz" +checksum = "sha256:7a2384641584ab9984221fcb0fc9265df465922af71be71410529e2a9c3f0540" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20261110/cpython-3.13.18+20261110-aarch64-apple-darwin-install_only_stripped.tar.gz" provenance = "github-attestations" [tools.python."platforms.macos-x64"] -checksum = "sha256:730c2a96c2cdd05c5e00192ea6804c45c28fd6944abb4b55aeaa02b833fc79ec" -url = "https://github.com/astral-sh/python-build-standalone/releases/download/20261020/cpython-3.13.16+20261020-x86_64-apple-darwin-install_only_stripped.tar.gz" +checksum = "sha256:d27d59a722db9f69926eb6d9564071247221f45a04da920ea7f3001c97e32f9b" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20261110/cpython-3.13.18+20261110-x86_64-apple-darwin-install_only_stripped.tar.gz" provenance = "github-attestations" [tools.python."platforms.windows-x64"] -checksum = "sha256:cab7dfd540382d1687fba3efb70dd176366cf25687b0d52e5b4e72499b514f8c" -url = "https://github.com/astral-sh/python-build-standalone/releases/download/20261020/cpython-3.13.16+20261020-x86_64-pc-windows-msvc-install_only_stripped.tar.gz" +checksum = "sha256:2e0fed09d48989f64c9305da9ff2d37a41c0d13ab2aa6283405b2b620dfbf805" +url = "https://github.com/astral-sh/python-build-standalone/releases/download/20261110/cpython-3.13.18+20261110-x86_64-pc-windows-msvc-install_only_stripped.tar.gz" provenance = "github-attestations" [[tools.rclone]] diff --git a/.mise/trivy-tools-check.awk b/.mise/trivy-tools-check.awk new file mode 100644 index 00000000..3fd7ec22 --- /dev/null +++ b/.mise/trivy-tools-check.awk @@ -0,0 +1,18 @@ +# Print the install path of each mise tool whose config lives under this repository, for trivy-tools-check. +# Input is `install_pathsource.path` per tool; ENVIRON["repo_root"] is mise's config_root. Every path is turned +# to forward slashes before the comparison, since on Windows mise reports `C:\...` while the bash globs that consume +# this output produce `C:/...`. The root comes from the environment rather than `-v`, which would read the +# backslashes in a Windows path as escape sequences. +BEGIN { + FS = "\t" + root = ENVIRON["repo_root"] "/" + gsub(/\\/, "/", root) +} + +{ + gsub(/\\/, "/") +} + +index($2, root) == 1 { + print $1 +} diff --git a/CHECKS.md b/CHECKS.md index bfeb797c..2f78583b 100644 --- a/CHECKS.md +++ b/CHECKS.md @@ -1,11 +1,11 @@ # Checks -- **Generated:** 2026-11-13 -- **Checks:** 86 +- **Generated:** 2026-11-14 +- **Checks:** 87 - **Tools:** 49 - **Shell-script checks:** 11 - **Checks with a repair pass:** 22 -- **Rules:** 397 custom local rules, or non-default strict linter settings +- **Rules:** 401 custom local rules, or non-default strict linter settings - **Meta rules:** 22 of those rules are rules about rules Every check is listed across every `MISE_ENV`, filed under the tool it runs. Each entry names the env whose config @@ -601,7 +601,7 @@ Rules, from `Cargo.toml`: policies (conftest verify). Config: `config/conftest/policy`. - `conftest-check-toml` (`default` env; run by `conftest-check`) -- Run conftest OPA/Rego policies over the TOML config + lock files. Config: `config/cargo-features.toml`, `config/conftest/policy`, `config/deny.toml`, - `config/pyrefly.toml`, `config/upstream-cache/data.toml`. + `config/pyrefly.toml`, `config/trivyignore-tools.yaml`, `config/trivyignore.yaml`, `config/upstream-cache/data.toml`. - `conftest-check-yaml` (`default` env; run by `conftest-check`) -- Run conftest OPA/Rego policies over the GitHub Actions YAML, and the backslash ban over all YAML. Config: `config/conftest/policy`. @@ -611,6 +611,10 @@ Rules, from `config/conftest/policy`: - Every advisory ignore must carry a `reason = "expires YYYY-MM-DD"` review date. - Nanoseconds in a day, added to the parsed midnight so an entry survives the whole of its review date. - Every advisory ignore expires on one date, the next milestone review, which the operator sets. + - Every entry in the scanner's ignore files must carry an `expired_at` review date. + - Every entry in the scanner's ignore files expires on the date the advisory ignores in config/deny.toml carry. + - An advisory published before 2026 may only be accepted if old_advisories names it. + - Every id in old_advisories must still be accepted by some ignore list, so the allowlist cannot outlive its entries. - `ast_grep_rules` (meta) (`config/conftest/policy/ast_grep_rules/ast_grep_rules.rego`): - A rule whose severity is anything but `error`, or is missing, is not a gate. - `bench_results` (`config/conftest/policy/bench_results/bench_results.rego`): @@ -1295,6 +1299,8 @@ Rules, from `config/taplo`: - `trivy-check` (`default` env; run by `check:rust`) -- Check every Dockerfile and generated Kubernetes manifest for hardening findings. Config: `config/trivyignore.yaml`. +- `trivy-tools-check` (`default` env; run by `check:rust`) -- Fail on HIGH or CRITICAL vulnerabilities inside the + mise-installed tools. Config: `.mise/trivy-tools-check.awk`, `config/trivyignore-tools.yaml`. ## `typos` diff --git a/README.md b/README.md index 9e33ceea..aa7c6ee5 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [coverage]: https://codecov.io/gh/edge-toolkit/core [crate-badge]: https://img.shields.io/crates/v/et-ws-server [crate]: https://crates.io/crates/et-ws-server -[checks-badge]: https://img.shields.io/badge/checks-%3E%3D380-blue +[checks-badge]: https://img.shields.io/badge/checks-%3E%3D400-blue [checks]: CHECKS.md [license-badge]: https://img.shields.io/badge/license-MIT%2BApache--2.0-blue [license]: #licence diff --git a/config/conftest/policy/advisories/advisories.rego b/config/conftest/policy/advisories/advisories.rego index b5e9aecc..4452827d 100644 --- a/config/conftest/policy/advisories/advisories.rego +++ b/config/conftest/policy/advisories/advisories.rego @@ -1,6 +1,6 @@ -# Review dates on the advisory ignores in config/deny.toml, evaluated from the combined TOML input. -# Run with `--namespace advisories` by conftest-check-toml, which feeds deny.toml alongside the other config -# TOML, so `input` is the --combine array of {path, contents} rather than one file's contents. +# Review dates on the advisory ignores in config/deny.toml and on the scanner's two ignore files. +# Run with `--namespace advisories` by conftest-check-toml, which feeds all three in one --combine run, so `input` +# is the array of {path, contents} rather than one file's contents. # # Every entry in `[advisories].ignore` is an accepted finding, and an accepted finding that nobody looks at # again is indistinguishable from one nobody noticed. So each carries a review date in its `reason`, and this @@ -58,9 +58,125 @@ deny contains msg if { msg := sprintf(lapsed_msg, [id, date]) } +# Every distinct review date the advisory ignores carry; one, once the rule below holds. +review_dates := {date | some date in dated} + # Every advisory ignore expires on one date, the next milestone review, which the operator sets. deny contains msg if { - dates := {date | some date in dated} - count(dates) > 1 - msg := sprintf(mixed_msg, [count(dates), sort(dates)]) + count(review_dates) > 1 + msg := sprintf(mixed_msg, [count(review_dates), sort(review_dates)]) +} + +# The scanner's two ignore files are reviewed on the same milestone as deny.toml. +# One holds the accepted vulnerabilities inside the mise-installed tools, the other the accepted Dockerfile and +# manifest misconfigurations. Each entry's `expired_at` is the scanner's own lapse date, so its scan already fails +# once that passes; what these rules add is that the date cannot be missing or drift from the one the operator sets +# in deny.toml. +tools_file := "config/trivyignore-tools.yaml" + +# Each dated ignore file, and the list in it that holds the entries. +expiring_lists := {tools_file: "vulnerabilities", "config/trivyignore.yaml": "misconfigurations"} + +undated_finding_msg := "%s: accepted finding %q has no `expired_at` review date" + +drift_msg := "%s: accepted finding %q expires on %s, not on %v like config/deny.toml" + +expiring contains [file.path, entry] if { + some file in paths.files + some entry in file.contents[expiring_lists[file.path]] +} + +tool_entries contains entry if { + some [path, entry] in expiring + path == tools_file +} + +has_expiry(entry) if is_string(entry.expired_at) + +# Every entry in the scanner's ignore files must carry an `expired_at` review date. +deny contains msg if { + some [path, entry] in expiring + not has_expiry(entry) + msg := sprintf(undated_finding_msg, [path, entry.id]) +} + +# Every entry in the scanner's ignore files expires on the date the advisory ignores in config/deny.toml carry. +deny contains msg if { + some [path, entry] in expiring + has_expiry(entry) + not entry.expired_at in review_dates + msg := sprintf(drift_msg, [path, entry.id, entry.expired_at, sort(review_dates)]) +} + +# The accepted advisories published before 2026, each one reviewed and named here. +# That is one from 2023, four from 2024 and eight from 2025. An advisory that old has had a fix available for a long +# time, so accepting another one is a decision to make here, in review, rather than an entry that slips into an ignore +# list unnoticed. The list only shrinks: an id that leaves every ignore list has to leave this one too. +old_advisories := { + "RUSTSEC-2023-0071", + "RUSTSEC-2024-0436", + "RUSTSEC-2024-0449", + "CVE-2024-21534", + "CVE-2024-34156", + "RUSTSEC-2025-0134", + "CVE-2025-1302", + "CVE-2025-15558", + "CVE-2025-47273", + "CVE-2025-47913", + "CVE-2025-61726", + "CVE-2025-61729", + "CVE-2025-68121", +} + +# The first year an advisory may come from without being named in `old_advisories`. +current_year := 2026 + +# The year in an advisory id: CVE, RUSTSEC, PYSEC, GO and the other `--` schemes. +# Anchored at both ends so a GHSA id, whose three segments are base-32 rather than a year and a number, never reads +# as dated, even when its first segment happens to be four digits. +year_pattern := `^[A-Z]+-([0-9]{4})-[0-9]+$` + +old_msg := "%s: accepted advisory %q is from %d; one from before %d must be named in advisories.rego's old_advisories" + +stale_msg := "advisories.rego: old_advisories names %q, which no ignore list accepts any more -- remove it" + +# Every accepted advisory id, with the file that accepts it. +accepted contains ["config/deny.toml", advisory_id(entry)] if { + some entry in entries +} + +accepted contains [tools_file, entry.id] if { + some entry in tool_entries +} + +advisory_year(id) := to_number(year) if { + [[_, year]] := regex.find_all_string_submatch_n(year_pattern, id, 1) +} + +# An advisory published before 2026 may only be accepted if old_advisories names it. +deny contains msg if { + some [path, id] in accepted + year := advisory_year(id) + year < current_year + not id in old_advisories + msg := sprintf(old_msg, [path, id, year, current_year]) +} + +accepted_ids contains id if { + some [_, id] in accepted +} + +# Staleness can only be judged from every ignore list at once; a run fed fewer files cannot tell gone from unread. +every_list_read if { + read := {file.path | some file in paths.files} + "config/deny.toml" in read + tools_file in read +} + +# Every id in old_advisories must still be accepted by some ignore list, so the allowlist cannot outlive its entries. +deny contains msg if { + every_list_read + some id in old_advisories + not id in accepted_ids + msg := sprintf(stale_msg, [id]) } diff --git a/config/conftest/policy/advisories/advisories_test.rego b/config/conftest/policy/advisories/advisories_test.rego index 7459ce18..6e2c7c61 100644 --- a/config/conftest/policy/advisories/advisories_test.rego +++ b/config/conftest/policy/advisories/advisories_test.rego @@ -89,3 +89,199 @@ test_other_files_in_the_combined_input_are_ignored if { msgs := advisories.deny with input as other with time.now_ns as review_day count(msgs) == 0 } + +# deny.toml plus the tools-scan ignore file, the pair the combined run feeds the policy. +with_tools(tool_entries) := array.concat( + deny_file([dated("RUSTSEC-2026-0285", "2026-10-15")]), + [{"path": "config/trivyignore-tools.yaml", "contents": {"vulnerabilities": tool_entries}}], +) + +test_tool_entry_on_the_deny_date_passes if { + entry := {"id": "CVE-2026-63209", "paths": ["aqua-k3d-io-k3d/5.9.0/k3d"], "expired_at": "2026-10-15"} + msgs := advisories.deny with input as with_tools([entry]) with time.now_ns as review_day + with advisories.old_advisories as set() + count(msgs) == 0 +} + +# A later date is still drift: it would leave the entry standing past the milestone review. +test_tool_entry_on_another_date_is_flagged if { + entry := {"id": "CVE-2026-63209", "expired_at": "2026-11-30"} + msgs := advisories.deny with input as with_tools([entry]) with time.now_ns as review_day + with advisories.old_advisories as set() + count(msgs) == 1 + names(msgs, "CVE-2026-63209") + names(msgs, "expires on 2026-11-30") +} + +test_tool_entry_without_a_date_is_flagged if { + msgs := advisories.deny with input as with_tools([{"id": "CVE-2026-63209"}]) with time.now_ns as review_day + with advisories.old_advisories as set() + count(msgs) == 1 + names(msgs, "has no `expired_at`") +} + +test_each_drifting_tool_entry_is_reported_separately if { + entries := [{"id": "CVE-2026-63209", "expired_at": "2027-01-01"}, {"id": "CVE-2026-78661"}] + msgs := advisories.deny with input as with_tools(entries) with time.now_ns as review_day + with advisories.old_advisories as set() + count(msgs) == 2 + names(msgs, "CVE-2026-63209") + names(msgs, "CVE-2026-78661") +} + +# The tools file is read only at its own path; a same-shaped file elsewhere is not an ignore list. +test_vulnerabilities_in_another_file_are_ignored if { + other := [{"path": "config/trivyignore.yaml", "contents": {"vulnerabilities": [{"id": "CVE-2026-63209"}]}}] + msgs := advisories.deny with input as array.concat(deny_file([dated("RUSTSEC-2026-0285", "2026-10-15")]), other) + with time.now_ns as review_day + count(msgs) == 0 +} + +with_misconfigs(misconfig_entries) := array.concat( + deny_file([dated("RUSTSEC-2026-0285", "2026-10-15")]), + [{"path": "config/trivyignore.yaml", "contents": {"misconfigurations": misconfig_entries}}], +) + +test_misconfiguration_on_the_deny_date_passes if { + entry := {"id": "DS-0026", "paths": ["Dockerfile"], "expired_at": "2026-10-15"} + msgs := advisories.deny with input as with_misconfigs([entry]) with time.now_ns as review_day + count(msgs) == 0 +} + +test_misconfiguration_on_another_date_is_flagged if { + msgs := advisories.deny with input as with_misconfigs([{"id": "DS-0026", "expired_at": "2027-06-30"}]) + with time.now_ns as review_day + count(msgs) == 1 + names(msgs, "config/trivyignore.yaml: accepted finding \"DS-0026\" expires on 2027-06-30") +} + +test_misconfiguration_without_a_date_is_flagged if { + msgs := advisories.deny with input as with_misconfigs([{"id": "KSV-0013"}]) with time.now_ns as review_day + count(msgs) == 1 + names(msgs, "config/trivyignore.yaml: accepted finding \"KSV-0013\" has no `expired_at`") +} + +# A misconfiguration id is a rule code, not an advisory, so the age allowlist never reads it. +test_misconfiguration_ids_are_not_advisories if { + msgs := advisories.deny with input as with_misconfigs([{"id": "KSV-2023-0001", "expired_at": "2026-10-15"}]) + with time.now_ns as review_day + with advisories.old_advisories as set() + count(msgs) == 0 +} + +tool_on_review_day(id) := {"id": id, "expired_at": "2026-10-15"} + +# Every year-numbered id scheme the scanners report, each just before and just at the cutoff year. +dated_ids_before_cutoff := { + "CVE-2025-1302", + "RUSTSEC-2025-0134", + "PYSEC-2024-110", + "GO-2023-2102", + "MAL-2025-41", + "OSV-2022-893", +} + +dated_ids_from_cutoff := {"CVE-2026-63209", "RUSTSEC-2026-0285", "PYSEC-2026-7", "GO-2026-4001", "MAL-2026-1"} + +# GHSA ids are base-32 segments with no year; four-digit first segments included, none of them may read as one. +undated_ids := {"GHSA-hrxh-6v49-42gf", "GHSA-2222-3333-4444", "GHSA-9999-xxxx-q2c4"} + +test_every_dated_prefix_before_the_cutoff_is_flagged_in_the_tools_file if { + every id in dated_ids_before_cutoff { + msgs := advisories.deny with input as with_tools([tool_on_review_day(id)]) + with time.now_ns as review_day + with advisories.old_advisories as set() + names(msgs, $"config/trivyignore-tools.yaml: accepted advisory \"{id}\" is from") + } +} + +test_every_dated_prefix_before_the_cutoff_is_flagged_in_deny_toml if { + every id in dated_ids_before_cutoff { + msgs := advisories.deny with input as deny_file([dated(id, "2026-10-15")]) + with time.now_ns as review_day + with advisories.old_advisories as set() + names(msgs, $"config/deny.toml: accepted advisory \"{id}\" is from") + } +} + +# A bare id string in deny.toml is still an accepted advisory, and still dated by its prefix. +test_bare_old_id_in_deny_toml_is_flagged if { + msgs := advisories.deny with input as deny_file(["RUSTSEC-2023-0071"]) + with time.now_ns as review_day + with advisories.old_advisories as set() + names(msgs, "\"RUSTSEC-2023-0071\" is from 2023") +} + +test_every_dated_prefix_before_the_cutoff_passes_once_allowlisted if { + every id in dated_ids_before_cutoff { + msgs := advisories.deny with input as with_tools([tool_on_review_day(id)]) + with time.now_ns as review_day + with advisories.old_advisories as {id} + count(msgs) == 0 + } +} + +# Ids from the cutoff year on, and GHSA ids that carry no year at all, need no allowlist entry. +test_ids_from_the_cutoff_or_without_a_year_pass_unlisted if { + every id in dated_ids_from_cutoff | undated_ids { + msgs := advisories.deny with input as with_tools([tool_on_review_day(id)]) + with time.now_ns as review_day + with advisories.old_advisories as set() + count(msgs) == 0 + } +} + +test_advisory_year_reads_each_prefix if { + advisories.advisory_year("CVE-2025-1302") == 2025 + advisories.advisory_year("RUSTSEC-2023-0071") == 2023 + advisories.advisory_year("PYSEC-2024-110") == 2024 + advisories.advisory_year("GO-2026-4001") == 2026 + not advisories.advisory_year("GHSA-2222-3333-4444") + not advisories.advisory_year("CVE-2025") +} + +test_unlisted_old_advisory_in_the_tools_file_is_flagged if { + msgs := advisories.deny with input as with_tools([tool_on_review_day("CVE-2025-99999")]) + with time.now_ns as review_day + with advisories.old_advisories as set() + count(msgs) == 1 + names(msgs, "\"CVE-2025-99999\" is from 2025") +} + +test_unlisted_old_advisory_in_deny_toml_is_flagged if { + msgs := advisories.deny with input as deny_file([dated("RUSTSEC-2024-9999", "2026-10-15")]) + with time.now_ns as review_day + with advisories.old_advisories as set() + count(msgs) == 1 + names(msgs, "config/deny.toml: accepted advisory \"RUSTSEC-2024-9999\" is from 2024") +} + +test_listed_old_advisory_passes if { + msgs := advisories.deny with input as with_tools([tool_on_review_day("CVE-2023-12345")]) + with time.now_ns as review_day + with advisories.old_advisories as {"CVE-2023-12345"} + count(msgs) == 0 +} + +# A GHSA id carries no year, so the age rule has nothing to read and leaves it alone. +test_advisory_without_a_year_is_not_judged_by_age if { + msgs := advisories.deny with input as with_tools([tool_on_review_day("GHSA-hrxh-6v49-42gf")]) + with time.now_ns as review_day + with advisories.old_advisories as set() + count(msgs) == 0 +} + +test_allowlisted_id_no_ignore_list_accepts_is_flagged if { + msgs := advisories.deny with input as with_tools([]) with time.now_ns as review_day + with advisories.old_advisories as {"CVE-2024-21534"} + count(msgs) == 1 + names(msgs, "\"CVE-2024-21534\", which no ignore list accepts") +} + +# Fed deny.toml alone, a run has not read the tools file, so it cannot call an id there gone. +test_stale_rule_waits_for_every_ignore_list if { + msgs := advisories.deny with input as deny_file([dated("RUSTSEC-2026-0285", "2026-10-15")]) + with time.now_ns as review_day + with advisories.old_advisories as {"CVE-2024-21534"} + count(msgs) == 0 +} diff --git a/config/jscpd.json b/config/jscpd.json index 6728b2fc..2a7ebb7c 100644 --- a/config/jscpd.json +++ b/config/jscpd.json @@ -9,6 +9,7 @@ "verification/**", "**/HELP.md", "**/pkg/package.json", + "config/trivyignore-tools.yaml", "libs/*/benches/results/**", "libs/gpu-probe/signatures.json", "libs/gpu-probe/signatures.yaml", diff --git a/config/pyrefly.toml b/config/pyrefly.toml index f89b70bc..d7b77bbe 100644 --- a/config/pyrefly.toml +++ b/config/pyrefly.toml @@ -8,7 +8,7 @@ project-includes = ["../libs/python-*/**/*.py", "../modules/**/*.py"] # The Python the code is checked against, rather than whichever interpreter the host's PATH yields first. # Must equal the mise `python` pin. -python-version = "3.13.16" +python-version = "3.13.18" # Resolve imports from `search-path` alone, never from an interpreter's site-packages. # A workstation's workspace `.venv` installs every package here editable, so its interpreter would resolve imports diff --git a/config/semgrep/no-check-tool-mentions.yaml b/config/semgrep/no-check-tool-mentions.yaml index da796d51..4b63e2be 100644 --- a/config/semgrep/no-check-tool-mentions.yaml +++ b/config/semgrep/no-check-tool-mentions.yaml @@ -39,6 +39,7 @@ rules: languages: [generic] paths: exclude: + - "/config/trivyignore-tools.yaml" # Scopes each accepted finding to a tool's install path, which names it. - "/.mise/**" # Tool pin, lockfile entry, and the task that runs it. - "/.codacy.yaml" # Names the workflow linters Codacy defers to, as its exclusion rationale. - "/CHECKS.md" # The generated catalogue of every check, which names each tool by design. @@ -195,6 +196,7 @@ rules: languages: [generic] paths: exclude: + - "/config/trivyignore-tools.yaml" # Scopes each accepted finding to a tool's install path, which names it. - "/.mise/**" # Tool pin, lockfile entries, and the per-format policy tasks. - "/AGENTS.md" # Documents which checks an agent runs for which file types. - "/.codacy.yaml" # Names the config linters Codacy defers to, as its exclusion rationale. @@ -289,6 +291,7 @@ rules: languages: [generic] paths: exclude: + - "/config/trivyignore-tools.yaml" # Scopes each accepted finding to a tool's install path, which names it. - "/.mise/**" # Tool pin, lockfile entry, and the task that runs it. - "/AGENTS.md" # Documents which checks an agent runs for which file types. - "/CHECKS.md" # The generated catalogue of every check, which names each tool by design. @@ -321,6 +324,7 @@ rules: languages: [generic] paths: exclude: + - "/config/trivyignore-tools.yaml" # Scopes each accepted finding to a tool's install path, which names it. - "/.mise/**" # Tool pin, lockfile entry, and the task that runs it. - "/AGENTS.md" # Documents which checks an agent runs for which file types. - "/config/gitleaks.toml" # Its own config, including how far its inline marker reaches. @@ -398,6 +402,7 @@ rules: languages: [generic] paths: exclude: + - "/config/trivyignore-tools.yaml" # Scopes each accepted finding to a tool's install path, which names it. - "/.mise/**" # Tool pin, lockfile entry, and the task that runs it. - "/README.md" # Tells a contributor which checks validate the generated manifests. - "/.codacy.yaml" # Names the manifest checks Codacy defers to, as its exclusion rationale. @@ -414,6 +419,7 @@ rules: languages: [generic] paths: exclude: + - "/config/trivyignore-tools.yaml" # Scopes each accepted finding to a tool's install path, which names it. - "/.mise/**" # Tool pin, lockfile entry, and the task that runs it. - "/AGENTS.md" # Documents which checks an agent runs, and keeping its ignores in sync with .gitignore. - "/config/ls-lint.yaml" # Its own config. @@ -470,6 +476,7 @@ rules: languages: [generic] paths: exclude: + - "/config/trivyignore-tools.yaml" # Scopes each accepted finding to a tool's install path, which names it. - "/.mise/**" # Tool pin, lockfile entry, and the tasks that scan each ecosystem. - "/.github/workflows/dependencies.yaml" # Runs the scan on CI. - "/config/osv-scanner.toml" # Its own config. @@ -508,6 +515,7 @@ rules: languages: [generic] paths: exclude: + - "/config/trivyignore-tools.yaml" # Scopes each accepted finding to a tool's install path, which names it. - "/.mise/**" # Tool pin, lockfile entry, and the lint/fix tasks. - "/AGENTS.md" # Documents which checks an agent runs for which file types. - "/config/conftest/policy/mise_lock/mise_lock.rego" # Allowlists it as a tool locking a glibc build. @@ -547,6 +555,7 @@ rules: languages: [generic] paths: exclude: + - "/config/trivyignore-tools.yaml" # Scopes each accepted finding to a tool's install path, which names it. - "/.mise/**" # Tool pin, lockfile entry, and the check/fix tasks. - "/AGENTS.md" # Documents which checks an agent runs for which file types. - "/config/regal.yaml" # Its own config. @@ -672,6 +681,7 @@ rules: languages: [generic] paths: exclude: + - "/config/trivyignore-tools.yaml" # Scopes each accepted finding to a tool's install path, which names it. - "/.mise/**" # Tool pin, lockfile entry, and the extractor that formats mise task bodies with it. - "/AGENTS.md" # Documents which checks an agent runs for which file types. - "/CHECKS.md" # The generated catalogue of every check, which names each tool by design. @@ -709,6 +719,8 @@ rules: - "/README.md" # Tells a contributor which checks validate the generated manifests. - "/.codacy.yaml" # Names the manifest checks Codacy defers to, as its exclusion rationale. - "/config/trivyignore.yaml" # Its own ignore file, where each entry states why the finding is an artifact. + - "/config/jscpd.json" # Names the tools-scan ignore file, whose entries repeat by design, to skip it. + - "/config/conftest/policy/advisories/**" # Reads the tools-scan ignore file to hold its review dates. - "/CHECKS.md" # The generated catalogue of every check, which names each tool by design. - "/config/semgrep/no-*-mentions.yaml" # The mention bans, which cannot help but name what they ban. pattern-regex: "(?i)trivy" diff --git a/config/trivyignore-tools.yaml b/config/trivyignore-tools.yaml new file mode 100644 index 00000000..20129f2a --- /dev/null +++ b/config/trivyignore-tools.yaml @@ -0,0 +1,710 @@ +# Accepted vulnerabilities inside the mise-installed tools, the known findings the tools scan task tolerates. +# +# The scan this serves exists so that a newly published advisory against any installed tool fails the build. That +# only works while every finding already known has been reviewed and recorded here, so each entry is one advisory id, +# scoped to the install paths it was reviewed for, with the reason it is accepted and a date it lapses on. +# +# Paths are relative to the mise installs directory, which is the scan root, so each one starts with the tool's own +# install directory and its version. A bump of the tool therefore stops the entry matching, and the advisory is +# reported again if the new release still carries it. The wildcards stand only for what differs between platforms +# and machines, since `mise run check` scans on every OS: `{,.exe}` for the Windows suffix on a binary, `*` for the +# digest mise appends to an npm install's directory (`~aube~`) and for the platform named in an +# unpacked archive's directory, and `**` for a layout that differs below the install directory. A finding that has no +# path, as the pip vendor list below does, is scoped by its package URL instead, which names the exact version. +# +# Every entry expires on the date the advisory ignores in config/deny.toml carry, and on that date stops suppressing +# anything, so the scan fails until the entry is dropped, fixed or re-dated alongside those. +--- +vulnerabilities: + # Go standard library and Go modules compiled into upstream release binaries. + # Each tool here is at the newest release the seven-day minimum release age admits, and the fix needs its project to + # rebuild with a newer Go toolchain or module; nothing in this repository can patch a prebuilt binary. Most of them + # are linters and formatters that only read this repository's own files (gitleaks, actionlint, regal, kubeconform, + # conftest, shfmt, goawk, jqfmt, editorconfig-checker, ls-lint, tsgolint), so an attacker would first need a commit + # here. The rest reach only endpoints the operator chooses: kubectl, k3d and docker compose drive local clusters and + # containers, crane publishes to GHCR, gh talks to GitHub, osv-scanner queries osv.dev, and otelcol receives the + # local hosts' metrics. pyodide's distribution ships a Windows `python.exe` launcher built with Go 1.21, which + # nothing runs: its install is kept off PATH, and the modules service only serves the files beside it. + - id: CVE-2024-34156 + paths: + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.22.7, 1.23.1, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2025-15558 + paths: + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + statement: >- + github.com/docker/cli as compiled into each release binary; fixed in 29.2.0, which none of these releases is + built with yet. + expired_at: 2027-01-01 + - id: CVE-2025-47913 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.43.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2025-61726 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.24.12, 1.25.6, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2025-61729 + paths: + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.24.11, 1.25.5, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2025-68121 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.24.13, 1.25.7, 1.26.0-rc.3, which none + of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-111943 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-mvdan-sh/3.14.1/shfmt{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "conftest/0.71.1/conftest{,.exe}" + - "crane/0.22.1/crane{,.exe}" + - "crane/0.22.1/gcrane{,.exe}" + - "crane/0.22.1/krane{,.exe}" + - "editorconfig-checker/4.0.2/editorconfig-checker{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "ls-lint/2.3.2/ls-lint{,.exe}" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + - "osv-scanner/2.7.0/osv-scanner{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.26.10, 1.27.3, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-116587 + paths: + - "conftest/0.71.1/conftest{,.exe}" + statement: >- + github.com/go-jose/go-jose/v4 as compiled into each release binary; fixed in 4.1.6, which none of these releases + is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-17106 + paths: + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + statement: >- + github.com/moby/go-archive as compiled into each release binary; fixed in 0.3.0, which none of these releases is + built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-25679 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.8, 1.26.1, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-27137 + paths: + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.26.1, which none of these releases is + built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-27145 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.11, 1.26.4, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-32280 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.9, 1.26.2, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-32281 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.9, 1.26.2, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-32283 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.9, 1.26.2, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-33810 + paths: + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.26.2, which none of these releases is + built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-33811 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.10, 1.26.3, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-33814 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.10, 1.26.3, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-33818 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.13, 1.26.6, 1.27.0-rc.3, which none + of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-39820 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.10, 1.26.3, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-39821 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.13, 1.26.6, 1.27.0-rc.3, which none + of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-39822 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.12, 1.26.5, 1.27.0-rc.2, which none + of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-39828 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.52.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-39829 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.52.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-39830 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.52.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-39831 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.52.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-39832 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.52.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-39835 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.52.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-39836 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.10, 1.26.3, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-41567 + paths: + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + statement: >- + github.com/docker/docker as compiled into each release binary; fixed in none, which none of these releases is + built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-42306 + paths: + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + statement: >- + github.com/docker/docker as compiled into each release binary; fixed in none, which none of these releases is + built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-42499 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.10, 1.26.3, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-42504 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.11, 1.26.4, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-42508 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.52.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-46595 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.52.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-46597 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.52.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-46600 + paths: + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + golang.org/x/net and the Go standard library as compiled into each release binary; fixed in 1.26.6, 1.27.0-rc.3, + which none of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-56851 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-kubernetes-kubernetes-kubectl/1.37.2/kubectl{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + golang.org/x/text as compiled into each release binary; fixed in 0.41.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-56852 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + golang.org/x/text as compiled into each release binary; fixed in 0.39.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-56853 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.13, 1.26.6, 1.27.0-rc.3, which none + of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-56854 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "crane/0.22.1/krane{,.exe}" + statement: >- + golang.org/x/crypto as compiled into each release binary; fixed in 0.55.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-56858 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.13, 1.26.6, 1.27.0-rc.3, which none + of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-56859 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.13, 1.26.6, 1.27.0-rc.3, which none + of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-56860 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.13, 1.26.6, 1.27.0-rc.3, which none + of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-56862 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.25.13, 1.26.6, 1.27.0-rc.3, which none + of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-56864 + paths: + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + statement: >- + golang.org/x/mod as compiled into each release binary; fixed in 0.40.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-56865 + paths: + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + statement: >- + golang.org/x/mod as compiled into each release binary; fixed in 0.40.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-63209 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + statement: >- + github.com/klauspost/compress as compiled into each release binary; fixed in 1.18.7, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-78661 + paths: + - "aqua-docker-compose/5.7.0/docker-cli-plugin-docker-compose{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-kubernetes-kubernetes-kubectl/1.37.2/kubectl{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "conftest/0.71.1/conftest{,.exe}" + - "gh/2.103.3/gh_2.103.3_*/bin/gh{,.exe}" + - "github-open-telemetry-opentelemetry-collector-releases/0.164.0/otelcol{,.exe}" + - "osv-scanner/2.7.0/osv-scanner{,.exe}" + statement: >- + golang.org/x/net as compiled into each release binary; fixed in 0.62.0, which none of these releases is built + with yet. + expired_at: 2027-01-01 + - id: CVE-2026-78667 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-mvdan-sh/3.14.1/shfmt{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "conftest/0.71.1/conftest{,.exe}" + - "crane/0.22.1/crane{,.exe}" + - "crane/0.22.1/gcrane{,.exe}" + - "crane/0.22.1/krane{,.exe}" + - "editorconfig-checker/4.0.2/editorconfig-checker{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + - "osv-scanner/2.7.0/osv-scanner{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.26.9, 1.27.2, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-78669 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-kubernetes-kubernetes-kubectl/1.37.2/kubectl{,.exe}" + - "aqua-mvdan-sh/3.14.1/shfmt{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "conftest/0.71.1/conftest{,.exe}" + - "crane/0.22.1/crane{,.exe}" + - "crane/0.22.1/gcrane{,.exe}" + - "crane/0.22.1/krane{,.exe}" + - "editorconfig-checker/4.0.2/editorconfig-checker{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + - "osv-scanner/2.7.0/osv-scanner{,.exe}" + statement: >- + the Go standard library and golang.org/x/net as compiled into each release binary; fixed in 1.26.9, 1.27.2, + which none of these releases is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-84304 + paths: + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + statement: >- + google.golang.org/grpc as compiled into each release binary; fixed in 1.83.1, which none of these releases is + built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-84445 + paths: + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + statement: >- + google.golang.org/grpc as compiled into each release binary; fixed in 1.82.2, 1.83.2, + 1.84.0-dev.0.20260825144003-d5a41119e0e3, 1.85.0-dev.0.20260825072537-93e31b48545e, which none of these releases + is built with yet. + expired_at: 2027-01-01 + - id: CVE-2026-97031 + paths: + - "aqua-gitleaks-gitleaks/8.30.1/gitleaks{,.exe}" + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + - "aqua-mvdan-sh/3.14.1/shfmt{,.exe}" + - "aqua-rhysd-actionlint/1.7.12/actionlint{,.exe}" + - "aqua-styra-inc-regal/0.43.0/regal{,.exe}" + - "aqua-yannh-kubeconform/0.8.0/kubeconform{,.exe}" + - "conftest/0.71.1/conftest{,.exe}" + - "crane/0.22.1/crane{,.exe}" + - "crane/0.22.1/gcrane{,.exe}" + - "crane/0.22.1/krane{,.exe}" + - "editorconfig-checker/4.0.2/editorconfig-checker{,.exe}" + - "github-benhoyt-goawk/1.32.0/goawk{,.exe}" + - "go-github-com-noperator-jqfmt-cmd-jqfmt/0.1.0/bin/jqfmt{,.exe}" + - "http-pyodide/0.29.3/python.exe" + - "npm-oxlint-tsgolint/0.24.0~*/**/tsgolint{,.exe}" + - "osv-scanner/2.7.0/osv-scanner{,.exe}" + statement: >- + the Go standard library as compiled into each release binary; fixed in 1.26.9, 1.27.2, which none of these + releases is built with yet. + expired_at: 2027-01-01 + - id: GHSA-hrxh-6v49-42gf + paths: + - "aqua-k3d-io-k3d/5.9.0/k3d{,.exe}" + statement: >- + google.golang.org/grpc as compiled into each release binary; fixed in 1.82.1, which none of these releases is + built with yet. + expired_at: 2027-01-01 + + # The npm CLI that ships inside node. + # No task runs npm: JavaScript dependencies install through pnpm and mise's own npm backend, so this copy is never + # invoked. node 24.22.2 is the newest 24.x the minimum release age admits; the next one is the earliest that can + # carry a newer npm, and these go with that bump. + - id: CVE-2026-102276 + paths: + - "node/24.22.2/**/npm/node_modules/brace-expansion/package.json" + statement: >- + brace-expansion 5.0.9; fixed in 5.0.10, 3.0.7, 2.1.5, 1.1.19. + expired_at: 2027-01-01 + - id: CVE-2026-102278 + paths: + - "node/24.22.2/**/npm/node_modules/brace-expansion/package.json" + statement: >- + brace-expansion 5.0.9; fixed in 5.0.11, 3.0.8, 2.1.6, 1.1.20. + expired_at: 2027-01-01 + - id: CVE-2026-109383 + paths: + - "node/24.22.2/**/npm/node_modules/undici/package.json" + statement: >- + undici 6.28.0; fixed in 6.29.1, 7.30.1, 8.12.2. + expired_at: 2027-01-01 + - id: CVE-2026-109869 + paths: + - "node/24.22.2/**/npm/node_modules/undici/package.json" + statement: >- + undici 6.28.0; fixed in 6.29.1, 7.30.1, 8.12.2. + expired_at: 2027-01-01 + - id: CVE-2026-19534 + paths: + - "node/24.22.2/**/npm/node_modules/undici/package.json" + statement: >- + undici 6.28.0; fixed in 6.28.1, 7.29.1, 8.10.2. + expired_at: 2027-01-01 + - id: CVE-2026-87018 + paths: + - "node/24.22.2/**/npm/node_modules/undici/package.json" + statement: >- + undici 6.28.0; fixed in 6.29.1, 7.30.1, 8.12.2. + expired_at: 2027-01-01 + + # pip's vendored setuptools, listed in pip/_vendor/vendor.txt inside the python install. + # pip vendors only setuptools' `pkg_resources`. The advisory is a path traversal in `setuptools.package_index`, which + # pip does not ship, so the vulnerable code is not present at all; the version string is all that matches. + - id: CVE-2025-47273 + purls: + - "pkg:pypi/setuptools@70.3.0" + statement: >- + setuptools 70.3.0; fixed in 78.1.1. + expired_at: 2027-01-01 + + # Guava on the classpath of the Gradle and Maven distributions. + # A memory-exhaustion denial of service, reachable only through the build files and dependency metadata the two tools + # read: this repository's own pom.xml and Gradle scripts, and artifacts from Maven Central and the Gradle Plugin + # Portal. Both pins are the newest releases the minimum release age admits, and Gradle 9.9.0 still bundles the same + # Guava, so no bump clears it. + - id: CVE-2026-102554 + paths: + - "gradle/9.8.2/gradle-9.8.2/lib/guava-33.4.6-jre.jar" + - "maven/3.10.0/apache-maven-3.10.0/lib/guava-33.7.1-jre.jar" + statement: >- + com.google.guava:guava 33.4.6-jre and com.google.guava:guava 33.7.1-jre; fixed in 33.7.2. + expired_at: 2027-01-01 + + # Dependencies of the AsyncAPI generator, which `gen:ws-md` drives through its library API. + # Its only input is generated/specs/ws.yaml, which et-int-gen writes from this repository's own Rust types, and its + # only template is the pinned markdown template installed beside it. jsonpath-plus therefore evaluates expressions + # from that document alone, and simple-git, which the generator uses to fetch a template from a git URL, is never + # called, since the template is a local path. 3.5.0 is the newest generator release, and it still depends on both. + - id: CVE-2024-21534 + paths: + - "npm-asyncapi-generator/3.5.0~*/**/jsonpath-plus/package.json" + statement: >- + jsonpath-plus 7.2.0; fixed in 10.2.0. + expired_at: 2027-01-01 + - id: CVE-2025-1302 + paths: + - "npm-asyncapi-generator/3.5.0~*/**/jsonpath-plus/package.json" + statement: >- + jsonpath-plus 7.2.0; fixed in 10.3.0. + expired_at: 2027-01-01 + - id: CVE-2026-102826 + paths: + - "npm-asyncapi-generator/3.5.0~*/**/simple-git/package.json" + statement: >- + simple-git 3.36.0; fixed in 4.0.0. + expired_at: 2027-01-01 + - id: CVE-2026-102827 + paths: + - "npm-asyncapi-generator/3.5.0~*/**/simple-git/package.json" + statement: >- + simple-git 3.36.0; fixed in 4.0.0. + expired_at: 2027-01-01 + - id: CVE-2026-102828 + paths: + - "npm-asyncapi-generator/3.5.0~*/**/simple-git/package.json" + statement: >- + simple-git 3.36.0; fixed in 4.0.1. + expired_at: 2027-01-01 + - id: CVE-2026-102829 + paths: + - "npm-asyncapi-generator/3.5.0~*/**/@simple-git/argv-parser/package.json" + statement: >- + @simple-git/argv-parser 1.1.1; fixed in 2.0.1. + expired_at: 2027-01-01 diff --git a/config/trivyignore.yaml b/config/trivyignore.yaml index cbdb342b..ed850c98 100644 --- a/config/trivyignore.yaml +++ b/config/trivyignore.yaml @@ -11,6 +11,9 @@ # # `statement` is trivy's own field for the justification, so the reason travels with the suppression rather # than living in a comment beside it. +# +# `expired_at` is trivy's own lapse date: on it the entry stops suppressing and the finding is reported again. +# Every entry carries the date the advisory ignores in config/deny.toml carry, reviewed on the same milestone. --- misconfigurations: # A locally built image has no registry version for a tag to name. @@ -20,6 +23,7 @@ misconfigurations: # is already closed, because the manifests set `IfNotPresent` explicitly. The one image that does come from # a registry, the collector, is pinned. - id: KSV-0013 + expired_at: 2027-01-01 paths: - "verification/*/output/*/k3s.yaml" statement: >- @@ -31,6 +35,7 @@ misconfigurations: # deployment runs. This repository mirrors assets it controls to its own releases (the upstream-cache # pattern) but has no mirror for a third-party container image. - id: KSV-0125 + expired_at: 2027-01-01 paths: - "verification/*/output/*/k3s.yaml" statement: >- @@ -42,6 +47,7 @@ misconfigurations: # deliberately absent from the ConfigMap and reaches the pods from a Secret the operator creates from the # uncommitted env file, which is the whole point of splitting the two. - id: KSV-01010 + expired_at: 2027-01-01 paths: - "verification/*/output/*/k3s.yaml" statement: >- @@ -54,26 +60,31 @@ misconfigurations: # is dropped, privilege escalation is off and the root filesystem is read-only. Scoped to the scenarios whose limits # need the plugins, so a root container or a host mount anywhere else in a generated manifest is still reported. - id: KSV-0012 + expired_at: 2027-01-01 paths: - "verification/local/output/math1-limits/k3s.yaml" statement: >- The NRI plugins must run as root to connect to the root-only NRI socket; they drop every capability. - id: KSV-0020 + expired_at: 2027-01-01 paths: - "verification/local/output/math1-limits/k3s.yaml" statement: >- The NRI plugins run as uid 0, the only user that can connect to the NRI socket. - id: KSV-0021 + expired_at: 2027-01-01 paths: - "verification/local/output/math1-limits/k3s.yaml" statement: >- The NRI plugins run as root's group alongside uid 0, the only user that can connect to the NRI socket. - id: KSV-0105 + expired_at: 2027-01-01 paths: - "verification/local/output/math1-limits/k3s.yaml" statement: >- The NRI plugins run as uid 0, the only user that can connect to the NRI socket. - id: KSV-0023 + expired_at: 2027-01-01 paths: - "verification/local/output/math1-limits/k3s.yaml" statement: >- @@ -84,6 +95,7 @@ misconfigurations: # plain `docker build` supplies with `--build-context`; trivy reads that as an image reference with no tag. A # published scenario names the released hub image instead, so the rule still applies there. - id: DS-0001 + expired_at: 2027-01-01 paths: - "verification/local/output/*/Dockerfile" statement: >- @@ -93,6 +105,7 @@ misconfigurations: # The maintainer's image publishing assembles that one tag from each architecture's build, so it is the only one a # node of either architecture resolves; there is no versioned tag yet for the Dockerfile to pin instead. - id: DS-0001 + expired_at: 2027-01-01 paths: - "verification/published/output/*/Dockerfile" statement: >- @@ -100,6 +113,7 @@ misconfigurations: # Scenario images serve the hub, whose health is checked by the deployment rather than the image. - id: DS-0026 + expired_at: 2027-01-01 paths: - "verification/*/output/*/Dockerfile" statement: >- @@ -110,6 +124,7 @@ misconfigurations: # is why the generated deployments give them no probe either -- the orchestrator restarts them until the hub # answers, and their exit is the result rather than a fault. - id: DS-0026 + expired_at: 2027-01-01 paths: - "services/ws-pyo3-runner/Dockerfile" - "services/ws-wasi-runner/Dockerfile" @@ -122,6 +137,7 @@ misconfigurations: # source; nothing consumes them as a long-lived deployment, and the hardened server image consumers actually # deploy is services/ws-server/Dockerfile. - id: DS-0026 + expired_at: 2027-01-01 paths: - "Dockerfile" - "Dockerfile.nanoserver" @@ -134,6 +150,7 @@ misconfigurations: # against the same endpoint, both generated by et-cli, so the check exists once per deployment rather than # being baked in. The image ships curl specifically so those external checks have a client to use. - id: DS-0026 + expired_at: 2027-01-01 paths: - "services/ws-server/Dockerfile" statement: >-