Repository navigation
fix(sandbox): pin the Kali keyring instead of the drifting InRelease hash - #206
Merged
Merged
Conversation
…hash `kali-last-snapshot` is a rolling pointer that Kali re-signs on every archive refresh, so the pinned InRelease hash broke `Build and smoke-test sandbox image` on each re-sign (main 9c6b910). The archive publishes no immutable dated suite and snapshot.kali.org is not serving, so the index bytes cannot be pinned durably. The trust anchor is now the Kali keyring shipped by the digest-pinned base image, verified by content hash, with apt signature verification enforced fail-closed through 99lyrashield-signature-required. Package selection still pins the snapshot suite at Pin-Priority 1001 with --allow-downgrades. UPGRADES.md documents how to refresh the pin.
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
📒 Files selected for processing (3)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The deb line named no keyring, so apt authenticated the Kali index with whatever trusted key the image happened to carry while the build separately hashed /usr/share/keyrings/kali-archive-keyring.gpg. Name that exact file with [signed-by=...] in both stages so the keyring whose sha256 the build checks is the file apt is told to trust, and keep the fail-closed apt conf. Verified the later 'apt-get install -y kali-archive-keyring' does not disturb that file: kali-archive-keyring_2025.2_all.deb unpacks the same keyring at the same path with an identical sha256 (42a247ff...). A future package that rotated the key would fail closed at the post-install 'apt-get update'. tests/test_sandbox_dockerfile.py gains an invariant that every Kali deb line carries signed-by pointing at the hashed keyring path, proven load-bearing by two negative controls (option removed, option pointing elsewhere). UPGRADES.md records signed-by and the keyring-package check.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
Build and smoke-test sandbox imagefails on every engine PR and onmain(9c6b9102).containers/DockerfilepinnedKALI_APT_INRELEASE_SHA256=5bc9a9bf...against thekali-last-snapshotsuite. That suite is a rolling pointer: Kali re-signed itsInReleaseon 2026-10-08 01:58 UTC (now 33,968 B,sha256 c6fc6a6d...), so thesha256sum -c -step fails and will fail again on every future re-sign.Design chosen: pin the trust anchor, not the drifting bytes
The archive publishes no immutable dated suite —
archive.kali.org/kali/dists/lists nine suites and all are floating;kali-last-snapshotis the only snapshot suite, and it is refreshed in place. The dated-snapshot servicesnapshot.kali.orgreturns 502 on repeated attempts, so option (a) is not available.The durable anchor is the Kali keyring shipped by the digest-pinned base image:
kalilinux/kali-rolling@sha256:f4912486...is pinned by manifest-list digest, so its contents — includingusr/share/keyrings/kali-archive-keyring.gpg— are immutable.sha256 42a247ff5a26869e3739b6d3ad125938bb5da8e7bb43ed0791d2a190cd09c64fand holds key827C8569F2518CC677FECA1AED65462EC8D5E4C5.InReleaseverifies against that key (gpg --verify→ Good signature from "Kali Linux Archive Automatic Signing Key (2025)"), so the build now proves the keyring is the one Kali signs with, and apt then verifies the index against it.Enforced fail-closed in
/etc/apt/apt.conf.d/99lyrashield-signature-required:Nothing is weakened: no
[trusted=yes], no--allow-unauthenticated, no fallback to an insecure repository. The keyring hash check makes a substituted keyring fail the build; apt's own verification then makes an unsigned or wrong-key index fail the build. Package selection is unchanged — the snapshot suite stays pinned atPin-Priority: 1001with--allow-downgrades.upgradestill installskali-archive-keyring, so Kali key rotation continues to work without a code change.Trade-off of the rejected alternative
Option (a), an immutable dated suite pinned by hash, is strictly stronger — it freezes the package set as well as the index. It is unavailable: no such suite is published and the snapshot service is down. Had it existed, it would also have meant the sandbox silently stops receiving tool updates until someone refreshes the pin.
Option (b) as literally specified — verify against the pinned Kali archive keyring — is what shipped, with one correction:
gpgvis not present in the base image (only apt's internalgpgv/sqvmethods are), so the verification is done by apt itself rather than by a hand-rolledgpgvinvocation. That is the stronger placement: the check runs on everyapt-get updatein the image, not once in a Dockerfile step.The residual trade-off versus (a): the trust boundary is now Kali's signing key rather than a frozen byte string, so a Kali key compromise would be trusted. The previous hash pin had the same exposure — it verified a signature made by that same key — it just also happened to freeze one day's index bytes.
Changes
containers/Dockerfile— replace bothARG KALI_APT_INRELEASE_SHA256lines withARG KALI_APT_KEYRING_SHA256=42a247ff...; verify the keyring by content hash; add the fail-closed apt policy file.tests/test_sandbox_dockerfile.py— assert the InRelease pin is gone, both keyring pins match, the three fail-closed settings are present and--allow-unauthenticated/trusted=yesare absent.UPGRADES.md— refresh procedure for the pin.strix/**,ENGINE_REVISIONand.lyrashield-worker-pinare untouched;scripts/verify-controlled-derivative.shhas no Kali reference.Verification
tests/test_sandbox_dockerfile.py: 10/10 pass (executed directly; the module has no pytest dependency).KALI_APT_INRELEASE_SHA256shape makestest_every_external_sandbox_input_is_immutable_or_hash_verifiedfail — the assertion is load-bearing.ruff checkandruff format --checkclean on the edited test file.gpg --verify InReleaseagainst that keyring → good signature.docker-smoke); no Docker daemon in the authoring sandbox.Draft: the founder and the Deep Review agent decide on merge.