Can someone please help me understand how nix ensures the authenticity of everything that it downloads (before building/installing) using cryptographic signatures?
Specifically, I come from Debian (in peace). I’m used to apt
. Perhaps it’s my bias, but I think it’s really easy to understand how apt
ensures the cryptographic authenticity of its packages:
- An apt repo is just a simple http (or ftp) server. You can view the URLs of these repos by viewing the contents of your
/etc/apt/
directory. For example, Index of /debian/dists/bookworm - We can just open the above URL in our web-browser, and see the files
Release
andRelease.gpg
. We can download both these files and confirm the authenticity of Release file withgpg
. - The release file (now verified as authentic, even if https is compromised) contains the cryptographic hashes of all the other files on this http server. For example,
main/binary-amd64/Packages.gz
- The
Packages.gz
file contains the cryptographic hashes of all our actual.deb
files.
From ^ this, it’s easy for a user to simply download the signed files using their web browser and see how Debian confirms the authenticity of all the packages.
I cannot figure out how to do the same with Nix.
Nix documentation promises that it has cryptographic signatures enabled by default. That’s great, but how do I view and actually test this (like above)?
Example
Let’s consider the package vim
.
In Debian
In Debian, I search my /etc/apt/
dir for the repos that I’m using. For example, we find Index of /debian
user@debian:~$ grep -ir deb /etc/apt
...
/etc/apt/sources.list:deb http://deb.debian.org/debian/ bookworm main contrib non-free non-free-firmware
...
user@debian:~$
Then I can just copy & paste this URL (Index of /debian) and see some directories. If I click on the dists/
directory, then I see a list of versions. The file above indicates we’re using bookworm
(the codename for Debian 12), so I again click on the bookworm/
directory in the web browser. Finally, I see the Release
and Release.gpg
files.
We can copy & paste the URL of these files from the web browser and then download them on the command line (for clarity)
wget https://ftp.debian.org/debian/dists/bullseye/Release
wget https://ftp.debian.org/debian/dists/bullseye/Release.gpg
Now we can verify the authenticity of this file cryptographically with gpg
user@debian:~$ gpg --import /etc/apt/trusted.gpg.d/*
...
user@debian:~$
user@debian:~$ gpg --verify Release.gpg Release
gpg: Signature made Sat 09 Nov 2024 05:11:43 AM -05
gpg: using RSA key A7236886F3CCCAAD148A27F80E98404D386FA1D9
gpg: Good signature from "Debian Archive Automatic Signing Key (11/bullseye) <ftpmaster@debian.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 1F89 983E 0081 FDE0 18F3 CC96 73A4 F27B 8DD4 7936
Subkey fingerprint: A723 6886 F3CC CAAD 148A 27F8 0E98 404D 386F A1D9
gpg: Signature made Sat 09 Nov 2024 05:11:43 AM -05
gpg: using RSA key 4CB50190207B4758A3F73A796ED0E7B82643E131
gpg: Good signature from "Debian Archive Automatic Signing Key (12/bookworm) <ftpmaster@debian.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: B8B8 0B5B 623E AB6A D877 5C45 B7C5 D7D6 3509 47F8
Subkey fingerprint: 4CB5 0190 207B 4758 A3F7 3A79 6ED0 E7B8 2643 E131
gpg: Signature made Sat 09 Nov 2024 05:14:43 AM -05
gpg: using EDDSA key 4D64FEC119C2029067D6E791F8D2585B8783D481
gpg: issuer "debian-release@lists.debian.org"
gpg: Good signature from "Debian Stable Release Key (12/bookworm) <debian-release@lists.debian.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 4D64 FEC1 19C2 0290 67D6 E791 F8D2 585B 8783 D481
user@debian:~$
Only now that we’ve confirmed the file is authentic, we can trust its file content’s cryptographic hashes. Here we have the MD5 and SHA256 checksums for the “main” packages for amd64 architecture:
user@debian:~$ grep main/binary-amd64/Packages.gz Release
63997849d2fd6076c844ddf0622f60f2 12079357 main/binary-amd64/Packages.gz
2f674d057c5f274c5a863664a586ef62a0deb571993914ccfe4e2cd784a4840d 12079357 main/binary-amd64/Packages.gz
user@debian:~$
Back in the web browser, we can click-through the main/
and binary-amd64/
directories to download the Packages.gz
file
wget https://ftp.debian.org/debian/dists/stable/main/binary-amd64/Packages.gz
And get its SHA256 checksum:
user@debian:~$ sha256sum Packages.gz
2f674d057c5f274c5a863664a586ef62a0deb571993914ccfe4e2cd784a4840d Packages.gz
user@debian:~$
It’s easy to see that this file’s checksum matches the checksum listed in the Release file, whoose authenticity we verified with gpg
.
Now we can get the checksum of the vim
user@debian:~$ gunzip Packages.gz
user@debian:~$
user@debian:~$ grep -EA 20 'Package: vim$' Packages
Package: vim
Version: 2:9.0.1378-2
Installed-Size: 3650
Maintainer: Debian Vim Maintainers <team+vim@tracker.debian.org>
Architecture: amd64
Provides: editor
Depends: vim-common (= 2:9.0.1378-2), vim-runtime (= 2:9.0.1378-2), libacl1 (>= 2.2.23), libc6 (>= 2.34), libgpm2 (>= 1.20.7), libselinux1 (>= 3.1~), libsodium23 (>= 1.0.14), libtinfo6 (>= 6)
Suggests: ctags, vim-doc, vim-scripts
Description: Vi IMproved - enhanced vi editor
Homepage: https://www.vim.org/
Description-md5: 59e8b8f7757db8b53566d5d119872de8
Tag: devel::editor, implemented-in::c, interface::commandline,
interface::text-mode, role::program, scope::application,
uitoolkit::ncurses, use::editing, works-with::text, works-with::unicode
Section: editors
Priority: optional
Filename: pool/main/v/vim/vim_9.0.1378-2_amd64.deb
Size: 1567304
MD5sum: cdcefcf9e364332e6ecef182976e096e
SHA256: 1ca56e3724191401f6598890bfbe3655174934fa3735ec2fb55f38b100087d46
user@debian:~$
And we now see it’s possible to download vim_9.0.1378-2_amd64.deb
and confirm its checksum, which can be trusted because of the gpg
verification from above.
In NixOS
It looks like here is the file info for the vim
package in nix:
…but I can’t find any signatures, nor find any documentation that spells out how nix actually verifies the cryptographic authenticity of an example package (like vim).
How can I download the vim
package from nix and verify its signatures in bash the same as nix does it?