Typing --from/--to/--image by hand means someone has to remember that the recipe also bumped its redis. That is how sidecar CVEs went uncounted for months. Point this at a PR's compose.yml and it reads the windows off the diff.
advisory-scan.py plausible --compose-to .../raw/branch/upgrade-4.0.0+v3.2.1/compose.yml
community-edition: v2.0.0 -> v3.2.1
clickhouse-server: 23.4.2.11-alpine -> 24.12-alpine
=> 6 CVEs (identical to the hand-specified args)
Three details that decided the design, each found by it being wrong first:
Keyed by SERVICE, not image repo. plausible moved plausible/analytics → ghcr.io/plausible/community-edition. Keyed by repo, that reads as one image vanishing and an unrelated one appearing — and the app window, the one carrying the criticalCVE-2026-8467, is lost entirely. My first cut did exactly that and reported 0.
Baseline = the repo's default branch resolved from the API, never assumed to be main, because several coopcloud recipes keep a stale main beside a live master.
Image names match sources BOTH ways. An image name is often longer than its source repo (clickhouse/clickhouse-server vs ClickHouse/ClickHouse) and sometimes shorter (redis vs redis/redis). One-directional matching silently dropped the clickhouse window — the scan said 1 instead of 6.
Credentials go in an Authorization header, never the URL: in-URL creds leak into shell history and process lists, and urllib mis-parses a password containing a colon.
--from/--to/--image stay for finer-grained checks — scanning a window that is not a literal compose diff, e.g. "what would the compatibility-safe target fix?".
71 tests (7 new covering the derivation, incl. the changed-repo and templated-tag cases). Regressions unchanged: discourse 140, gitea 2, mailu 2. SPEC updated.
Typing `--from/--to/--image` by hand means someone has to remember that the recipe also bumped its redis. That is how sidecar CVEs went uncounted for months. Point this at a PR's `compose.yml` and it reads the windows off the diff.
```
advisory-scan.py plausible --compose-to .../raw/branch/upgrade-4.0.0+v3.2.1/compose.yml
community-edition: v2.0.0 -> v3.2.1
clickhouse-server: 23.4.2.11-alpine -> 24.12-alpine
=> 6 CVEs (identical to the hand-specified args)
```
**Three details that decided the design, each found by it being wrong first:**
- **Keyed by SERVICE, not image repo.** plausible moved `plausible/analytics` → `ghcr.io/plausible/community-edition`. Keyed by repo, that reads as one image vanishing and an unrelated one appearing — and the app window, the one carrying the **critical** `CVE-2026-8467`, is lost entirely. My first cut did exactly that and reported 0.
- **Baseline = the repo's default branch resolved from the API**, never assumed to be `main`, because several coopcloud recipes keep a stale `main` beside a live `master`.
- **Image names match sources BOTH ways.** An image name is often longer than its source repo (`clickhouse/clickhouse-server` vs `ClickHouse/ClickHouse`) and sometimes shorter (`redis` vs `redis/redis`). One-directional matching silently dropped the clickhouse window — the scan said 1 instead of 6.
Credentials go in an `Authorization` header, never the URL: in-URL creds leak into shell history and process lists, and urllib mis-parses a password containing a colon.
`--from/--to/--image` stay for finer-grained checks — scanning a window that is not a literal compose diff, e.g. "what would the compatibility-safe target fix?".
**71 tests** (7 new covering the derivation, incl. the changed-repo and templated-tag cases). Regressions unchanged: discourse 140, gitea 2, mailu 2. SPEC updated.
Typing --from/--to/--image by hand means someone has to remember the recipe also
bumped its redis. That is how sidecar CVEs went uncounted for months. Point this
at a PR's compose.yml and it reads the windows off the diff instead.
advisory-scan.py plausible --compose-to <.../branch/<pr>/compose.yml>
-> community-edition: v2.0.0 -> v3.2.1
-> clickhouse-server: 23.4.2.11-alpine -> 24.12-alpine
-> 6 CVEs, identical to the hand-specified args
Details that mattered:
- keyed by SERVICE, not image repo. plausible moved plausible/analytics ->
ghcr.io/plausible/community-edition; keyed by repo that reads as one image
vanishing and an unrelated one appearing, and the app window - the one carrying
the critical - is lost entirely.
- the baseline is the repo's DEFAULT BRANCH resolved from the API, never assumed
to be main, because several recipes keep a stale main beside a live master.
- image names are matched against advisory sources BOTH ways: an image name is
often longer than its source repo (clickhouse/clickhouse-server vs
ClickHouse/ClickHouse) and sometimes shorter (redis vs redis/redis). One
direction silently dropped the clickhouse window.
- credentials go in an Authorization header, never the URL: in-URL creds leak
into shell history and process lists, and urllib mis-parses a password
containing a colon.
--from/--to/--image remain for finer-grained checks (scanning a window that is
not a literal compose diff). 71 tests; discourse 140 / gitea 2 / mailu 2
unchanged.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Typing
--from/--to/--imageby hand means someone has to remember that the recipe also bumped its redis. That is how sidecar CVEs went uncounted for months. Point this at a PR'scompose.ymland it reads the windows off the diff.Three details that decided the design, each found by it being wrong first:
plausible/analytics→ghcr.io/plausible/community-edition. Keyed by repo, that reads as one image vanishing and an unrelated one appearing — and the app window, the one carrying the criticalCVE-2026-8467, is lost entirely. My first cut did exactly that and reported 0.main, because several coopcloud recipes keep a stalemainbeside a livemaster.clickhouse/clickhouse-servervsClickHouse/ClickHouse) and sometimes shorter (redisvsredis/redis). One-directional matching silently dropped the clickhouse window — the scan said 1 instead of 6.Credentials go in an
Authorizationheader, never the URL: in-URL creds leak into shell history and process lists, and urllib mis-parses a password containing a colon.--from/--to/--imagestay for finer-grained checks — scanning a window that is not a literal compose diff, e.g. "what would the compatibility-safe target fix?".71 tests (7 new covering the derivation, incl. the changed-repo and templated-tag cases). Regressions unchanged: discourse 140, gitea 2, mailu 2. SPEC updated.
Typing --from/--to/--image by hand means someone has to remember the recipe also bumped its redis. That is how sidecar CVEs went uncounted for months. Point this at a PR's compose.yml and it reads the windows off the diff instead. advisory-scan.py plausible --compose-to <.../branch/<pr>/compose.yml> -> community-edition: v2.0.0 -> v3.2.1 -> clickhouse-server: 23.4.2.11-alpine -> 24.12-alpine -> 6 CVEs, identical to the hand-specified args Details that mattered: - keyed by SERVICE, not image repo. plausible moved plausible/analytics -> ghcr.io/plausible/community-edition; keyed by repo that reads as one image vanishing and an unrelated one appearing, and the app window - the one carrying the critical - is lost entirely. - the baseline is the repo's DEFAULT BRANCH resolved from the API, never assumed to be main, because several recipes keep a stale main beside a live master. - image names are matched against advisory sources BOTH ways: an image name is often longer than its source repo (clickhouse/clickhouse-server vs ClickHouse/ClickHouse) and sometimes shorter (redis vs redis/redis). One direction silently dropped the clickhouse window. - credentials go in an Authorization header, never the URL: in-URL creds leak into shell history and process lists, and urllib mis-parses a password containing a colon. --from/--to/--image remain for finer-grained checks (scanning a window that is not a literal compose diff). 71 tests; discourse 140 / gitea 2 / mailu 2 unchanged.