feat: lock and verify external NGINX artifacts - #11
Conversation
Approve the official NGINX stable channel and select `nginx-2:1.30.4-1.el9.ngx` as the first-release implementation and qualification candidate. Add reviewed AMD64 and ARM64 artifact locks covering the selected RPM, its complete 79-package dependency closure, 59 source RPMs, sizes, SHA-256 values, the actual signer fingerprint, and the digest-pinned base images. Add the explicit lock-update path and atomic official and alternate-source acquisition with inventory, digest, signature, signer, NEVRA, architecture, and lock-manifest verification. Source maps, credentials, and private CA material stay outside the repository and the image build. The Containerfile still resolves RPMs in the builder stage; migrating it to the verified bundle is the next increment.
…s-and-acquisition # Conflicts: # CHANGELOG.md
Regenerate both architecture locks against the refreshed UBI 9.8 Minimal and Micro base digests so the locked closure carries `openssl-1:3.5.8-1.el9_8` from RHSA-2026:67165, which addresses CVE-2026-14456. Reviewed diff, identical on both architectures: openssl 1:3.5.5-6.el9_8 -> 1:3.5.8-1.el9_8 openssl-libs 1:3.5.5-6.el9_8 -> 1:3.5.8-1.el9_8 systemd 0:252-67.el9_8.4 -> 0:252-67.el9_8.6 systemd-libs 0:252-67.el9_8.4 -> 0:252-67.el9_8.6 systemd-pam 0:252-67.el9_8.4 -> 0:252-67.el9_8.6 systemd-rpm-macros 0:252-67.el9_8.4 -> 0:252-67.el9_8.6 The systemd rebuild arrived with the refreshed base and was not the reason for the refresh. No package was added or removed, the 79-package closure and 59 source packages keep the same shape, both architectures resolve identical versions, the NGINX package is unchanged at 1.30.4-1.el9.ngx, and no signing identity changed. Resolution ran in a clean networked UBI 9 container per the lock-refresh procedure. Resolver output was not committed.
|
Rebuilt on current Why the locks changed. They pinned Reviewed lock diff (step 6 of
Resolution ran in a clean networked UBI 9 container; resolver output was not committed. |
Closes the first three Package 2 roadmap items: approve the package channel,
add reviewed architecture locks, and add verified acquisition.
What this adds
nginx-2:1.30.4-1.el9.ngxselected as the first-release implementation and qualification candidate.
Reviewed against authoritative NGINX sources on 2026-09-12, including the
security-advisory index. The selection does not freeze release inputs.
artifacts/locks/amd64.jsonandarm64.jsonpin theselected RPM, its complete 79-package installation closure, 59 source RPMs,
sizes, SHA-256 values, the actual signer fingerprint, and the builder and
runtime manifest-list digests. Schema in
artifacts/artifact-lock.schema.json, reviewed inputs inartifacts/lock-inputs.json.fetch-lock-inputs.py(HTTPS-only, approved hosts,reviewed SHA-256),
resolve-lock.sh(independent inventory, hash,fingerprint, signature, NEVRA, architecture, closure, and source-RPM checks),
and
render-lock.py(maps the observed signing key ID to exactly oneapproved fingerprint, fails closed on inconsistent output).
artifacts.py acquirepublishes atomically and refuses toreplace an existing output directory.
verify-rpm-bundle.shperformsRPM-level verification before the bundle is exposed to any build.
--source-mapaccepts an external JSON map with--token-envand--ca-bundle. URLs with credentials, query strings, orfragments are rejected; redirects must stay on the original HTTPS host;
source URLs and tokens are never printed on error. Maps, credentials, and
private CA material stay outside this repository and the build context.
Notes for review
(
8540 A6F1 ... B49F 6B46) differs from the older fingerprint in NGINX'spublished install instructions. The locks accept the actual signer
specifically rather than trusting every certificate in the downloaded
bundle. See
docs/PACKAGE-SOURCE.md.Containerfilestill resolves RPMs in the builder stage. Migrating itto consume the verified bundle is the next increment and is deliberately
kept out of this PR.
Verification
python -m unittest tests.test_artifacts -v(11 tests) now runs in the lintjob. Lock validation commands documented in the README and acquisition guide
were executed against both architecture locks.
🤖 Generated with Claude Code