Passing secret to overlay / environment variable?

i’d like to reproduce passing a github token to nixpkgs-review, which can use say:

  • a --token flag of its sub-commands, which seems sort of impractical to configure
  • a GITHUB_TOKEN environment variable

now, the latter seems easy enough to set using either nixos or home-manager, but security seems like the tricky bit there.
i had been using sops-nix, which exposes protected files containing the secrets to prevent them from hitting /nix/store.

i’m not sure however how to use that to either:

  • set environment variables in nixos or home-manager (as the settings for these aren’t made to grab these from files)
  • wrap the package to pass it such a variable, as config (which sops-nix is accessed thru) i think would not be available at the time overlays are defined yet

what would be a nice way to solve this?

1 Like

Fundamentally, you have to do these things at runtime, any other mechanism will expose your secrets to the nix store. So in each case, some bash will be required:

# Do this with home-manager to prevent leaking the
# variable to other users
programs.bash.initExtra = ''
  export GITHUB_TOKEN="$(cat ${config.sops.secrets.github-token.path})"
'';

I don’t like this though, since this means anything can read your github token, which is a bit excessive.

let
  gh-wrapped = pkgs.writeShellScriptBin "gh" ''
    ${pkgs.gh}/bin/gh --token $(cat ${config.sops.secrets.github-token.path}) $@
  '';
in
environment.systemPackages = [
  gh-wrapped
];

I don’t actually recommend this, since it exposes the secret in /proc because process args are world readable.

My actual preferred solution would be a mix of the two:

let
  gh-wrapped = pkgs.writeShellScriptBin "gh" ''
    export GITHUB_TOKEN="$(cat ${config.sops.secrets.github-token.path})"
    ${pkgs.gh}/bin/gh $@
  '';
in
environment.systemPackages = [
  gh-wrapped
];

This limits the variable just to the gh process (and its children), and doesn’t expose anything via other channels. Make sure to set appropriate permissions for the secret.

Feel free to substitute with wrapProgram as you see fit, too lazy to figure out the API for that right now. Doing it not as an overrideAttrs means you don’t need to rebuild gh, so I suggest using runCommandLocal if you wish to do so.

5 Likes

@TLATER thanks!
wrapProgram --set ... seems to wrap the environment variable’s values in single quotes, so not sure that’d work.
(also i couldn’t get the $(cat ...) to render there, but that was prob an escaping thing.)
your writeShellScriptBin approach works just fine tho. :slight_smile: :pray: