Skip to content

Commit 2bd3f39

Browse files
authored
chore(deps): bump aiperf to 0.13.0 and fix license arch guard (#2987)
Signed-off-by: Mark Chmarny <mark@chmarny.com>
1 parent caa38a6 commit 2bd3f39

11 files changed

Lines changed: 2214 additions & 685 deletions

File tree

β€Ž.agents/skills/aicr-managing-openvex/SKILL.mdβ€Ž

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ no-ops every statement in the document.
4747
- A `Weekly Image Vulnerability Scan` run reports HIGH+ CVE(s) on the
4848
aiperf-bench image and a maintainer needs to add a suppression after
4949
verifying reachability.
50-
- A maintainer bumps the aiperf pin (`AIPERF_VERSION` in
51-
`validators/performance/aiperf-bench.Dockerfile`) or its dependency
52-
pins, fixing a CVE that was previously suppressed β†’ the entry must be
50+
- A maintainer bumps the aiperf pin (`validators/performance/requirements.txt`
51+
and `AIPERF_VERSION` in `validators/performance/aiperf-bench.Dockerfile`)
52+
or its dependency pins, fixing a CVE that was previously suppressed β†’ the entry must be
5353
removed.
5454
- A maintainer audits the file before a release to drop stale entries.
5555
- The scan workflow shows non-zero HIGH+ counts but VEX is "supposed to
@@ -317,9 +317,11 @@ For each ID:
317317
1. **Check upstream first.** Read the GHSA / NVD page. If a fix has
318318
shipped in a version reachable from aiperf's pins, the right action
319319
is usually *not* a VEX entry β€” it's bumping the aiperf pin so the
320-
fix lands and the finding disappears. Bump
321-
`AIPERF_VERSION` in `validators/performance/aiperf-bench.Dockerfile`,
322-
verify with the local repro above, and skip the rest of this section.
320+
fix lands and the finding disappears. Bump `aiperf` in
321+
`validators/performance/requirements.txt` and `AIPERF_VERSION` in
322+
`validators/performance/aiperf-bench.Dockerfile` together (the build
323+
fails on a mismatch), run `make python-licenses`, verify with the local
324+
repro above, and skip the rest of this section.
323325
2. **If a bump isn't feasible**, prove non-reachability. The work that
324326
must be visible in `impact_statement`:
325327
- Identify the vulnerable function / file in upstream source.
@@ -453,7 +455,8 @@ goes into the document itself.
453455
bound)
454456
- Grype config (excludes for source scans only): `.grype.yaml`
455457
- Image source: `validators/performance/aiperf-bench.Dockerfile`
456-
- aiperf pin: `AIPERF_VERSION` ARG in that Dockerfile
458+
- aiperf pin: `validators/performance/requirements.txt` (what installs) and
459+
the `AIPERF_VERSION` ARG in that Dockerfile (must match; Renovate moves both)
457460
- Grype version pin (read from scan-action): `GrypeVersion.js` at the
458461
pinned scan-action SHA in the workflow
459462
- Workflow output format (per image, in scan-N artifact):

β€Ž.agents/skills/aicr-managing-openvex/vex-state.yamlβ€Ž

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,36 @@ deferred_verifications:
8282
references remain. What is unverified is only whether the CI scan step
8383
accepts the tag-plus-digest matrix value, not whether the override
8484
works.
85+
- id: aiperf-0.13.0-image-scans-clean-in-ci
86+
opened: 2026-09-29
87+
check: >-
88+
The aiperf 0.13.0 bump retired the 10 pillow statements and
89+
GHSA-cq5v-8q36-5273 (0.13.0 resolves pillow 12.3.0 and aiohttp 3.14.3,
90+
the fixed versions) and rewrote the CVE-2026-82049 evidence for the
91+
0.13.0 closure. Read the aiperf-bench scan-result artifact of the first
92+
`Weekly Image Vulnerability Scan` run on main after that PR merged.
93+
resolves_when: >-
94+
that run's aiperf-bench line reports 0 critical, 0 high and exactly
95+
1 VEX-suppressed row (CVE-2026-82049 on python 3.13.15)
96+
caveat: >-
97+
Measured on a local linux/amd64 build of the branch with grype v0.118.0
98+
(the version scan-action v7.4.2 pins), `--fail-on high --only-fixed -c
99+
.grype.yaml --vex .openvex.json`, against the 2026-09-29 grype DB. A newer DB in CI can add
100+
findings this run could not see; triage those as new, not as a
101+
regression of the retirement.
85102
86103
known_negatives:
87104
- id: no-fixed-cpython-3.13-for-cve-2026-82049
88-
checked: 2026-09-21
105+
checked: 2026-09-29
89106
finding: >-
90107
CVE-2026-82049 (tarfile extraction filters) cannot be remediated by any
91108
bump available to this image. 3.13.15 is the newest CPython 3.13 release
92109
(2026-08-05); the advisory published 2026-09-14 and the 3.13 backport
93110
landed after that release, so grype records the sole fixed version as
94111
`3.14.0b1` -- which is why `--only-fixed` does not withhold it.
95112
nvcr.io/nvidia/distroless/python publishes a 3.14-v4.1.4 tag, but aiperf
96-
0.11.0 declares `Requires-Python: <3.14,>=3.10` and upstream main still
97-
declares `>=3.11,<3.14`, so building the venv on 3.14 fails pip resolution
98-
instead of producing a fixed image.
113+
0.13.0 still declares `Requires-Python: <3.14,>=3.11`, so building the
114+
venv on 3.14 fails pip resolution instead of producing a fixed image.
99115
also: >-
100116
The finding is on the base image's interpreter (pkg:generic/python@3.13.15
101117
at /usr/local/bin/python), not a pip package, so no requirements.txt change
@@ -105,29 +121,6 @@ known_negatives:
105121
a CPython 3.13.16+ release carrying the backport (then bump the distroless
106122
3.13 pin and delete the statement), or an aiperf release whose
107123
Requires-Python admits 3.14 (then the 3.14 base becomes reachable, #1910)
108-
- id: aiperf-pins-block-pillow-and-aiohttp-fixes
109-
checked: 2026-09-03
110-
finding: >-
111-
Neither surviving suppression can be remediated by a pin bump. aiperf
112-
pins pillow~=12.2.0 while the 10 pillow GHSAs are fixed in 12.3.0, and
113-
aiohttp~=3.13.3 (>=3.13.3,<3.14) while GHSA-cq5v-8q36-5273 is fixed in
114-
3.14.3. Both caps hold at aiperf 0.11.0 (installed) and 0.12.0 (newest
115-
upstream at the time of checking), so requiring a fixed version in
116-
validators/performance/requirements.txt would fail pip resolution rather
117-
than produce a fixed image.
118-
also: >-
119-
Both packages arrive through the copied virtualenv layer, not the
120-
distroless base, so no base-image bump can retire either statement.
121-
update_2026_09_21: >-
122-
aiperf upstream main has since relaxed the aiohttp cap to
123-
`aiohttp>=3.14.3,<4`, which is past the GHSA-cq5v-8q36-5273 fix. Main is
124-
not a release, so the finding stands for now, but the next aiperf release
125-
carrying that pyproject.toml very likely retires that one statement. The
126-
pillow cap on main is still `pillow~=12.2.0`, so all 10 pillow statements
127-
are unaffected by this and stay.
128-
invalidated_by: >-
129-
an aiperf release later than 0.12.0 that relaxes either cap; re-check
130-
pyproject.toml before assuming the suppression is still unavoidable
131124
132125
deliberate_exclusions:
133126
- id: libexpat1-wont-fix-highs

β€Ž.github/RENOVATE.mdβ€Ž

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Policy choices (schedule, cooldown, auto-merge scope, group consolidation) are d
2020
| `go.mod` | `gomod` (groups: `kubernetes`, `golang-x`, `opencontainers`) |
2121
| `.github/workflows/*.yaml`, `.github/actions/*/action.yml` | `github-actions` (**disabled** β€” Dependabot owns workflow / composite-action bumps; Renovate cannot push `.github/workflows/*` with the auto-issued `GITHUB_TOKEN`) |
2222
| `validators/*/Dockerfile` | `dockerfile` |
23+
| `validators/performance/requirements.txt` (aiperf) | `pip_requirements` (`aiperf` group) |
24+
| `validators/performance/aiperf-bench.Dockerfile` `ARG AIPERF_VERSION` | dedicated `pypi` customManager (`aiperf` group, so it moves with `requirements.txt`) |
2325
| `infra/**/*.tf` | `terraform` (grouped) |
2426
| `recipes/components/*/values.yaml` | `helm-values` (partial β€” see limitations) |
2527
| `recipes/registry.yaml` (35 chart pins) | custom regex manager (`# renovate:` annotations) β€” **report-only**, see [Registry drift report](#registry-drift-report) |
@@ -134,5 +136,6 @@ This is guidance for a Renovate-owned branch. `AGENTS.md`'s branch-hygiene rule
134136

135137
- **AWS EFA device-plugin image** (`recipes/components/aws-efa/values.yaml`) is published only to AWS's authenticated public ECR (`602401143452.dkr.ecr.us-west-2.amazonaws.com/...`); no `public.ecr.aws` mirror. The image is in `ignoreDeps`; bumps must be coordinated manually with EKS add-on releases.
136138
- **`recipes/components/*/values.yaml`** is partially covered, and cannot be extended in place. `helm-values` only auto-detects the conventional `image: { repository, tag }` shape. No custom manager's `managerFilePatterns` covers this path, so a `# renovate:` annotation added in one of these files rotates nothing and reports nothing β€” extending coverage means adding a custom manager, as `.settings.yaml` and `recipes/registry.yaml` each do.
139+
- **aiperf PRs need a manual license refresh and VEX re-audit.** The committed `validators/performance/licenses/python-notices.md` records the sha256 of `requirements.txt`, so an `aiperf` group PR fails `notices-generator` until a maintainer runs `make python-licenses` (network access to PyPI) and pushes the regenerated fragment; no `postUpgradeTasks` entry regenerates it. The same maintainer must re-audit `.openvex.json` against the new closure with the `aicr-managing-openvex` skill: its statements cite the installed aiperf version as evidence, and nothing gates them against `requirements.txt`.
137140
- **No vulnerability fast-path.** Self-hosted Renovate cannot consume GitHub vulnerability alerts (Mend-hosted feature). The weekday cron is the mitigation.
138141
- **The Renovate runner image** (`ghcr.io/renovatebot/renovate`) is not yet auto-managed. The digest is pinned in two places β€” the `RENOVATE_VALIDATOR_IMAGE` variable in `Makefile` and the `renovate-version` input in the workflow β€” and must be bumped manually in lockstep. The custom regex doesn't yet capture `image:tag@sha256:...` shapes.

β€Ž.github/renovate.json5β€Ž

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,19 @@
144144
],
145145
depTypeTemplate: "registry-chart",
146146
},
147+
{
148+
// aiperf is pinned twice: validators/performance/requirements.txt (read
149+
// by the pip_requirements manager) and the AIPERF_VERSION default in
150+
// aiperf-bench.Dockerfile, which the image build requires to match it.
151+
// No built-in manager reads a bare ARG, so without this the Dockerfile
152+
// copy never moves and every aiperf PR fails its own image build (#2956).
153+
// The `aiperf` group below keeps both edits in one PR.
154+
customType: "regex",
155+
managerFilePatterns: ["/^validators/performance/aiperf-bench\\.Dockerfile$/"],
156+
matchStrings: ["(?m)^ARG AIPERF_VERSION=(?<currentValue>\\S+)"],
157+
datasourceTemplate: "pypi",
158+
depNameTemplate: "aiperf",
159+
},
147160
],
148161

149162
// Kubernetes manager: scan AICR's component manifests for Pod-spec
@@ -249,6 +262,12 @@
249262
matchManagers: ["gomod"],
250263
matchPackageNames: ["github.com/opencontainers/**"],
251264
},
265+
// Cross-manager: requirements.txt (pip_requirements) and the Dockerfile
266+
// ARG (custom.regex) must move together; see the aiperf customManager.
267+
{
268+
groupName: "aiperf",
269+
matchPackageNames: ["aiperf"],
270+
},
252271
// Disable the github-actions manager β€” dependabot owns workflow/action
253272
// bumps because GitHub's auto-issued GITHUB_TOKEN cannot push changes to
254273
// `.github/workflows/*` regardless of `permissions:` set in the workflow.
@@ -466,7 +485,7 @@
466485
// PR #1906 auto-bumped this to 3.14 and broke the UAT validator image
467486
// build (aiperf's pyzmq/uvloop had no cp314 wheels, and the single-stage
468487
// image had no toolchain to compile them). Even with the current
469-
// multi-stage toolchain, aiperf 0.11.0 declares requires-python <3.14, so
488+
// multi-stage toolchain, aiperf 0.13.0 declares requires-python <3.14, so
470489
// pip refuses to install on 3.14 β€” the 3.14 move is blocked upstream until
471490
// aiperf supports it. This cap mirrors that constraint; #1910 tracks
472491
// lifting it.

β€Ž.grype.yamlβ€Ž

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ exclude:
3939
# carries the structured status + justification + per-CVE
4040
# reachability evidence and is self-sufficient for suppression.
4141
# The image builds on python:3.13-slim (Debian trixie) and ships on
42-
# nvcr.io/nvidia/distroless/python:3.13-v4.1.4, so suppressed findings
43-
# now come from pillow and aiohttp in the copied venv only. Base-package
44-
# findings are answered by bumping this pin, never by a statement: the
42+
# nvcr.io/nvidia/distroless/python:3.13-v4.1.4. The only suppressed finding
43+
# is CVE-2026-82049 on that base's CPython 3.13.15, which no 3.13 release
44+
# fixes yet. Other base-package findings are answered by bumping this pin: the
4545
# v4.1.4 bump (from v4.1.2) moved glibc 2.41-12+deb13u3 -> u4 and
4646
# libsqlite3-0 3.46.1-7+deb13u1 -> u2, clearing 6 HIGH+ rows without
4747
# adding one; the v4.1.2 bump (from v4.1.1) moved openssl
@@ -52,9 +52,9 @@ exclude:
5252
# When scanning the aiperf-bench image locally, pass `--vex
5353
# .openvex.json` alongside `-c .grype.yaml`. Scans of the AICR Go
5454
# source tree (`make scan` β†’ `grype dir:.`) don't need VEX since the
55-
# suppressed CVEs are all in Python packages (pillow, aiohttp) and
56-
# never surface against Go source.
57-
# Reviewed: 2026-09-17
55+
# suppressed CVE is in the image's CPython interpreter and never
56+
# surfaces against Go source.
57+
# Reviewed: 2026-09-29
5858

5959
# Go-source suppressions (accepted risk, not "not affected").
6060
#

0 commit comments

Comments
Β (0)