Nix fetchers currently require location-based addressing (URLs with specific hosts/gateways), even when fetching from content-addressed systems like IPFS or Radicle. This undermines the decentralized nature of these protocols and creates fragility.
For example, to fetch from IPFS today, you must hardcode a gateway:
This keeps Nix expressions location-agnostic while allowing per-user/per-system transport policies.
Key Design Questions
Generic framework: Should we design a pluggable fetcher system that can support any content-addressed protocol, or implement IPFS/Radicle separately?
Hash redundancy: IPFS CIDs already contain hash information. Should fetchIPFS require an additional hash parameter for Nixâs own verification, or trust the CID?
Offline/availability handling: What happens when no configured node has the content? Fallback behavior? Error messages? Default Gatway provided by NixInfra?
Configuration scope: Should node preferences live in nix.conf, separate config files, or only in NixOS/Home-Manager modules?
Security model: Do we trust the resolver/node, or only the content hash? How does this interact with Nixâs existing security assumptions?
Consider pkgs.fetchgit, which has a similar hash redundancy âissueâ. Do you understand why it is the way it is? Does the same reasoning apply to what you want to do?
If you drop the hash redundancy issue, then these seem like simple fetchers that could be added to Nixpkgs without an RFC, adding optional gateway configuration to the Nixpkgs inputs.
Like with your proposed fetchIPFS, etc., the Git hash theoretically already encodes the contents of the files to be added to the store. So one might similarly ask why the hash is necessary here:
But it is. Having the hash â making the fetcher a fixed-output derivation, in other words â simplifies a lot of concerns about ensuring that the impure things the fetcher does in order to make a Git connection and prepare the checkout as desired and so on have no sneaky effects on the output.
To be clear, if you would find a fetchIPFS that takes both cid and hash useful, Iâm encouraging you to submit the PR adding it to Nixpkgs right away, and let the discussion take place around the concrete code. The âgeneric frameworkâ doesnât need to be debated; the concept of FODs is already that framework, I think.
In my mind a true CA fetcher only needs a set of digests. This helps with,
Abstracting the CAS implementations, allowing systems with incompatible digest algorithms.
Migrate away from vulnerable digest algorithms.
Also deal with collision vulnerabilities. You could require using 2+ digest algorithms if none are considered safe for the next 5-10 years.
However, itâs often nice to use a mutable reference to an artifact, like rev in fetchRadicle or ref in fetchGit. This is something that interacts with flakes as it separates a somewhat âimmutable intentionâ with the required precise versioning used to have reproducible systems. Flakes are still experimental, but itâd be nice to understand where things should go when the mutable references go in the fetchers and the sets of hashes into lockfiles.
A good endstate would be to have a generic fetcher taking a set of mutable references like URLs, git repo+branch, etc; and have the lockfiles track a set of hashes.
What gets tricky with multiple (and thus alternative) mutable references is that when updating youâll need to rank them and trust one, or try getting everything and verify all hashes just to observe how propagation delays bite you with âfalseâ hash differences.
I think we need a few more discussions, as we need to address gateway configuration for both cases (Radicle and IPFS).
In my opinion, this should work analogously to how we handle GitHub tokens for example. However, this configuration might not be solvable through a pull request to nixpkgs and may require changes to Nix itself. We also need to decide what happens when no gateways are configured, especially while there are no official NixOS-operated nodes for IPFS or Radicle yet. (Radicle seems to be already in planning)
Just add a list of gateways for each to Nixpkgs config. Nixpkgs config is already configurable by file or on a per-import basis. The fetcher can access that list and, if unset, use some sensible default.
Thatâs not a practical problem. As I understand it, second preimage problem seems still quite safe with SHA1 (probably far from bgetting computable).
One of the core questions here is whether we can implement a fetcher which is more general (i.e. captures both IPFS and radicle) and whether we should.
Last time I checked it did not really work and it expects an ipfs node on the build system hardcoded to its default port.
As I already said. My main motivation for the discussion is finding a structure of how to give the user the ability to configure the gateways for content addressed protocols like IPFS and Rsdicle