Skip to content
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

Cannot sign store path that contains a flake.nix #4568

Closed
stephank opened this issue Feb 22, 2021 · 1 comment
Closed

Cannot sign store path that contains a flake.nix #4568

stephank opened this issue Feb 22, 2021 · 1 comment

Comments

@stephank
Copy link
Contributor

stephank commented Feb 22, 2021

Describe the bug

It appears nix store sign (and probably other similar commands) treats paths in /nix/store that contain a flake.nix as a flake, and try to evaluate it. This also happens when these commands visit such a path while traversing dependencies of some other path.

I've found specific cases where this breaks signing for us, but it may also have undesirable influence on general behaviour.

Steps To Reproduce

We have a flake that roughly does this:

{
  outputs = { self, nixpkgs }:
  with nixpkgs.lib;
  let
    # Subject is an example, in practice we use an attribute set with a bunch of parameters here.
    mkEnv = subject: {
      # Simple build to simulate `flake.nix` in the output.
      defaultPackage = mapAttrs (_: pkgs:
        pkgs.runCommand "greet" { } ''
          cp -r '${self}' $out
          chmod 0755 $out
          echo 'Hello ${subject}' > $out/greeting
        ''
      ) nixpkgs.legacyPackages;
    };
  in
    (mkEnv "world") // {
      inherit mkEnv;
    };
}

The purpose of this is that the flake exports both packages and modules, which are instantiated per environment (staging / production). We do a 'default' set of exports to make stuff like nix build work for testing, which is an instance with subject == "world" in the example above, but this default is never actually deployed. The actual deployments might do something like subflake.mkEnv "staging".

Important in this example is that the store output contains the source tree with its flake.nix, and that the defaultPackage for the flake will not exist in the store at all, because the dependant will only ever call mkEnv with some other parameter.

To replicate the issue, create a directory structure:

  • a/flake.nix, where the contents is the above example
  • b/flake.nix, which will simulate our deployment flake that uses a. Contents are: (make sure to tweak the path)
{
  inputs.subflake.url = "/path/to/a";
  outputs = { self, subflake }: {
    defaultPackage = (subflake.mkEnv "foobar").defaultPackage;
  };
}

Also generate a signing key:

# nix-store --generate-binary-cache-key dummy priv pub

Now build and try to sign:

# nix build ./b
warning: creating lock file '/Users/stephank/foo/b/flake.lock'
# ls -l result
lrwxr-xr-x 1 stephank staff 49 Feb 22 16:20 result -> /nix/store/wzgkz3jpiy4jalb46dzzp4xmgn99xq4v-greet
# nix store sign --key-file ./priv /nix/store/wzgkz3jpiy4jalb46dzzp4xmgn99xq4v-greet
warning: creating lock file '/nix/store/wzgkz3jpiy4jalb46dzzp4xmgn99xq4v-greet/flake.lock'
error: opening file '/nix/store/wzgkz3jpiy4jalb46dzzp4xmgn99xq4v-greet/flake.lock': Permission denied
(use '--show-trace' to show detailed location information)

Here, the sign command tries to evaluate the flake, but can't create a flake lock.

The error is different if the flake lock already exists:

# nix flake update ./a
warning: creating lock file '/Users/stephank/foo/a/flake.lock'
# rm b/flake.lock
# nix build ./b
warning: creating lock file '/Users/stephank/foo/b/flake.lock'
# ls -l result
lrwxr-xr-x 1 stephank staff 49 Feb 22 16:30 result -> /nix/store/a5jrv43k7yg7vla6jwwdqv05275ffrcf-greet
# nix store sign --key-file ./priv /nix/store/a5jrv43k7yg7vla6jwwdqv05275ffrcf-greet
error: path '/nix/store/vs7yklvf0fch04rqm8cyvkld4rgapmx5-greet' is not valid

This store path is for the default mkEnv "world" case, which was never built, so doesn't exist in the store. But because it is trying to evaluate the flake, it is encountering this derivation.

In practice, we have more derivations inbetween, but this still happens as nix store sign traverses dependencies.

Expected behavior

The store path itself should be signed, and no flake evaluation should happen.

nix-env --version output

nix-env (Nix) 2.4pre20210219_548437c

@stephank stephank added the bug label Feb 22, 2021
@edolstra edolstra added this to the nix-2.4 milestone Feb 22, 2021
@stephank
Copy link
Contributor Author

stephank commented Feb 22, 2021

Test case: stephank@03f2085

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants