kubernetes / git-sync

A sidecar app which clones a git repo and keeps it in sync with the upstream.
Apache License 2.0
2.16k stars 409 forks source link

submodule specific credentials #796

Closed qcho closed 9 months ago

qcho commented 10 months ago

Hi,

I've been using git-sync v4.0.0 without any issues until I stumbled upon a repository with git-submodules. At first glance it should work but the credentials strategy i'm currently using isn't compatible.

I'm creating specific "project access tokens" so that i can access repositoryA with usernameA and passwordA; but in this case repositoryA depends of repositoryB. When the sync pulls repositoryB I get an invalid username error message since the ones provided in the env via GITSYNC_USERNAME/PASSWORD don't match.

I've tried to use the GITSYNC_ASKPASS_URL and start a service that will provide credentials but in the askpass request i don't get any information of what repo is being asked so provide a dynamic response.

I also tried to create a .git-credentials file but failed.

Any recommended solution that I'm missing or feature that i can help with?

Thanks in advance! Great tool.

Context info:

thockin commented 10 months ago

Is this new with v4 or the same in v3?

I don't think we have any particular affordance for different credentials, so it's not surprising it would fail this way. How would you do this manually?

thockin commented 10 months ago

As a hack, could you use $GIT_SYNC_GIT_CONFIG with a value like "credential.repositoryB.username":usernameB,"credential.repositoryB.password":passwordB ?

To really solve this, we maybe need to accept a list of (URL, username, password) tuples to store in the credentials cache. Not sure how that interacts with askpass, either.

qcho commented 10 months ago

Hi, I'm using v4, never used v3.

Understand that manually is, kind of, the hack you proposed. Tried it but was much more obscure since .password in "credential.repositoryB.password":passwordB is not a valid credential property.

Had to create a custom helper by adding .helper as explained in https://git-scm.com/docs/gitcredentials that shares the hardcoded password:

GIT_SYNC_GIT_CONFIG='"credential.https://repoB.net.git.username":userB,"credential.https://repoB.net.git.helper":"!f() { test \"$1\" = get && echo \"password=passB\"; }; f"'

Probably, considering the complexity of this pragmatic solution having a map of url,user,pass somewhere in the config may be of value. In particular in my usecase i have recursive submodules and needed to add various configs in this manner.

thockin commented 10 months ago

Ahh, right. Internally we use the cache helper via credential approve.

So the open question is how to feed those in to git-sync. We could do something like:

--extra-credential='{"url":"http://whatever", "username":"joe.blow", "password":"hunter2"}' \
--extra-credential='{"url":"http://another", "username":"jblow", "password":"hunter2!"}' 

The problem is that we support a variety of credential feeds - username/passwd, askpass, password file, ssh.

I'll need to think more about how to do this.

thockin commented 10 months ago

It would be good to get an e2e set up to test this case - e.g. a repo that wants one password with 2 submodules that want different passwords. We could run 3 containers with 3 local IPs, set up the main repo and submodules, then point git-sync at it. Then I could test all the modes.

thockin commented 10 months ago

I can't seem to make a case where git credential approve satisfies an SSH password (not key) request. I added multiple SSH key support and that seems to be happy. I can add multiple username/password/password-file fairly easily but I don't want to do that unless I have a test.

Maybe I should figure out a local HTTP-based test instead of SSH.

As always, help is welcome, otherwise I will get to it when I get to it.