-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create .git-credentials to allow secure auth when cloning private repos #711
Conversation
Codecov Report
@@ Coverage Diff @@
## master #711 +/- ##
=======================================
Coverage 72.45% 72.45%
=======================================
Files 61 61
Lines 4679 4679
=======================================
Hits 3390 3390
Misses 1039 1039
Partials 250 250 Continue to review full report at Codecov.
|
Codecov Report
@@ Coverage Diff @@
## master #711 +/- ##
==========================================
- Coverage 72.37% 72.32% -0.05%
==========================================
Files 61 62 +1
Lines 4695 4712 +17
==========================================
+ Hits 3398 3408 +10
- Misses 1044 1052 +8
+ Partials 253 252 -1
Continue to review full report at Codecov.
|
Hi Andrew, thanks for the PR! I'm wondering if we should make this optional based on an environment variable because it's writing the credentials in plaintext to disk? |
Hey. I can see the logic behind that, and am happy to implement that. Do you have any preferences around the variable name? |
Hmm, maybe |
Hmm, I'm wondering if we should actually implement this within Atlantis itself on startup? Because this requires you use environment variables and our Docker container. What about a flag |
Implementing it into Atlantis itself is probably a better solution. I’m happy to give it a shot though I have next to no experience with go. I like |
|
So I'm just in the process of figuring out where to put the logic in the I put something like the below in the respective GitHub, GitLab and Bitbucket blocks here
Or I split it out to its own logic just below it and duplicate the logic around determining which git provider is being used. Do you have any preferences around this? |
I think I've got the basic logic in place now. I have no idea why the testing is saying writeGitCreds is undefined I'm a bit out of my depth here, unfortunately. Would appreciate some pointers and/or assistance in getting this working. |
Well, I figured it out and it's passing now after some swearing on my end. I've squashed it to make it easier to review/merge as desired. Let me know if you want adjustments made. |
@lkysow I think it's ready for review. I'm not sure how to fix the coverage with server.go though. |
Nice! Don't worry about the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome! Final feedback:
- some small changes requested
- please squash your commits
Not in this PR but if you're down to do another one I'd like to:
- Get ssh private cloning working as well. All you need to do is write an additional line to the .gitconfig:
[url "https://TOKEN@github.com"] insteadOf = ssh://git@github.com
- Get this working if using more than one VCS provider. Right now if you're using github and gitlab then it will fail because it tries to overwrite itself.
--write-git-creds will create a .git-credentials file and configure git to use it. To allow authentication with your git remotes over https. To access private repos.
Changes made and commits squashed.
Sure. If you create an issue and assign it to me I'll give it a shot. |
I wouldn't suggest doing that, actually. We shouldn't assume that all repos available over SSH are accessible to this user with their token provided. The Atlantis user is only required to have read access to the repository/repositories being acted upon. Other git operations as a consequence (I'm looking at you, modules), are not necessarily accessible to that Github user. I could see a scenario in which the Atlantis user doesn't even have an SSH key, but various modules that need accessing are given deploy keys that are loaded into the ssh-agent that Atlantis uses. Compartmentalizing access isn't a bad idea, after all :) I'd stick to just HTTPS with this patch and leave SSH as-is.
Github Enterprise is being forgotten here. Please vary all config based on |
Generally speaking, I think we can do a little better here to help avoid the "malicious PRs could exfiltrate credentials" issue.
Another approach could include messing with the credential cache times -- basically set it to infinity so it's in memory and so after first authentication we can kill the on-disk credential entirely. |
How do you expect Terraform to be able to checkout modules via
But then you're storing secrets (ssh keys) in your terraform repo/git? Perhaps I'm misunderstanding your intended workflow here.
I believe the request was to look at doing SSH in a separate PR. I certainly have no intention of doing anything apart from HTTPS in this PR at this point in time. Perhaps in a future PR if/when SSH is looked at it could be added as another flag to alivieate your concerns here.
The code should work fine with Github Enterprise and already makes use of the ATLANTIS_GH_HOSTNAME value. We pass this value to the function on every usage when GitHub user is actually set. https://github.com/ImperialXT/atlantis/blob/master/server/server.go#L161-L165 By default, the Github hostname value is github.com unless overridden via the CLI fags or environment variable ATLANTIS_GH_HOSTNAME.
That could work. I think the only place it'd need to be called would be in |
If the repos are accessed over SSH instead of HTTPS, they could be done with deploy keys as I say below, which are injected into the ssh-agent. The Atlantis Github user doesn't have any relation to these keys at all, hence why rewriting SSH to HTTPS would break things. This isn't actually my workflow, but it doesn't seem implausible and rewriting protocols just struck me as likely to cause issues for someone so I was just playing hypotheticals.
The public key would be a deploy key on the repo on Github, the private key would be injected into the ssh-agent where Atlantis is running (be that Docker container or otherwise). At my last job, we actually wrote some software to allow for SSH keys to be used without exposing the private key to the caller, so this isn't entirely implausible either.
I misunderstood! Carry on then :)
I must've misread something or misunderstood the comments, I guess! Again, carry on!
Oh cool, I wasn't sure if that'd be feasible or not. That'd be a great route and would alleviate a lot of the concerns with exfiltration we see right now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the great PR!
I'd be happy to take a look at a PR that implements the ASK_PASS suggestions but this is a nice improvement for now and is optional for users that don't want to enable.
Currently when Atlantis is running in a docker container it cannot access private repositories without people either pushing ssh private keys into the container with commands at launch or in some cases forking off their own copy where they embed the ssh key/secrets in the image. I'm sure there are a myriad of other ways people are doing it also. None of these are particularly nice options at least personally as then you're providing two sets of secrets instead of one.
GitHub, GitLab and Bitbucket all support push/pull via HTTPS you just need to provide the respective token. git will and does prompt you for the username and password required to authenticate over HTTPS however it is not cached to disk.
Terraform itself doesn't support any sort of environment variables either which would allow it to take care of this. As such we need to use git-credentials-store to configure this as a once off when we run the container. We do this by writing out a
.git-credentials
file into the atlantis users home directory with the relevant information that is already provided to the container as environment variables when launched and then runninggit config --global credential.helper store
as the atlantis user so that it's aware of the.git-credentials
file.This will only affect/work for those who use HTTPS sources.
I've conducted some basic testing on all three providers and didn't run into any issues.
Happy to enhance/tweak as required.