go
go copied to clipboard
cmd/go: private repos on hard-coded hosting providers require special configuration
What version of Go are you using (go version
)?
$ go get -u golang.org/x/vgo
$ vgo version
go version go1.10 darwin/amd64 vgo:2018-02-20.1
Does this issue reproduce with the latest release?
yes (coming from https://github.com/golang/go/issues/25590)
What operating system and processor architecture are you using (go env
)?
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/brunetto.ziosi/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/brunetto.ziosi/Code"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/m3/145jfhdd5qsf66_41wt9p02mhc4hp5/T/go-build518939426=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
I ran
vgo get github.com/MY_ORGANIZATION/MY_REPO
where:
- I ran the command in a folder with a working golang app and a proper go.mod file -> vgo is working here and I can vgo build the app
- the repo is a private repo with SSO enabled I can access (git pull/push, ...)
What did you expect to see?
The package code in MY_REPO or the go module downloaded
What did you see instead?
vgo get github.com/MY_ORGANIZATION/MY_REPO: git ls-remote -q https://github.com/MY_ORGANIZATION/MY_REPO in /Users/brunetto.ziosi/Code/src/mod/cache/vcs/2cb00fa3547080bb301974fe87cf912af55d50f7a6d8a9955e11fed7a20ac6d3: exit status 128:
remote: Repository not found.
fatal: repository 'https://github.com/MY_ORGANIZATION/MY_REPO/' not found
What vgo
commit did you build from?
What happens if you attempt to go get
the same repository with the ordinary go
tool?
Are you using the credential helper?
What vgo commit did you build from?
I don't know, I just updated it before running it... how can I know the commit?
What happens if you attempt to go get the same repository with the ordinary go tool?
The simple go get
does some stuff in the background and says nothing, if I run go get -v -u
I see the repo itself downloaded and some dependencies downloaded, few others blocked by our firewall (-insecure
seems to allow the download for everything).
Are you using the credential helper?
I don't think so, I exchanged the keys with github so my remote is like
$ git remote -v
origin [email protected]:MY_ORGANIZATION/MY_REPO.git (fetch)
origin [email protected]:MY_ORGANIZATION/MY_REPO.git (push)
The error text shows the command being run. It is one of the few git commands that doesn't actually care about having a git repo to run, so you can just try it in any directory you want:
git ls-remote -q https://github.com/MY_ORGANIZATION/MY_REPO
Does it work?
Possible duplicate of #26145 but the error message from git is different (no mention of terminal prompts disabled).
Ok, so
$ git ls-remote -q https://github.com/MY_ORGANIZATION/MY_REPO
remote: Repository not found.
fatal: repository 'https://github.com/MY_ORGANIZATION/MY_REPO/' not found
but
$ git ls-remote [email protected]:MY_ORGANIZATION/MY_REPO.git
3fe3e3f8b07ff40cdf5de8685360715c4c06df9c HEAD
1fd67741650c052e30bce6d780cd26c273ba0ab2 refs/heads/dev
1498d237221b9e19d55148dded8fafc7316a47bf refs/heads/evo
3fe3e3f8b07ff40cdf5de8685360715c4c06df9a refs/heads/master
3e86bf596a1f63631b91cc9cbbc0866b88cb67c3 refs/pull/1/head
14aef40c003sw32ab1402b2471d164c549624e5c refs/pull/2/head
...
Maybe I am able to reach the repository only via ssh?
If you can make the https form work then vgo (and old go get) will be happy. The two possible ways to do that are:
-
Add to $HOME/.gitconfig:
[url "ssh://[email protected]/MYORGANIZATION/"] insteadOf = https://github.com/MYORGANIZATION/
-
Add to $HOME/.netrc:
machine github.com login YOU password APIKEY
where APIKEY is an API key obtained from the GitHub API page with access to private repos.
Retitling this to "cmd/go: github private repos require special configuration". Maybe for Go 1.12 we should think about some way to get this right by default. I'm not sure exactly how.
The first option, adding
[url "ssh://[email protected]/MYORGANIZATION/"]
insteadOf = https://github.com/MYORGANIZATION/
to $HOME/.gitconfig
work like a charm!!
Thanks!
Hi Guys,
I don't know if this is the correct issue to comment on so please forgive me if it's not correct, I ended up here because of an Issue I am having with Gitlab. We have a project structure where we use subgroups for project organisation by client/project/repo. So our package import paths are 3 levels deep rather than the standard 2 you see on Github. This is fine except for an issue with go get
. Gitlab has a strict security policy where requests for the go-import
meta data is incorrect for private sub groups by design for unauthenticated requests. So for example if I wanted to go get my.gitlab.com/foo/bar/fizz
the meta data request would be https://my.gitlab.com/foo/bar/fizz?go-get=1
and the meta data returned would be:
<html><head><meta name="go-import" content="my.gitlab.com/foo/bar git https://my.gitlab.com/foo/bar.git" /></head></html>
Gitlab recently did implement support for a HTTP header to override this behaviour over here: https://gitlab.com/gitlab-org/gitlab-ce/issues/42817 so we can send a Private-Token
header to get the correct meta. However I cannot find a way where I can get go get
to send that header to resolve the source path.
We could update our import paths to include a .git
suffix but that feels a little broken?
I guess what we need is a way for go get
to find crednetial information for these sorts of projects, perhaps another file that lives alongside go.mod
and go.sub
like go.creds
or something, which could contain credential information (you wouldn't want to check that into a repo tho). Or perhaps a way to override go-import
meta data locally? :man_shrugging:
To add to the list of options in this space (https://github.com/golang/go/issues/26134#issuecomment-403885803), we should also add use of a keychain/keyring as a third option (which is independent of remote VCS). Instructions vary quite widely between platforms, unsurprisingly:
- Mac: https://help.github.com/articles/updating-credentials-from-the-osx-keychain/
- Linux: https://wiki.archlinux.org/index.php/GNOME/Keyring (or equivalent)
- Windows: ???
I've switched back from using the ssh solution on Linux to using Gnome keyring (even though I don't use Gnome) to great effect... not least because it can be used to unify all credentials.
@FiloSottile are there are any security implications that I'm unaware of with respect to the use of keychain/keyrings for this sort of thing?
With Go tip (f2131f6e0c) I can use private repos without modules (with the url "ssh://git insteadOf
config above), but not with modules:
dev:barlogaamp $ GO111MODULE=on go install -x -v .
# /home/bradfitz/pkg/mod/cache/vcs/61e3c76780847e514802ec6af8f940f641c6017f711444f05c59cb17ac46d456 for git2 https://github.com/bradfitz/private
go: finding github.com/bradfitz/private v0.0.0-20180808000000-9069f54cff2af5e9fc291df126155504d71d1fd9
cd /home/bradfitz/pkg/mod/cache/vcs/61e3c76780847e514802ec6af8f940f641c6017f711444f05c59cb17ac46d456; git -c log.showsignature=false log -n1 '--format=format:%H %ct %D' 9069f54cff2af5e9fc291df126155504d71d1fd9
0.002s # cd /home/bradfitz/pkg/mod/cache/vcs/61e3c76780847e514802ec6af8f940f641c6017f711444f05c59cb17ac46d456; git -c log.showsignature=false log -n1 '--format=format:%H %ct %D' 9069f54cff2af5e9fc291df126155504d71d1fd9
cd /home/bradfitz/pkg/mod/cache/vcs/61e3c76780847e514802ec6af8f940f641c6017f711444f05c59cb17ac46d456; git tag -l
0.002s # cd /home/bradfitz/pkg/mod/cache/vcs/61e3c76780847e514802ec6af8f940f641c6017f711444f05c59cb17ac46d456; git tag -l
cd /home/bradfitz/pkg/mod/cache/vcs/61e3c76780847e514802ec6af8f940f641c6017f711444f05c59cb17ac46d456; git ls-remote -q https://github.com/bradfitz/private
0.177s # cd /home/bradfitz/pkg/mod/cache/vcs/61e3c76780847e514802ec6af8f940f641c6017f711444f05c59cb17ac46d456; git ls-remote -q https://github.com/bradfitz/private
cd /home/bradfitz/pkg/mod/cache/vcs/61e3c76780847e514802ec6af8f940f641c6017f711444f05c59cb17ac46d456; git fetch -f --depth=1 https://github.com/bradfitz/private 9069f54cff2af5e9fc291df126155504d71d1fd9:refs/dummy
0.165s # cd /home/bradfitz/pkg/mod/cache/vcs/61e3c76780847e514802ec6af8f940f641c6017f711444f05c59cb17ac46d456; git fetch -f --depth=1 https://github.com/bradfitz/private 9069f54cff2af5e9fc291df126155504d71d1fd9:refs/dummy
go: github.com/bradfitz/private@v0.0.0-20180808000000-9069f54cff2af5e9fc291df126155504d71d1fd9: git fetch -f --depth=1 https://github.com/bradfitz/private 9069f54cff2af5e9fc291df126155504d71d1fd9:refs/dummy in /home/bradfitz/pkg/mod/cache/vcs/61e3c76780847e514802ec6af8f940f641c6017f711444f05c59cb17ac46d456: exit status 1
go: error loading module requirements
That final git fetch fails, but that hash exists in the private repo:
$ git cat-file -t 9069f54cff2af5e9fc291df126155504d71d1fd9
commit
And it's on the remote (it's remote/origin/master^
), but it doesn't have a remote tag or other ref, if that's the problem.
dev:src $ git --version
git version 2.11.0
@bradfitz I think you're running up against https://github.com/golang/go/issues/26894
Is it possible to add a flag that causes go to clone over ssh (or any other potential future protocol)?
A flag would be easy to use in CI where necessary and is more easily explained than editing a .gitconfig or .netrc.
Wrote a script if any of you guys need to containerize a similar app using private github repo imports: https://github.com/anuragdhingra/pdocker-go
Note that this issue only applies to the hard-coded hosting sites.
If we have some sort of general HTTPS auth mechanism (#26232), HTTPS servers that use <meta>
tags should provide ssh
URLs as appropriate to begin with.
Issue #31376 was duplicated here, but is not using one of the hard-coded hosting sites. The matching HTTPS server provides no tags, and documented methods to make 'go get' skip VCS detection step do not seem to be working.
@stub42, my apologies. We do have a special case for launchpad.net
; I had missed the fact that git.launchpad.net
should not match that special case.
Thank you for this issue, I was debugging the access to my private github repos for a week..
$HOME/.gitconfig:
[url "ssh://[email protected]/MYORGANIZATION/"]
insteadOf = https://github.com/MYORGANIZATION/
@rsc I have a huntch that capturing private repo information in the go.mod file might help. This information and auth details can get used directly or passed to Athens.
Maybe instead of insteadOf
Add to $HOME/.gitconfig:
[url "ssh://[email protected]/MYORGANIZATION/"] insteadOf = https://github.com/MYORGANIZATION/
we could write something like
module my/package
replace github.com/MYORGANIZATION => ssh://[email protected]/MYORGANIZATION/someprivatepackage v1.1.1
require github.com/MYORGANIZATION/someprivatepackage v1.1.1
or
module my/package
require github.com/MYORGANIZATION/someprivatepackage v1.1.1 at [email protected]:MYORGANIZATION/someprivatepackage
I'd also like to see a solution to this where the private repo information can be stored in the repository. This is currently holding me back from using Go modules for projects that depend on private repositories because it's not seamless enough (requires modifying $HOME/.gitconfig locally).
@marksamman any ideas on how authentication should be done?
Is putting a public key in the go.mod file a security issue?
eg
module my/package
require github.com/MYORGANIZATION/someprivatepackage v1.1.1 at [email protected]:MYORGANIZATION/someprivatepackage using ssh-rsa AAAAB3NzaC1yc2EAAAADAQA...2JN millergarym@development_machine_and_ci
@marksamman any ideas on how authentication should be done? ...
@millergarym if you mean a private key, yes.
I am not suggesting including authentication credentials in the repository, just a way of pulling over SSH instead of HTTPS and leaving the rest for Git to handle.
EDIT: I've learned that my problem can be solved with the go-import meta tag, so this is no longer a blocker for me to use Go modules with private repositories.
@marksamman any ideas on how authentication should be done? ...
@millergarym if you mean a private key, yes.
No, only public keys
EDIT: I've learned that my problem can be solved with the go-import meta tag, so this is no longer a blocker for me to use Go modules with private repositories.
Can meta tags point to private repos? If so please provide an example.
Meta tags require serving public document referencing the private branch or repo, which is data leakage and not acceptable at some sites. The Launchpad web site returns a 404 for private branches, unless you are both logged in and have been granted read access. A tool can't tell if the repo exists unless it has a valid oauth token or speaks SSH.
My current workaround is to embed my private branches as git subtrees, as 'replace' in go.mod already allows me to reference a relative local path:
replace api/fooclient v0.0.0 => ../api/fooclient
require api/fooclient v0.0.0
I think allowing 'replace' to specify full URLs would be a workable solution, or a new command, ideally without the v0.0.0 version pin. Say, theoretically:
rewrite api/fooclient => git+ssh://git.launchpad.net/~stub/foo/+git/foo-client
require api/fooclient
(Interestingly, you should be able to use the existing replace to force use of a fork without changing imports, perhaps even a fork of parts of the standard library)
The first option, adding
[url "ssh://[email protected]/MYORGANIZATION/"] insteadOf = https://github.com/MYORGANIZATION/
to
$HOME/.gitconfig
work like a charm!! Thanks!
DO NOT MISSING THE LAST '/' CHAR!
Note that this issue only applies to the hard-coded hosting sites.
I have reason to believe that this statement may have been mistaken. I plan to investigate further.
This issue somehow ended up in the Proposals queue in Feb. 2021, but I'm not sure why — I think it may be just a bug.
I've started to suspect that this may just be a problem in the way that we probe for which protocol to use.
It appears that both GitHub and GitLab support SSH by having everyone use the username git
, and then treating the public key presented by the user as the “effective user ID”. So probably when we probe for SSH support, in addition to trying ssh
with the user's actual username, we should also try ssh
with the hard-coded username git
.
I'm a little surprised this is still an issue, I've encountered this at 3 different companies over the last 6 years, and we're always doing the .gitconfig InsteadOf dance.
I got here because if you have the following setup this does NOT work:
~/.gitconfig
[includeIf "gitdir:/company/"]
path = /company/.gitconfig-company
/company/.gitconfig-company
[url "[email protected]:"]
insteadOf = https://github.com
[url "[email protected]:company"]
insteadOf = https://github.com:company
I guess because the git commands are being run with the gitdir being inside the GOENV rather than in the project's repo under /company/... ?