Accessing private repo uses root's ssh key instead of user's ssh

I’m trying to access a (non-flake) private repo I own on github. I have setup github to accept access with ssh-key, and I’ve given github my user’s ssh public key, stored in /home/<username>/.ssh/

The issue is that when I rebuild my system, I do so with sudo nixos-rebuild switch --flake ., which means that this process is run as root, and root does not look for ssh keys in /home/<username>/.ssh/ hence it doesn’t find an ssh key to access the github repo, and fails.

I have tested this behaviour, and when using

fetchGit {
    url="git@github.com:username/secret-repo-name.git";
    rev = "[the correct rev number]";
}

in my configuration, the command sudo nixos-rebuild switch --flake . fails with the following error:

git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Additionally, I’ve tried to run

nix eval --expr 'fetchGit { url="git@github.com:username/secret-repo-name.git"; rev = "[again rev number]"; }'

and this command succedes, while running this command with sudo fails with the same error as above. Because of this I am confident that there must be some issue with using the correct ssh key.

How do other people access private repos?? I’ve seen plenty of references where they just use a variation of this (another way is to use it as a flake input with flake = false, but it gives the same error), and I haven’t found anywhere anything documenting this issue.

Do other people not have this issue? How do you manage your ssh keys and what public key have you given to github? Should I not be running nixos-rebuild switch with sudo?

Thanks in advance for any help

By using sudo you let root evaluate the expression, so all eval time fetchers of course are done under root.

As you are using flakes, and not using --impure, the use of --use-remote-sudo rather than using sudo will solve your problem and should not introduce any new ones (unless you consider asking the password after build, prior to activation a problem).

4 Likes

Thanks, this does indeed fix the issue!

Is this “the intended way” of doing this? Sorry if it’s a stupid question, but it’s the first time I’ve seen this mentioned, in particular I’ve never found it anywhere that mentioned accessing a private github repo. By quickly looking online it seems that running nixos-rebuild switch with sudo is treated as “the intended way”.

Also, I wouldn’t consider asking the password after the build, prior to activation a huge problem, but it kind of is an inconvenience, mainly because it takes up to a minute to build and I usually do something else while it builds on a different workspace, without being able to see the terminal and the build progress. Is there any workaround for this?

Depending on the timing sudo echo; nixos-rebuild --use-remote-sudo … can work.

With channels, sudo vs. --use-remote-sudo can make a huge difference, also --use-remote-sudo was originally designed to be used with --target-host, but works locally “by accident”.

Personally I think, flakes should also imply the behaviour of remote sudo. You can see this in many of the personal wrappers users wrote, like vipers nh or my switcher (very opinionated and even has my repo hardcoded).

I understand.

I have to say I’m not 100% happy with the --use-remote-sudo, both because of the password requirement not being upfront and mainly because this feels a bit hacky and I don’t want to rely on something that MIGHT change behaviour (I am not familiar with nix developement but I could understand if they changed it so that --use-remote-sudo required the remote to actually be a remote, to avoid misunderstandings).

As an alternative solution, I have tried symlinking both public and private keys from ~/.ssh to /root/.ssh and (unsurprisingly) it works (as in, it works when using sudo), and I’m 99% happy with this so I think I might stick to this. I have only checked out nh briefely and I might look into it more, thanks for the tip!

I now have a “working” setup that I’m almost happy with, but I would like to know how other people with private repos solve this issue, because in many sources they seem to propose either fetchGit or a flake input with flake = false as a it-just-works-out-of-the-box solution (for example these sources: [1], [2], though I’ve seen it mentioned here where they also suggest the /root/.ssh fix), which is not my experience.

I’d like to know how many other people with private repos have faced this issue, and how they solved it, because by the looks of it it seems like I’m the odd one.

Anyway, thanks for the help!

nixos-rebuild is part of NixOS, not nix. It’s a pretty simple bash script.

Changing behavior of that flag is unlikely to happen anytime soon, and if it does you’ll get deprecation warnings and NixOS release notes for sure. Many people rely on it, this will not be a surprise change, if it even happens. I’d wager that nixos-rebuild-ng will become the default before then, and that has already taken years.

I agree that the password prompt after the build is quite annoying, though. Not great to set a build that’ll take a good 20 minutes going and then forgetting about the password prompt. There’s no good alternative, sadly, at least not without some development.

2 Likes

You can also just run nixos-rebuild build first as your regular user, and then only invoke the switch with sudo. That has the same issue of delay until the password prompt, though with a little more interactivity so it doesn’t always feel so forgotten.

The other place where this comes into play is with autoupdates, where again the eval and build is run under root. For this case, I have the source repo set up with the root user ssh keys for each host having read-only access, as a different user in the repo. I’m using soft-serve locally for this, it’s rather more difficult for github where you can’t just add extra users so easily.

Perhaps some kind of mirror setup could help? You do all your development as now in github, but either sync revisions from there, or have your workspace git remote with multiple pushurl’s for both github and a local repo (which can just be a file path) that root can access. It all depends on what will fit your workflow.

2 Likes