Copy to cache fails, but why?

Hello there,
I’m trying to learn more about nix caches so I’ve setup an https cache as explained in Binary Cache - NixOS Wiki but then , when it’s time to experiment with populating the cache I get the following:

$ nix copy --to ssh://cache.foo.it .#deps
[8 built, 0.0 MiB DL] copying 116 pathserror: cannot add path '/nix/store/06amnnhhyl5v07yrjyi3ph9v6fbgzmaj-python3.7-charset-normalizer-2.0.6' because it lacks a valid signature
error: unexpected end-of-file

.#deps is an environment derivation containing all the dependencies of my development environment, whose binaries I want to share with a colleague to spare him the time spent building them.

But I don’t know if I’m doing something wrong or how to fix the situation. I’m using unstable and nix is at version:

$ nix --version
nix (Nix) 2.4pre20210922_bcd73eb

Ultimately I want to try something described here: https://www.tweag.io/blog/2019-11-21-untrusted-ci/ but with a push via ssh instead of s3.

In our cache-copy scripts we explicitly sign the paths, using the trusted binary cache key, before nix copy --to:

$ nix sign-paths \
  --key-file "/my/secret.key" \
  /nix/store/...

You should be able to verify that the store path(s) are signed correctly:

$ nix verify \
  --sigs-needed 1 \
  --trusted-public-keys "/my/public.key" \
  /nix/store/...

Oh, bummer, so I have to distribute the private key as well, that’s unfortunate.
I hoped that having the rights to ssh into the cache machine would make such step implicit on the cache side.
When found the error I suspected that could be something like that, but I’m now wondering why I couldn’t find it mentioned right near every nix copy bla bla example instuction.

Thanks anyway

But that probably would change the package in the process, but the changing the hash as well? Even if it’s known before the actual build process?

I hoped that having the rights to ssh into the cache machine would make such step implicit on the cache side.

But that probably would change the package in the process, but the changing the hash as well? Even if it’s known before the actual build process?

What you’re doing is to add a signature to the .narinfo file in the cache, which is separate from the actual pacakge. E.g. my nixpkgs version of the hello package from cache.nixos.org/mp9l1b6h5wfadvh5nac59sk6vm2k8ra5.narinfo has:

StorePath: /nix/store/mp9l1b6h5wfadvh5nac59sk6vm2k8ra5-hello-2.10
URL: nar/1g8785s97y08gi7h7qb2k08vn4m314z0lhmds379ab7s0dpzysdm.nar.xz
Compression: xz
FileHash: sha256:1g8785s97y08gi7h7qb2k08vn4m314z0lhmds379ab7s0dpzysdm
FileSize: 40996
NarHash: sha256:13zcqi7qcnmcmalf1zx1h5yxh03sqx70h88brxinh4cawd7n5as3
NarSize: 206000
References: jsp3h3wpzc842j0rz61m5ly71ak6qgdn-glibc-2.32-54 mp9l1b6h5wfadvh5nac59sk6vm2k8ra5-hello-2.10
Deriver: p77iwhiygckl6fxrzgj83w13kmr0q5xr-hello-2.10.drv
Sig: cache.nixos.org-1:CzqnTUo+BD++UqAjxHLMuRsAH4h8SzHi0jbl1fO8+/Py/Wp5YRRafM5yxFoAIsLw1UJzSX8NHl/p5FuOs3zQBA==

If you look at your cache for your packages, you should see your own signature there. This is then independent of the transport (ssh, s3, or whatever).

I guess if you only want network level security you can also disable signature checks (I have not tried this though so there might be some caveats):

$ nix copy --no-check-sigs --to ...

Then correspondingly whoever substitutes from that cache would have to disable signature checks (nix config parameter require-sigs), which seems dangerous.

I agree, maybe instead knowing how the nix copy works it could be possible to add a “stage” on the server side that signs the packages and then pipes them to the “copy handler”?

Write access control for binary caches - Cachix Blog for some thoughts about this :slight_smile:

I was getting it all wrong! It does what I want. Looking at the code gave me some hints. I works with the root user i.e. running it like this is successful:

$ nix copy --to ssh://root@cache.foo.it .#deps

no signing needed

and then if you configure the server with with you user in nix.trustedUsers the non-root user copy works as well.