Using git crypt with flakes

I have been using git crypt to encrypt my wifi passwords in a separate file. I recently switch to using flakes for my NixOS config. This worked well and the nix build process got the decrypted file from my local working tree. But since recently the file that the nix build process sees is encrypted so it is probably taken from the git repository (local) instead of the git worktree (where I have it decrypted with git crypt unlock).

It looks like it depends on the version of nix that is used to build my configuration, not the nxipkgs revision that is used as input for my flake. I did this in zsh to “bisect” and find a last known good nixpkgs version that can build my configuration and a first known bad one:

for sys in /nix/var/nix/profiles/system-*-link/bin/switch-to-configuration(On); do
  echo $sys
  sudo $sys switch &>/dev/null
  nixos-version
  nixos-rebuild build && break
  echo; echo
done

The out put is rather short:

/nix/var/nix/profiles/system-365-link/bin/switch-to-configuration
[sudo] password for luc: 
21.11.20210923.51bcdc4 (Porcupine)
building the system configuration...
error: syntax error, unexpected end of file

       at /nix/store/hggl6jg1xg2b62301n659rbg2d0q5y3y-source/modules/wifi.nix:1:1:

            1| GITCRYPT�
                        cv�v湇�����ß%��Fݳk47�6��[�v^-��Z����f���Vqʏ�|�e0�S=�n�����>�o,�z��ЁԳ9\���F7��=�Y����$�+�>K�G�,���^��!�/>�h-���7�9B�

                          �F-jt}!4bp�z�}_u�H�9�d��i�o��1��"���Q�jC�[�
             | ^
            2| IV�����a�H��՟�S���aʋ�
                                    �ߡ���\!6��������B��+Ep�K�����[`�le z��x�@�6��ߵ�@QK*~��Dt�,�%�/��u��ιha7u��Q�Q�ƪ����/Q_�.�����^�᫰�����������g�����z-H`��{B�\��K��F��!�A��l[��!-Kg㰲8�yF��$�QI�
(use '--show-trace' to show detailed location information)


/nix/var/nix/profiles/system-364-link/bin/switch-to-configuration
21.11.20210923.51bcdc4 (Porcupine)
building the system configuration...
error: syntax error, unexpected end of file

       at /nix/store/hggl6jg1xg2b62301n659rbg2d0q5y3y-source/modules/wifi.nix:1:1:

            1| GITCRYPT�
                        cv�v湇�����ß%��Fݳk47�6��[�v^-��Z����f���Vqʏ�|�e0�S=�n�����>�o,�z��ЁԳ9\���F7��=�Y����$�+�>K�G�,���^��!�/>�h-���7�9B�

                          �F-jt}!4bp�z�}_u�H�9�d��i�o��1��"���Q�jC�[�
             | ^
            2| IV�����a�H��՟�S���aʋ�
                                    �ߡ���\!6��������B��+Ep�K�����[`�le z��x�@�6��ߵ�@QK*~��Dt�,�%�/��u��ιha7u��Q�Q�ƪ����/Q_�.�����^�᫰�����������g�����z-H`��{B�\��K��F��!�A��l[��!-Kg㰲8�yF��$�QI�
(use '--show-trace' to show detailed location information)


/nix/var/nix/profiles/system-363-link/bin/switch-to-configuration
21.11.20210910.bbbe2b3 (Porcupine)
building the system configuration...

and tells me that nix-unstable from nixpkgs bbbe2b3 is able to build my configuration but nix-unstable from 51bcdc4 is not.

Now I have some questions:

  1. Why can I no longer build my configuration from the working tree?
  2. How can I bisect this further in order to answer 1? I do not need to use different nixpkgs revisions as input for my flake but nix itself needs to be build from different nixpkgs revisions. I then want to build the same revision of my flake with these different nix versions.
  3. Is there a good alternative to git-crypt? I started a similar discussion here and in the wiki but I think nothing has features similar to git-crypt, unless I misunderstand something.

I did not find any better solution so I have now extracted all confidential information into a seperate repository/flake that I specify as input to my system flake. Now I just have to keep this new repository private as a whole.

1 Like

Note that in recent versions of nix the changes that broke the use of git-crypt were reverted. (See https://github.com/NixOS/nix/pull/5284)

You can also use https://github.com/Mic92/sops-nix or agenix instead.

@Mic92 is that just a general remark that “one can use sops-nix (or agenix)” to somehow manage secrets or is it related to this specific scenario? I started the wiki page I linked above and am aware of these projects. I did not try them yet because to my understanding they are not tailored to my scenario.

Maybe I should specify the scenario again: I have a separate file (nixos module) that just has all my wifi passwords, it looks like this:

{
  networking.wireless.networks = {
    some-ssid.psk = "very secret";
    other-wifi.psk = "also secret";
  };
}

This file is called wifi.nix and was just listed in the modules = [ ] list in my nixos flake. And this file was encrypted via git-crypt. Currently this file is in a private repository and is imported from a flake input.

The requirements of this scenario are:

  1. I do not want to push my secrets (unencrypted) to a public git repository but I do want to push my system flake to such a place (I have in the mean time published my nixos config here)
  2. I do not care about the secrecy of the data post evaluation. It can be stored in the nix store dectyped for all I care
  3. I want to use the networking.wireless.networks option of nixos, I do not want to write my own code to generate a wpa config from some yaml or json file and a systemd service for decryption and generation of that config file.

I can rephrase point 2 & 3 into: I want to decrypt a nix expression at evaluation time. But in order to have 1. I do not want to store the passphrase/key for the decryption in the repository.

Git-crypt did provide that but as I see from the recent changes and the discussions (Unsmudge fetchGit for reproducibility and security by roberth · Pull Request #4635 · NixOS/nix · GitHub, https://github.com/NixOS/nix/issues/5260, and the one linked by chvp) this might not be a solution that is supported by nix in the long run.

ok. This workflow would not work with sops-nix. But also this workflow would expose all secrets to the nix store which might be not acceptable for some users (i.e. I like building my configuration in CI and upload it to public build caches).

There is networking.wireless which allows secrets to be stored separately.

networking.wireless.environmentFile = "/run/secrets/wireless.env";
networking.wireless.networks = {
  home.psk = "@PSK_HOME@";
  work.auth = ''
    eap=PEAP
    identity="my-user@example.com"
    password="@PASS_WORK@"
  '';
};

Otherwise you are stuck with the two option you already mentioned before.

I noticed from your nixos-config repo that you have been using git-crypt before agenix. I have something similar myself (based on git smudge) and I don’t intend to trade it for flakes.

Can you tell me if/how you avoided the decrypted secrets in the local repository being copied inside /nix/store?

I did not avoid the decrypted secrets being copied to the nix store. I had an encrypted nix file that was decrypted by git-crypt and only then copied to the nix store. And I was already using flakes at that point. Only after nix changed the copying mechanism upstream the nix file got copied into the nix store encrypted and my build broke.

Same as lucc for me. When I used git-crypt, the “secrets” covered by git crypt were world-readable in the nix store. I took great care to only use git-crypt for “secrets” that were not that critical. I moved away from git crypt due to the same issue that started this thread, since the git crypt usage could be replaced with agenix without huge issues.

I see, thank you anyway.

Hosted by Flying Circus.