-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flake authentication #2849
Comments
How can you sign mutable references? They can by definition change, so including anything like a content hash is impossible. Who would be able to sign these things exactly? Is that GitHub itself? For immutable references, I would definitely try to include some sort of content hash to secure against GitHub being hacked. |
You don't sign mutable references, you sign particular versions of a flake. This could be done as a signature over an immutable reference. But the real question is where to get the signatures from. |
I marked this as stale due to inactivity. → More info |
This is still important to me. I don't know whether that is feasible in general but at least for Git Nix could just use existing commit signatures. That's sort of portable because there already exists instrumentation in Git and it would also work for non-flake references to Git repos. |
Relevant: NixOS/rfcs#100 |
I marked this as stale due to inactivity. → More info |
Begone, bot! |
I'm particularly concerned about this, but mostly about what was a footnote: registry signing. While it's a good idea to validate/sign the flakes themselves, the global registry itself should be signed and validated, since otherwise that opens up the possibility of server spoofing (DNS poisoning most likely). The two issues can probably be solved separately even: checking whether or not the list of aliases provided by the registry is provided securely doesn't have to be tied to whether or not the resulting reference is secure. Even then, that would mean you could then build a secure registry by providing aliases to specific revisions (possibly with hashing? idk about that part). |
I fully agree. As an added benefit this does not require any additional tooling for the developers of flakes; everything requires is built-in and ships with git, provided the runtime dependencies are met (gpg is in your PATH). While I am a strong proponent of ed25519 signatures everywhere, git already provides plenty of tooling for this use-case.
I'd like to remind you that the Linux kernel is 1990s stuff too, as is Plan9, as is SSH, all of which are several years older than GPG actually (which is a 1999 thing), making it four years younger than the initial IPv6 drafts. |
Given the added support for git signing with ssh keys since I last commented, and that recent debacle of GitHub exposing their SSH host key, it might be an increasingly decent idea... EDIT: Would <sigstore.dev> be of use here? Haven't used it so I have no idea. |
Inspired by NixOS/rfcs#34 discussion:
Currently we don't have any way to authenticate flakes. We only have transport security, e.g. by downloading via
https
orssh
, so if the server is compromised, it can serve Trojaned flakes. Thus, we would like to have the ability to require that flakes are signed in some way.Authentication is only needed when fetching from a mutable flake reference (i.e. one that doesn't include a Git revision or content hash). It will be assumed that the immutable flake references in a lock file were authenticated at the time the lock file was generated. [Actually it just occurs to me that for security,
github
flakes must include a content hash in the lock file, since we have no way to verify that the Git revision corresponds to the contents.]Ideally, the flake registry would contain public keys that are allowed to sign the trees fetched from a mutable flake reference. For example,
Alternatively, public keys could be part of a flake URI, e.g. a flake dependency could specify a public key like this:
However, the main issue is how to associate a signature with the downloaded flake.
For
github
flakes, GPG signatures can be fetched out-of-band via the GitHub API, but I would prefer to avoid GPG because 1) it's 1990s crypto; 2) I don't want to make Nix dependent on GPG when we already havelibsodium
; 3) GPG keys/signatures are much more unwieldy thanlibsodium
'sed25519
; 4) it would be nice to use the exact same mechanism as binary caches. We could use Git notes to attach ed25519 signatures, but I don't think they can be queried via the GitHub API.For
git
flakes, since we're cloning the whole repo, we do have the ability to use Git notes.For tarball flakes, the signature could be included in the tarball, or delivered as a separate file (e.g.
http://example.org/flake.tar.xz.sig
). However, the latter is racy because there is a time window betweenflake.tar.xz
andflake.tar.xz.sig
get updated.Another possibility is to fetch the signature from some content-addressable source specified in the flake registry, e.g.
"nixpkgs": { "sigs": "https://nixos.org/flake-sigs", ... }
. The client would compute the hash of the data to sign (see below) and then download the signature fromhttps://nixos.org/flake-sigs/<hash>
.Signature contents: The signature should be over the string
<content-hash>:<git-revision>:<git-ref>:<refcount-or-commit-date>
. Thegit-ref
(branch or tag name) is included to prevent an attack where the attacker replaces one channel (e.g.nixos-19.03
) with another (e.g.nixos-unstable
).refcount-or-commit-date
could be used to prevent rollback attacks, but this requires the client to keep some state about the last refcount or date it saw from a mutable flake.Registry authentication: The registry should also be signed. The public signing key will be hard-coded in Nix.
Certificates: We should allow the private signing key ("cold key") for a flake to be kept offline. This can be done by signing the flake using a hot key, and including in the signature file a certificate where the hot key signs the cold key. Revoked keys could be listed in the registry. (This would be pretty nice to have for binary cache signing as well.)
The text was updated successfully, but these errors were encountered: