Git, ssh, repo depdendency and authentication

We need to keep a dependency in a project private. My first instinct was to grant all of its developers ssh access (with public key authentication) to the repository, and have the project use:

[dependencies]
foo = { git = "ssh://foo.org:3333/bar/buzz.git" }

With that I encountered Support SSH Git URLs for authenticated connections to private repositories · Issue #1851 · rust-lang/cargo · GitHub, which basically says that cargo does not use the git command, which uses the regular ssh command. Instead cargo uses libgit2, which does not use ~/.ssh. So the authentication against the repo host fails when checking out the source.

One solution is to set ~/.cargo/config to use the git command line tool instead:

[net]
git-fetch-with-cli = true

This works, but I would prefer to not have to reconfigure cargo on each system to use a non-default behavior for something like checking out code. The documentation states that libgit2 should be able to pick up keys from ssh-agent. I tried disabling git-fetch-with-cli again and adding the private key to ssh-agent using ssh-add <private key file> (and verified that it was loaded using ssh-add -l, and that the shell has SSH_AUTH_SOCK set properly), but when cargo tries to check out the code I get the error which says it's unable to get the repository. (It's clearly not picking up the private key).

I'm currently trying this on macOS.

Does anyone here have fetching crates from a custom git repo working with ssh public key authentication without git-fetch-with-cli?

1 Like

I've tried various solutions to exactly this problem for years, but without any success.
Ultimately my solution was what you describe, but I don't have to do it for multiple workstations.

If I did, I'd just put it in a git repo together with other config files and have each developer clone it.

2 Likes

Yes, it works fine for me on Linux.

Maybe you need to specify the ssh user in the repo URL? (I.e. "ssh://user@foo.org:3333/bar/buzz.git"). You can also try to set CARGO_LOG=debug environment variable and see if it provides any insight.

So apparently I stepped into an area where there is some flakyness. In case anyone else embarks on this adventure, here are some of my observations:

I started using PuTTY/plink/pageant on Windows long before Microsoft saw the light and integrated OpenSSH, and I stuck with it. This came back to bite me. If one uses plink without specifying a username, it will send a "login:" string, which (obviously) confuses git. But when I passed a username, I got another error.

I gave up on PuTTY/plink and moved on to the OpenSSH that is integrated in Windows. First I tried to clone a repository directly using something akin to git clone ssh://git.foo.org:2222/some/repo.git. This causes an "network unreachable" error, because it interprets that as a really funky IPv4 address, something along the line of 0.0.4.97. So I assumed it was simply misparsing the URL, potentially with the port number. So I tried to set the environment variable GIT_SSH_COMMAND to ssh -oPort=2222 and ran git clone ssh://git.foo.org/some/repo.git. This time it worked -- but this is straying far off the "keep it as simple and default as possible" path I'm trying to stay on.

Upgrading to git 2.35.1.windows.2 appears to have fixed the URL parsing bug; it can now handle ssh://git.foo.org:2222/some/repo.git.

So with this, and setting git-fetch-with-cli = true in ~/.cargo/config, I can get private crates using ssh with public key authentication working on Windows as well. ... However, doing this makes checking out crates via ssh incredibly slow [because launching processes on Windows is a very expensive operation].

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.