Skip to content

chore(docker): bump caddy from 198d47e to c7ae802 - #382

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/docker/caddy-c7ae802
Closed

chore(docker): bump caddy from 198d47e to c7ae802#382
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/docker/caddy-c7ae802

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 17, 2026

Copy link
Copy Markdown
Contributor

Bumps caddy from 198d47e to c7ae802.

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps caddy from `198d47e` to `c7ae802`.

---
updated-dependencies:
- dependency-name: caddy
  dependency-version: 2.11.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file docker Pull requests that update Docker base images labels Aug 17, 2026
@dependabot
dependabot Bot requested a review from Cre-eD as a code owner August 17, 2026 09:28
@dependabot dependabot Bot added the docker Pull requests that update Docker base images label Aug 17, 2026
@github-actions

Copy link
Copy Markdown

Semgrep Scan Results

Repository: api | Commit: e15e34d

Check Status Details
⚠️ Semgrep Warning 1 warning(s), 5 total

Scanned at 2026-08-17 09:28 UTC

@github-actions

Copy link
Copy Markdown

Security Scan Results

Repository: api | Commit: e15e34d

Check Status Details
✅ Secret Scan Pass No secrets detected
⚠️ Dependencies (Trivy) High 0 high, 3 total
⚠️ Dependencies (Grype) High 2 high, 3 total
📦 SBOM Generated 523 components (CycloneDX)

Scanned at 2026-08-17 09:29 UTC

@github-actions

Copy link
Copy Markdown

📊 Statement coverage

Measured on the documented included set (see docs/TESTING.md → Coverage scope). Observe-only — no regression gate is enforced yet.

Scope This PR main baseline Δ
Included set (Gold-tier denominator) 90.3% 90.3% +0.0 pp
Full set (whole repo, transparency) 28.5% 28.5% +0.0 pp

Baseline: main @ 3071875

@Cre-eD

Cre-eD commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Superseded by #387. The runtime digest here (df7f1c2f) is the same one #387 pins, but the builder digest is stale: c7ae802 was the 2.11.4-builder index at the time this PR opened (2026-08-17), and the tag was rebuilt on 2026-08-19/20. Current:

$ docker buildx imagetools inspect caddy:2.11.4-builder
Digest: sha256:4bdeabce8e79d36b23d1cba7d20598cec2c1117ace960d8ca06071f945e8fc9b

That rebuild is not cosmetic — it is the whole point of the refresh:

198d47e (pinned on main)  -> go version go1.26.5
4bdeabce (current tag)    -> go version go1.26.7

xcaddy build in the builder stage produces the binary COPY --from=builder puts into the runtime image, so the builder's toolchain is the shipped binary's stdlib. Moving to the 1.26.7 builder closes 8 stdlib CVEs in usr/bin/caddy (CVE-2026-33818, -39821, -46600, -56853, -56858, -56859, -56860, -56862).

#387 pins both digests and additionally lifts Caddy's own vendored x/net, x/text and grpc via xcaddy --replace. Measured with docker build --no-cache on both sides: 11 HIGH + 1 MEDIUM → 1 MEDIUM. Closing this one.

@Cre-eD Cre-eD closed this Aug 21, 2026
@dependabot @github

dependabot Bot commented on behalf of github Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

OK, I won't notify you again about this release, but will get in touch when a new version is available. If you'd rather skip all updates until the next major or minor version, let me know by commenting @dependabot ignore this major version or @dependabot ignore this minor version. You can also ignore all major, minor, or patch releases for a dependency by adding an ignore condition with the desired update_types to your config file.

If you change your mind, just re-open this PR and I'll resolve any conflicts on it.

@dependabot
dependabot Bot deleted the dependabot/docker/caddy-c7ae802 branch August 21, 2026 07:28
Cre-eD added a commit that referenced this pull request Aug 21, 2026
…e to 90.5 % (#387)

## Summary

Closes every fixable dependency vulnerability in the repo across all
severities, and lifts included-set statement coverage over the Gold-tier
bar it was documented as already meeting.

| | before | after |
|---|---|---|
| **OpenSSF Scorecard `Vulnerabilities`** | 3 advisories
(`GO-2026-6238`, `GO-2026-6179`, `GO-2026-6180`) | **0** |
| `osv-scanner` on `go.mod` | 3 (2 packages) | **0** |
| `trivy fs` | 2 HIGH + 1 LOW | **0** |
| Dependabot open alerts | 1 (LOW) | closes on merge |
| `simplecontainer/caddy` image | 11 HIGH + 1 MEDIUM | **1 MEDIUM** |
| `simplecontainer/cloud-helpers` image | 8 HIGH | **0** |
| `simplecontainer/github-actions` image | 17 HIGH | unchanged (upstream
binaries) |
| `simplecontainer/kubectl` image | 14 HIGH + 3 MEDIUM | unchanged
(upstream binary) |
| Included-set statement coverage | 89.6 % | **90.5 %** |

Deferred: 1 (cel-go, needs an upstream Caddy code change). Documented
unfixable: 4 classes, all upstream-owned binaries.

The Scorecard `Vulnerabilities` check was the trigger, and all three
advisories it reported land on **dev-tool-only** dependencies (`delve`
and `gofumpt` via `tools.go`) — `go list -deps ./...` links **zero**
packages from either module into anything we ship. They are still fixed
rather than VEX'd, because a fix exists upstream and is non-breaking;
VEX is for findings that cannot be fixed.

## Fixed

### Go modules

| Package | Old → New | Advisory | Sev | Reported by |
|---|---|---|---|---|
| `golang.org/x/mod` | v0.38.0 → **v0.40.0** | `GO-2026-6179` /
`CVE-2026-56865` — tlog tile verification bypass | HIGH | Scorecard,
osv-scanner, trivy fs |
| `golang.org/x/mod` | v0.38.0 → **v0.40.0** | `GO-2026-6180` /
`CVE-2026-56864` — unauthenticated hashes honoured in `sumdb.Lookup` |
HIGH | Scorecard, osv-scanner, trivy fs |
| `github.com/cilium/ebpf` | v0.11.0 → **v0.22.0** | `GO-2026-6238` /
`CVE-2026-10722` / `GHSA-xhgw-qwwf-pg32` — integer overflow in BTF
parsing | LOW | Scorecard, osv-scanner, trivy fs, Dependabot |

Neither could be fixed by bumping its parent: `mvdan.cc/gofumpt` v0.11.0
(latest) still requires `x/mod` v0.38.0, and `go-delve/delve` v1.27.1
(latest) still requires `cilium/ebpf` v0.11.0. Both are therefore raised
by an explicit indirect requirement.

MVS collateral, no advisory of its own, listed for review completeness:

`golang.org/x/crypto` v0.54.0 → v0.55.0 · `golang.org/x/net` v0.57.0 →
v0.58.0 · `golang.org/x/text` v0.40.0 → v0.41.0 · `golang.org/x/tools`
v0.48.0 → v0.49.0 · `golang.org/x/exp/typeparams` ·
`golang.org/x/telemetry` · `github.com/sirupsen/logrus` v1.9.3 → v1.9.4

### `caddy.Dockerfile` — 11 HIGH closed

Two independent causes, both fixed:

1. **Builder digest refresh** `198d47e` → `4bdeabce` (same
`2.11.4-builder` tag, rebuilt 2026-08-20). The pinned digest carried
**Go 1.26.5**; the current one carries **Go 1.26.7**. Since `xcaddy
build` in the builder stage produces the binary that `COPY
--from=builder` puts into the runtime image, the builder's toolchain
*is* the shipped binary's stdlib — this alone closed 8 stdlib CVEs
(`CVE-2026-33818`, `-39821`, `-46600`, `-56853`, `-56858`, `-56859`,
`-56860`, `-56862`). Runtime digest refreshed alongside it (`844f60b6` →
`df7f1c2f`) so builder and runtime stay on the same tag push.
2. **Three `xcaddy --replace` directives** lifting Caddy 2.11.4's own
vendored deps past `CVE-2026-46600` (`x/net` → v0.58.0),
`CVE-2026-56852` (`x/text` → v0.41.0) and `GHSA-hrxh-6v49-42gf` (`grpc`
→ v1.82.1). `--replace` and not `--with`: `--with` also writes a blank
import, and none of these modules has a package at its module root, so
it fails with `cannot find module providing package`.

The Dockerfile's existing build-time gates (`caddy version | grep`,
`caddy list-modules | grep` for `rate_limit` and `storage.gcs`) all
still pass, so a silently dropped plugin or a version skew would have
failed the build.

### `cloud-helpers.aws.Dockerfile` — 8 HIGH closed, image now clean

Every finding in this image came from `/usr/local/bin/aws-lambda-rie`,
the base image's **local-testing** Runtime Interface Emulator: 9 MB of
Go that AWS builds with an older toolchain (Go 1.26.5 at the pinned
digest → 8 HIGH, all fixed in Go ≥ 1.26.6).

It is not reachable in this image. `/lambda-entrypoint.sh` execs it only
when `AWS_LAMBDA_RUNTIME_API` is unset, and our `ENTRYPOINT
["/cloud-helpers"]` replaces that script outright. Nothing links it and
no workflow invokes it — `welder run debug-aws-cloud-helpers` is `runOn:
host` and uses the **host's** `aws-lambda-rie`, not the image's copy. So
it is deleted, which is a fix rather than a suppression.

What this removes is `docker run --entrypoint /lambda-entrypoint.sh
<image> /cloud-helpers`; the welder task is the supported path. Verified
after the change: the image scans clean **and** `/cloud-helpers` still
starts (it exits with the expected "did you pass
SIMPLE_CONTAINER_CLOUD_HELPER_TYPE" error).

### `honnef.co/go/tools` pinned to v0.6.1 via `replace`

`cilium/ebpf` v0.22.0 names `honnef.co/go/tools` v0.7.0 in its own
`go.mod`, so MVS raises it. `golangci-lint` v1.64.8 does not compile
against v0.7.0's analysis API and **panics mid-run**, exit 7:

```
typedness: panic during analysis: interface conversion: interface {} is nil, not *buildir.IR
  honnef.co/go/tools@v0.7.0/analysis/facts/typedness/typedness.go:59
```

That fails the `golangci-lint run` step in `branch.yaml` / `push.yaml` /
`branch-preview.yaml`. ebpf needs staticcheck for *its* CI, not for any
code we compile, and v0.22.0 is the fix for `GO-2026-6238` so it cannot
be held back — and a `require` line loses to ebpf's, so only `replace`
pins it. `honnef.co/go/tools` v0.6.1 carries no advisories (checked
against osv.dev). Removal condition is in the go.mod comment:
golangci-lint v2 builds against v0.7.x, but that is a separate migration
(module path rename + `.golangci.yml` schema change).

**This is the reason to supersede Dependabot #385 rather than merge it**
— #385 makes exactly this bump and would have broken lint on `main` on
its own.

## Deferred (breaking change, needs upstream)

**`GHSA-gcjh-h69q-9w9g` — `github.com/google/cel-go` v0.28.1 → v0.29.0,
MEDIUM, inside the shipped `caddy` binary.**

Not a version bump: v0.29.0 renames `interpreter.Interpretable` to
`InterpretableV2`, and Caddy 2.11.4's `modules/caddyhttp/celmatcher.go`
does not compile against it. Verified by attempting it:

```
caddy/v2@v2.11.4/modules/caddyhttp/celmatcher.go:506:5: cannot use []interpreter.Interpretable{…}
  (value of type []interpreter.Interpretable) as []interpreter.InterpretableV2 value in argument to interpreter.NewCall
caddy/v2@v2.11.4/modules/caddyhttp/celmatcher.go:529:5: (same)
```

**Reachability**: cel-go backs Caddy's `expression` request matcher.
SC's generated Caddyfiles never emit `expression` (0 occurrences across
the Caddyfile templates in `pkg/clouds/pulumi/kubernetes/`), so the CEL
evaluator is only reachable if a consumer writes one by hand into
`lbConfig.extraHelpers` / `siteExtraHelpers`. **Closing condition**: a
Caddy release that adopts cel-go ≥ 0.29.0 — then drop this note and
rebuild. Deliberately called out in a `caddy.Dockerfile` comment so the
next digest refresh does not silently add it to the `--replace` list and
break the build.

## Documented unfixable (upstream-owned binaries, no action available)

1. **`alpine/kubectl` → `/usr/local/bin/kubectl`** — 8 HIGH
`stdlib@v1.26.5`, 5 HIGH + 3 MEDIUM `x/net@v0.49.0`, 1 HIGH
`x/text@v0.33.0`. kubectl is built by the Kubernetes release process; we
cannot rebuild it. Refreshing the digest gains nothing and was measured,
not assumed: the pinned digest `5d380d18` and the current `latest`
(`dae26110`, = tag `1.36.3`) are **both kubectl v1.36.3** and produce
**identical** finding counts, so the pin is left alone rather than
churned. The Dockerfile's `apk upgrade` already clears **all**
OS-package findings (0 alpine findings on a fresh build). Closing
condition: a Kubernetes patch release rebuilt with Go ≥ 1.26.6, then
refresh the digest.
2. **Google Cloud SDK binaries in `github-actions`** — 8 HIGH in
`gcloud-crc32c` (`stdlib@v1.26.5`) and 9 HIGH in
`gke-gcloud-auth-plugin` (8 × `stdlib@v1.26.5` + `x/text@v0.38.0` /
`CVE-2026-56852`). That is the image's *entire* finding set: base OS
packages scan 0 and `root/github-actions` scans 0.
`gke-gcloud-auth-plugin` is fetched by `gcloud components install` at
build time, so it is already the freshest version Google publishes.
Bumping the pin does **not** help, also measured rather than assumed:
`GCLOUD_VERSION` 579.0.0 (pinned) and 581.0.0 (latest) both ship
`gcloud-crc32c` built with **go1.26.5** (`go version` on the extracted
binaries). The pin stays at 579.0.0 and its `GCLOUD_SHA256` was
re-verified correct against a fresh download. *Reachability*:
`gcloud-crc32c` is a checksum helper for `gcloud storage` / gsutil
transfers, and no SC code path shells out to either (0 matches for
`gsutil` across `pkg/`; GCP static-site uploads go through the Pulumi
SDK's `storage.BucketObject`). Not deleted the way the Lambda RIE was,
because a consumer-authored deploy hook *can* invoke `gcloud storage`,
so the execute path is not provably empty. Candidate for an image-scope
VEX statement once this repo has a convention for one — today
`vex/openvex.json` covers Go-module advisories only.
3. **`public.ecr.aws/lambda/provided:al2023` digest is deliberately NOT
refreshed.** The currently-tagged digest is **worse** than the pinned
one: 30 HIGH vs 8. Anyone rebasing a Dependabot docker-digest bump onto
this image should check the scan before taking it.
4. **`GO-2026-5932`** (`golang.org/x/crypto/openpgp` unmaintained) —
unchanged `not_affected`, re-triaged below.

## VEX re-triage

All three statements in `vex/openvex.json` re-checked against the
current tree this pass; document bumped to `version: 4`, `timestamp:
2026-08-21`. No statement flipped, and each was **re-confirmed with
fresh evidence** rather than carried forward by default:

| Advisory | Status | This pass |
|---|---|---|
| `GO-2022-0635` (aws-sdk-go v1 s3crypto) | `not_affected` /
`component_not_present` | **Re-confirmed.** Still 0 matches in `go.mod`
and `go.sum`; `go mod why -m` still reports "main module does not need";
`go list -m all` still resolves v1.55.8 only through a transitive
`go.mod`. |
| `GO-2022-0646` (same module) | `not_affected` /
`component_not_present` | **Re-confirmed**, same evidence. |
| `GO-2026-5932` (x/crypto/openpgp) | `not_affected` /
`vulnerable_code_not_present` | **Re-confirmed.** `go list
-buildvcs=false -deps ./...` still links 24 `x/crypto` packages and
**0** `openpgp` packages; OpenPGP still goes through
`ProtonMail/go-crypto`; no fix event upstream (`introduced: 0`,
permanent "unmaintained" notice). Impact statement updated for the
`x/crypto` v0.54.0 → v0.55.0 bump in this PR. |

`osv-scanner.toml` needs no change: its single mirrored entry
(`GO-2026-5932`) is still the only one of the three that osv-scanner
actually reports, and it still filters correctly (`Filtered 1
vulnerability from output`). No new suppressions were added anywhere —
no `.trivyignore`, no new VEX statement, no new `IgnoredVulns` entry.

## Coverage: 89.6 % → 90.5 %

`docs/TESTING.md` claimed the Gold-tier `test_statement_coverage90`
criterion was **Met**. It was not: the `main` baseline artifact reads
`included=89.6`, reproduced exactly locally. This PR closes the gap and
makes the doc honest — the status column now carries the number, so the
next drift is visible.

The included set is 5,975 statements, so 90 % needed 29 more covered
statements. Seven test files add ~60, all of them exercising real logic
with assertions that fail on a real regression rather than padding the
denominator:

| Test | What it guards |
|---|---|
| `pkg/security/tools/cosigntest/cosigntest_test.go` **(new, 208
lines)** | The whole package was at **0 %** — see below. |
| `pkg/clouds/gcloud/auth_test.go` | `ReadSecretsProviderConfig` must
reject a bad `keyRotationPeriod` **at read time** (4 shapes), and must
ignore it when `provision: false`. This is the contract the function's
own comment describes: an already-provisioned secrets-provider stack is
skipped by the provisioner, so a provisioner-only check never runs and a
bad value would surface at a DR rebuild. Plus
`EffectiveNoncurrentVersionRetentionDays` — nil means "apply the 30-day
default", explicit zero means "disable the rule"; collapsing the two
would silently drop the rollback horizon on every state bucket that
never set the field. |
| `pkg/clouds/compose/compose_test.go` | An absolute `composeFilePath`
must re-root `workingDir` onto the file's own directory (relative build
contexts resolve against `workingDir`, so honouring the caller's would
point them at the wrong tree); `${VAR}` interpolation must still read
the process env under `SkipResolveEnvironment`; a missing file must not
return a half-built project. |
| `pkg/clouds/fs/fs_state_test.go` | `init()`'s two registrations,
asserted **through `api.ReadProvisionerFieldConfig`** — the same lookup
the descriptor reader uses. A typo'd key or a reader wired to the wrong
struct otherwise only shows up as `unknown provisioner field config
type` at read time. |
| `pkg/clouds/docker/types_test.go` | `RegistryRequiresAuth` gates
whether an imagePullSecret is generated at all:
username-without-password must read as "no auth" rather than produce a
half-formed secret, while both-present-but-empty must still count as
"auth requested" so the deploy fails on a bad credential instead of
silently pulling anonymously. |
| `pkg/clouds/cloudflare/cloudflare_test.go` | `ReadRegistrarConfig`
happy + error path, including that `dnsRecords` survives the yaml
round-trip `ConvertConfig` performs. |
| `pkg/clouds/mongodb/mongodb_test.go` | `ReadAtlasConfig` happy + error
path, with the `*float64` / `*int` fields asserted specifically: they
distinguish "unset" from "explicitly zero" and must survive the
round-trip, and unset ones must stay nil so downstream defaults apply. |

### Why `cosigntest` got tests instead of an exclusion

`pkg/security/tools/cosigntest` was the single largest uncovered block
in the included set (42 statements, 0 %) because Go attributes coverage
per test binary, and this package is a harness consumed only by *other*
packages' tests (`pkg/security/provenance`, `pkg/security/sbom`).

Adding it to the `pkg/util/test/*` exclusion category would have been
the cheap way to clear the number, and it would have been wrong. The 0 %
is a real gap: the package generates a `/bin/sh` script, and three retry
suites silently depend on its shell quoting, its cross-process
invocation counter, and which stream it writes the Rekor conflict marker
to. A break there turns those suites green for the wrong reason. So the
new tests drive the stub through **`tools.ExecCommand`** — the exact
function `signing.RunCosignWithRetry` calls — so stdout and stderr stay
separated the way they do in production, and they include:

- the `ConflictOnStdout` case asserting stderr is **non-empty but does
not contain the marker**, so a stdout-classification bug cannot pass
because the marker leaked onto both streams;
- a `FailStderr` body containing a single quote — the exact input that
broke an earlier harness by terminating the generated script early;
- `shellQuote` round-tripped through `/bin/sh` itself, including a
metacharacter payload, because string equality alone would not catch a
quoting form the shell re-splits or expands;
- `DelayEach` vs `DelayFirst` asserted per invocation, which is what
distinguishes a fresh per-attempt timeout from one budget shared across
attempts;
- `RekorConflictStderr` checked against the `[POST
/api/v1/log/entries][409]` shape the retry classifier actually anchors
on, so a drifted fixture cannot quietly stop exercising the retry path.

`docs/TESTING.md` records why it is *not* excluded, next to the
exclusion table.

## Also in this PR

`pkg/clouds/aws/helpers/ct_enrichment_test.go` — two `staticcheck`
`SA1012` findings (never pass a nil `Context`) that surface on this
branch but not on `main`. Fixed properly rather than silenced: the cases
assert that `lookupTriggeringEvents` short-circuits **before** any AWS
call, so they now pass an already-cancelled context instead of `nil` — a
regression that stops short-circuiting fails with `context.Canceled`
instead of reaching the network.

**Pre-existing lint drift, deliberately left alone:** `golangci-lint run
--fix` (the exact CI invocation) rewrites 19 unrelated files on `main`
today — `gci` import ordering plus missing `goheader` SPDX headers in
`pkg/api/secrets/ciphers/x25519.go`, `x25519_test.go` and
`pkg/clouds/pulumi/aws/permissions_boundary.go`. CI is green because
`--fix` repairs them in the workspace and never commits them. Worth a
separate cleanup PR; folding 19 files of import churn into an SCA diff
would only make this one harder to review.

## Dependabot reconciliation

| PR | Action |
|---|---|
| **#385** `bump github.com/cilium/ebpf 0.11.0 → 0.22.0` | **Superseded
— close.** Same bump, plus the honnef/golangci-lint fallout it would
have hit alone (see above). |
| **#382** `bump caddy from 198d47e to c7ae802` | **Close or rebase.**
Already stale: the `caddy` tags were rebuilt 2026-08-20 and this PR pins
the resulting digests directly (`4bdeabce` builder / `df7f1c2f`
runtime), so #382 conflicts and targets an older push. |
| #380 `github-actions group`, #381 `reecetech/version-increment`, #378
`node 22-alpine → 26-alpine` | Left open. Separate docker / actions
version stream per `.github/dependabot.yml`; no overlap with this diff.
|

Open Dependabot **alerts**: 1 (`github.com/cilium/ebpf`, LOW, fix
0.22.0). Closes automatically once this lands on `main`. The two `x/mod`
advisories never opened an alert — Dependabot did not surface them —
which is precisely why the Scorecard / osv-scanner / trivy cross-check
matters and why alert state alone is not the source of truth.

`.github/dependabot.yml` needs no change: both language ecosystems
(`gomod` at `/`, `pip` at `/docs`) and both version ecosystems
(`docker`, `github-actions`) are already configured.

## Evidence

<details>
<summary>Source scans, before → after</summary>

```
# osv-scanner scan source --lockfile=go.mod     (the scanner OpenSSF Scorecard uses)
BEFORE  github.com/cilium/ebpf@0.11.0   GO-2026-6238, GHSA-xhgw-qwwf-pg32
        golang.org/x/mod@0.38.0         GO-2026-6179, GO-2026-6180
        (+ GO-2026-5932 filtered by osv-scanner.toml)
AFTER   CLEAN
        (+ GO-2026-5932 filtered by osv-scanner.toml — still the only mirrored entry)

# trivy fs --severity CRITICAL,HIGH,MEDIUM,LOW
BEFORE  HIGH  golang.org/x/mod@v0.38.0      CVE-2026-56864   fix=0.40.0
        HIGH  golang.org/x/mod@v0.38.0      CVE-2026-56865   fix=0.40.0
        LOW   github.com/cilium/ebpf@v0.11.0 CVE-2026-10722  fix=0.22.0
AFTER   CLEAN   (0 findings; docs/requirements.txt also 0)

# reachability of the two fixed modules — neither links into anything we ship
go list -buildvcs=false -deps ./... | grep -c '^golang.org/x/mod'        -> 0
go list -buildvcs=false -deps ./... | grep -c '^github.com/cilium/ebpf'  -> 0
```
</details>

<details>
<summary>Image scans — built locally from this branch vs from
origin/main</summary>

Both sides built from the same Dockerfiles at the same moment, so this
is apples to apples rather than a comparison against the published
`:latest` tags (which lag the current Dockerfiles and are much worse —
caddy 178 findings, cloud-helpers 72, github-actions 151, kubectl 92;
the next release build closes that gap regardless).

All four images rebuilt with `docker build --no-cache`. That matters: a
first pass reported 48 phantom `python3` findings in `github-actions`
because BuildKit reused a cached `apk update && apk upgrade && apk add`
layer (the layers came into the local store from pulling the published
image for the "before" scan), so the image kept `python3 3.14.5-r0`
while `alpine v3.24/main` already served `3.14.7-r1`. Fresh builds — and
CI runners — install the current package. Worth knowing before trusting
any local image scan in this repo.

```
caddy — docker build -f caddy.Dockerfile
  origin/main   HIGH=11 MEDIUM=1
                x/net@v0.55.0     CVE-2026-46600
                x/text@v0.37.0    CVE-2026-56852
                grpc@v1.81.0      GHSA-hrxh-6v49-42gf
                stdlib@v1.26.5    CVE-2026-33818 -39821 -46600 -56853 -56858 -56859 -56860 -56862
                cel-go@v0.28.1    GHSA-gcjh-h69q-9w9g  (MEDIUM)
  this branch   MEDIUM=1
                cel-go@v0.28.1    GHSA-gcjh-h69q-9w9g  <- deferred, upstream-breaking
  gates:        caddy version -> v2.11.4 ; http.handlers.rate_limit + caddy.storage.gcs present
  OS packages:  0 both sides (apk upgrade already handled it)

cloud-helpers — docker build -f cloud-helpers.aws.Dockerfile
  origin/main   HIGH=8      all in usr/local/bin/aws-lambda-rie (stdlib@v1.26.5)
  this branch   0 findings  amazon OS 0 ; /cloud-helpers 0 ; RIE removed
  smoke:        /cloud-helpers starts (exits on missing SIMPLE_CONTAINER_CLOUD_HELPER_TYPE)

kubectl — docker build -f kubectl.Dockerfile
  this branch   HIGH=14 MEDIUM=3   all in usr/local/bin/kubectl (upstream)
                alpine OS packages: 0
  digest check  pinned 5d380d18 and latest dae26110 are both kubectl v1.36.3,
                identical finding counts -> pin left alone

github-actions — docker build -f github-actions.Dockerfile
  this branch   HIGH=17     alpine OS 0 ; root/github-actions 0
                gcloud-crc32c            8 HIGH  stdlib@v1.26.5      (upstream)
                gke-gcloud-auth-plugin   9 HIGH  stdlib@v1.26.5 + x/text@v0.38.0  (upstream)
  unchanged vs origin/main — neither the alpine base nor the gcloud pin moved,
  and our binary scans 0 on both sides.
  smoke:        pulumi version / gcloud version / gke-auth-plugin present /
                aws --version / sc symlink all pass in-build

our own Go binaries, scanned directly (trivy rootfs + grype --only-fixed)
  dist/github-actions   go1.26.6   trivy 0 / grype 0
  dist/cloud-helpers    go1.26.6   trivy 0 (in-image scan)
```
</details>

<details>
<summary>Coverage</summary>

```
# main baseline (coverage.yml artifact, run 32352899068, sha ec0f628)
included=89.6
full=28.9

# this branch, same filter as coverage.yml / welder.yaml
included: 90.5%
full:     29.0%

# gap arithmetic
included set = 5,975 statements ; 5,348 covered = 89.506%
90.0% needed +29 covered statements ; this PR adds ~60
```
</details>

## Test plan

- `go build ./...` — passes (locally with `-p 2`; the `pulumi-gcp` /
`pulumi-aws` SDK packages want several GB per compile process, so full
parallelism OOMs on a 19 GB machine).
- `go test ./...` — passes except one pre-existing, environment-only
failure:
`TestDetectRootDir/WithDetectRootDir_errors_when_no_git_repo_is_found_above_cwd`.
It asserts that `WithDetectRootDir()` errors when no git repo exists
above `cwd`, and this machine has a `.git` above every temp dir
(`/home/creed/.git`, plus a stray `/tmp/.git` from an unrelated
worktree). Untouched by this PR — no file under `pkg/api/git/` is in the
diff — and CI runners have neither, so `Run tests` should be green.
- `golangci-lint run --fix --timeout 20m` (the CI invocation) — **exit
0**.
- `bin/gofumpt -l` — clean on every file in this diff.
- `go build` of all five `tools.go` targets against the bumped deps —
`dlv` (the risky one: `cilium/ebpf` v0.11.0 → v0.22.0 is a 11-minor jump
and delve pins the old one), `gofumpt`, `golangci-lint`, `mockery`,
`go-jsonschema` — all build.
- `docker build` of `caddy.Dockerfile`, `cloud-helpers.aws.Dockerfile`,
`kubectl.Dockerfile`, `github-actions.Dockerfile` — all succeed, with
the in-Dockerfile smoke tests (`caddy version`, plugin greps, `pulumi
version`, `gcloud version`, gke-auth-plugin presence, `aws --version`,
`sc` symlink) passing.
- `govulncheck -mode=source ./...` — **not run locally**: it peaks
around 13.5 GB RSS on this module. The `govulncheck` workflow gates this
PR and scans unconditionally on a Go-touching diff, which this is.

## CI on this PR

All checks green: `Build Setup (clean, tools, schemas, lint, fmt)`, `Run
tests`, `govulncheck (reachability-aware)`, `Analyze Go (go)` / CodeQL,
`security / SBOM + Dependency Scan`, `security / Secret Scan`,
`semgrep`, `Measure statement coverage`, all five `Build *` jobs, and
`Fuzz HMAC cache parse path`.

Two notes for anyone reading the run history:

- `TestDetectRootDir` fails on my machine but passes in `Run tests`,
exactly as expected — the assertion needs a temp dir with **no** git
repo above it, and this laptop has one above every temp dir. Nothing
under `pkg/api/git/` is in the diff.
- `Fuzz HMAC cache parse path` failed on the first attempt and **passed
on re-run**. It was not a discovered crash: `FuzzCacheGetPath` reported
`context deadline exceeded` at exactly the 30.10 s `-fuzztime` boundary
and **no crash corpus was written** (`No files were found with the
provided path: pkg/security/testdata/fuzz/`), which is Go's fuzz
coordinator missing its shutdown grace period on a loaded runner.
Reproduced locally on this branch at 2.1 M execs — `PASS`, no corpus.
Nothing in `pkg/security` itself is in the diff; the only addition is a
test in the `pkg/security/tools/cosigntest` subpackage, which
`pkg/security` does not import.

The Scorecard `Vulnerabilities` check itself cannot run here —
`scorecard.yml` triggers on `push` to `main`, the weekly cron, and
`branch_protection_rule`, and the check queries osv.dev against the
default branch. It clears on the next `main` push after merge. The same
scanner (`osv-scanner scan source --lockfile=go.mod`, with
`osv-scanner.toml` applied) is what reports **0** in the evidence above.

Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file docker Pull requests that update Docker base images

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant