How to handle files with sensitive data?

I’m building an Android app using Nix, and I need to include a keystore file which contains the necessary certificates.

As far as I know there are two ways of achieving this:

  1. Use copyPathToStore to include the file in the build.
  • Pro: Dead Simple
  • Con: Adds a sensitive file to Nix Store, which will cause it to end up in our Nix Binary Cache
  • Con: Fails with: Keystore was tampered with, or password was incorrect
    • probably due to permissions changes?
  1. Use the extra-sandbox-paths to use the file directly from where it’s located.
  • Pro: Not adding the sensitive file to Nix Store
  • Con: On NixOS this fails with: ignoring the user-specified setting 'extra-sandbox-paths', because it is a restricted setting and you are not a trusted user

Is there some other third way I can do this? Or maybe some way I can make extra-sandbox-paths work on NixOS?

If you want to make latter work you would just have to add yourselve to the trusted users in /etc/nixos/configuration.nix

1 Like

Probably the best way would be to just use a small shell wrapper around Nix to sign the resulting APK.
That way your build is still clean and you do not have any secrets flying around.

You could even have the signature script be generated through Nix:
Something roughly like this:

{ pkgs, ... }:
let apk = (import ./apk.nix);
in
pkgs.writeShellScript "sign-apk" ''
#!{stdenv.shell}
${pkgs.androidtools}/bin/sign --key /home/my/key --apk ${apk}
'';
1 Like

Thanks @zischknall for that, I wasn’t aware of that setting. Appreciate it!

@tokudan but that script references /home/my/key which is outside of /nix/store, so how is that different from using extra-sandbox-paths?

Also beware of using paths (E.g. src = ./.) as nix will add those paths to the store as well.

3 Likes

Right, that kind of implicit behavior is useful, but can be dangerous if you have anything sensitive.

What’s the recommended way of dealing with sensitive data in Nix in general tho?

That script is not run during the build process, it’s just generated during the build process.
You tell nix to build the script and all its dependencies, which will automatically build the apk.
Then you manually run the generated script, which will generate the signed apk.

I’ve never built an App myself, so the exact steps are probably way off, but I was only trying to point out a rough direction.

Similar to what you would do in industry. At runtime have the application read from a file or environment the information you need. You just want avoid adding the information to the store.