3

When simply using the command line, the main strategy would be to use the cache git credential helper:

git config --global credential.helper cache
git config --global credential.username {{ gituser }}
git pull {{ repository1 }}
... asks password
... pulls
git pull {{ repository2 }}
... pulls
... etc.

But if I use the ansible git module, prompting does not work (nor is it practical). The only solution I currently see is to use:

- git: repo=https://{{ gituser }}:{{ gitpass }}@{{ repo_url }} dest={{ dest }}

Where I get gituser and gitpass using vars_prompt:, or from ansible's local secure storage. However, this has the unfornutate side effect that it stores the password in {{ dest }}/.git/config in plain text, which I would like to avoid.

Is there a way to set the password from ansible for the time of the playbook run, but not to store it on the server?

P.Péter
  • 569
  • 2
  • 6
  • 24

2 Answers2

3

Is there a way to set the password from ansible for the time of the playbook run, but not to store it on the server?

The ansible git module doesn't currently have a way to specify the password be ephemeral, i.e. to ensure it is erased from the .git directory after the upstream repository has been cloned.

You could "hack" this by invoking the command module after the invocation of the git module to remove the upstream remote from the repository configuration, which will obviously remove any secrets. This does mean the secret is temporarily stored on the host during the pull operation -- this may not be suitable depending upon the threat model you are working under.


A better way?

These scenarios are where SSH key authentication comes to the fore, per EEAA's comment. If you can authenticate to your git upstream using SSH, you can use SSH agent forwarding in your Ansible session to pass your SSH agent from the control host through to the target server.

This is a robust method of credential sharing which only survives for the duration of the session, so the long-term risks of secrets being left on the remote host are minimised.

Cosmic Ossifrage
  • 1,640
  • 14
  • 23
  • Unfortunately, ssh git authentication is not available. However, is it possible to ssh-tunnel a local git credential helper, e.g. git-credential-gnome-keyring? – P.Péter Apr 18 '16 at 13:50
  • The hack above is certainly an option, by the way. I have thought of something like that, but did not want to do all that hassle. – P.Péter Apr 18 '16 at 13:52
  • One more: `git remote remove origin` is not enough to remove all on-disk secrets, as the password is written to various files in .git/logs/. – P.Péter Apr 19 '16 at 09:38
1

In the end, I went with a solution similar to the hack @CosmicOssifrage mentions. The main difference is that git remote remove origin is not enough to remove all secrets, as the password is written to various files in .git/logs/. So at the end I simply created an include file that calls sed to clean up the mess:

- name: git password cleanup
  shell: cd {{ git_dir }}/.git ; sed -i 's/https:\/\/{{ gituser }}:{{ gitpass }}@/https:\/\/{{ gituser }}@/' config logs/HEAD logs/refs/heads/* logs/refs/remotes/*/*

This is called like:

- git: repo={{ repository }} dest=/var/www/
- include: ../../library/git_password_cleanup.yml git_dir=/var/www/

What this fails to address is if the git checkout fails for some reason, the next command will not be run, thus leaving the credentials there. The solution would be quite awkward with current ansible failure handling tactics, so I chose to take that risk.

P.Péter
  • 569
  • 2
  • 6
  • 24