Recommended way of providing username/password for private GitHub repos

The fetchFromGitHub function allows for fetching from private repos, which requires specifying a username/password. It gets these from environment variables.

Personally, I’m a bit leery of stuffing my GitHub credentials into environment variables accessible to any tool I run. I know that sticking them in something like ~/.netrc makes them visible to tools I run, so I need to trust anything I run anyway, but I feel like reading ~/.netrc is a conscious decision (and one that I could theoretically detect) whereas environment variables are things that might end up in various logs (e.g. build logs) and whatnot.

Is there any way of having fetchFromGitHub read the username/password from something other than environment variables (using ~/.netrc would be ideal, since this is a single-user install), or do I just need to give up and wrap nix in a script that sets the variables (so at least they’re not exposed to every other tool I run)?

1 Like

The builtin fetchers are executed at evaluation time and have access to your user’s environment, including reading from the ~/.netrc. So that’s one way to do it. I find that they are a bit slower to execute than the drv fetchers.

The drv fetchers are executed at build time and their build instructions are recorded into the machine-wide store. Not great for credentials. Some environment variables are let through but still, it doesn’t feel right. One option here is to pretend that the source is publicly accessible and use a HTTP_PROXY + MITM for TLS to inject the credentials upstream.

1 Like

We have a private rhodecode instance rather than using github, but we use overlays to store our credentials for this issue. Then we can use a url like https://${pkgs.authdetails}@hostname/repo to access our repos.

The overlay itself tends to look like this:

self: super:
let authDetails = builtins.fromJSON (builtins.readFile ./auth.json);
in
{

authdetails = “${authDetails.username}:${authDetails.password}”;

}

Additionally, the credentials are access tokens with short expiry (number of hours) that are rotated often and managed using a script that is run before building.

Yes, the credentials appear in logs, but the short expiry and rotation reduces the risk to levels we are comfortable with.

2 Likes

Interesting idea, but don’t the credentials end up in the .drv files in the nix store?

They do, however they are invalid after a short period of time, so it is a risk we are willing to tolerate.

Fair enough. That won’t be great for me then because I’m looking to use this with long-lived credentials (a manually-generated GitHub API token).

It would be good to hear what others are doing as other people must have solved this better than we have.

fetchgitPrivate supports reading ssh-auth-sock and git-ssh from the nix path as a way to use SSH keys to access git repositories. You can use this to keep your credentials in the ssh-agent instead of in the environment. I believe private repositories on GitHub support ssh.

1 Like

Thanks for that.
Are you (or anyone else) aware of similar functionality for hg?

It doesn’t look like there is a fetchhgPrivate. I’d start by trying the same approach as fetchgitPrivate.