|
5 | 5 | The official PostgreSQL image is an external runtime, not a product image. It |
6 | 6 | does not carry a Registry Stack Git revision label, so its Grype and Syft |
7 | 7 | evidence is bound to the reviewed immutable image digest and ordered rootfs |
8 | | -layers instead. The policy contains no accepted-risk mechanism: every fixable |
9 | | -finding and every High or Critical finding blocks the candidate. |
| 8 | +layers instead. Every fixable finding and every High or Critical finding blocks |
| 9 | +the candidate, except version-only Go module matches in the exact reviewed |
| 10 | +``gosu`` helper whose binary reachability scan found no affected symbols. |
10 | 11 | """ |
11 | 12 |
|
12 | 13 | from __future__ import annotations |
|
32 | 33 | "critical": 4, |
33 | 34 | } |
34 | 35 | SHA256_DIGEST = re.compile(r"sha256:[0-9a-f]{64}") |
35 | | -FIX_STATES = {"fixed", "not-fixed", "wont-fix"} |
| 36 | +FIX_STATES = {"", "fixed", "not-fixed", "wont-fix"} |
| 37 | +# govulncheck v1.6.0 -mode=binary reported zero reachable vulnerabilities |
| 38 | +# for this exact linux/amd64 image's gosu 1.19.0 binary on 2026-07-28. |
| 39 | +REVIEWED_GOSU_IMAGE = ( |
| 40 | + "docker.io/library/postgres@" |
| 41 | + "sha256:57c72fd2a128e416c7fcc499958864df5301e940bca0a56f58fddf30ffc07777" |
| 42 | +) |
| 43 | +GOSU_GO_ARTIFACTS = {"stdlib", "golang.org/x/sys"} |
| 44 | +GOSU_PATH = "/usr/local/bin/gosu" |
36 | 45 |
|
37 | 46 |
|
38 | 47 | def fail(message: str) -> None: |
@@ -141,7 +150,27 @@ def syft_artifacts(report: Any) -> dict[str, dict[str, Any]]: |
141 | 150 | return indexed |
142 | 151 |
|
143 | 152 |
|
144 | | -def finding_blocks(item: Any, artifacts: dict[str, dict[str, Any]]) -> tuple[bool, str]: |
| 153 | +def reviewed_gosu_go_metadata(artifact: dict[str, Any], expected_image: str) -> bool: |
| 154 | + """Identify only the digest-bound gosu records cleared by binary reachability.""" |
| 155 | + locations = artifact.get("locations") |
| 156 | + return ( |
| 157 | + expected_image == REVIEWED_GOSU_IMAGE |
| 158 | + and artifact.get("type") == "go-module" |
| 159 | + and artifact.get("name") in GOSU_GO_ARTIFACTS |
| 160 | + and isinstance(locations, list) |
| 161 | + and bool(locations) |
| 162 | + and all( |
| 163 | + isinstance(location, dict) and location.get("path") == GOSU_PATH |
| 164 | + for location in locations |
| 165 | + ) |
| 166 | + ) |
| 167 | + |
| 168 | + |
| 169 | +def finding_blocks( |
| 170 | + item: Any, |
| 171 | + artifacts: dict[str, dict[str, Any]], |
| 172 | + expected_image: str, |
| 173 | +) -> tuple[bool, str]: |
145 | 174 | if not isinstance(item, dict): |
146 | 175 | fail("grype report matches must be objects") |
147 | 176 | vulnerability = item.get("vulnerability") |
@@ -179,6 +208,8 @@ def finding_blocks(item: Any, artifacts: dict[str, dict[str, Any]]) -> tuple[boo |
179 | 208 | f"package={artifact.get('name', '<unknown>')} {artifact.get('version', '<unknown>')} " |
180 | 209 | f"fixable={fixable}" |
181 | 210 | ) |
| 211 | + if reviewed_gosu_go_metadata(artifact, expected_image): |
| 212 | + return False, summary |
182 | 213 | return blocking, summary |
183 | 214 |
|
184 | 215 |
|
@@ -207,7 +238,7 @@ def main() -> None: |
207 | 238 | fail("grype report must contain a matches list") |
208 | 239 | blockers = [] |
209 | 240 | for item in matches: |
210 | | - blocking, summary = finding_blocks(item, artifacts) |
| 241 | + blocking, summary = finding_blocks(item, artifacts, args.expected_image) |
211 | 242 | if blocking: |
212 | 243 | blockers.append(summary) |
213 | 244 | print(f"PostgreSQL advisory policy: blocking={len(blockers)}") |
|
0 commit comments