21

I am trying to programmatically clone a git repository. My ASP.NET MVC application is creating and starting a process. The code to handle the processes works correctly however the authentication is failing when trying to use a TFS on premise PAT to clone a git repository. I cannot use NTLM or require the user to enter credentials. I can confirm my C# code handling creating processes to use the git bash shell programmatically works as I have no issue on my local machine but in production on IIS the issue arises. I have tried the following two methods.

Method 1: git clone http://anyusername:PAT@tfs2017:8080/tfs/DefaultCollection/_git/Git%20Repository

PAT is the token I have generated for my user. I have tried to encode it in base64 as well.

Method 2: As suggested by a person on a MS social forum.

git -c http.extraheader="AUTHORIZATION:bearer {base64encodedPAT}" clone {url}

Original MS Forum Question for Reference: https://social.msdn.microsoft.com/Forums/vstudio/en-US/0107cf1f-7fe4-4429-af74-ca7d2be7405e/using-personal-access-tokens-in-tfs-2017?forum=tfsversioncontrol

cloutcomputer
  • 233
  • 1
  • 2
  • 7

6 Answers6

23

If you have a PAT, you should not need a password: the PAT would act as your username.
See if the following works:

git clone http://PAT@tfs2017:8080/tfs/DefaultCollection/_git/Git%20Repository
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • This prompts the git credential manager with the PAT as the username. Now for testing sake, if I move the PAT into the password field and supply a blank username I can authenticate and the clone the repository. – cloutcomputer Aug 16 '17 at 16:21
  • 1
    @Marcus Do you mean that `http://:PAT@tfs2017:8080/tfs/DefaultCollection/_git/Git%20Repository`? Wit `:PAT`meaning no username, PAT as a password? – VonC Aug 16 '17 at 21:10
  • I tried your above suggestion with the URL to my repository and I get an authentication failed from the command line. – cloutcomputer Aug 16 '17 at 22:24
  • @Marcus Please try to install Git Credential Manager on your client machine. Credential Manager is included in the latest version of git (2.11), which you can download from [here](https://git-scm.com/download/win). When Credential Manager prompts you for credentials, make sure to specify empty user name and your PAT token as password. – Andy Li-MSFT Aug 22 '17 at 09:59
  • Andy this is not a solution. I am trying to programmatically do this in code and there is no way for the user to access that dialog box. This method works with the git credential manager but this is not what I'm asking. – cloutcomputer Aug 22 '17 at 15:58
  • 1
    I'm fairly certain no one is actually reading my question. I clearly state this is all being done in code therefore accessing the git credential manager is literally impossible. – cloutcomputer Aug 22 '17 at 16:09
  • 1
    I tried `the command in the answer` in a fresh environment and it's working. – Ajeeb.K.P Oct 24 '18 at 12:57
  • Why on earth do they not not document this better. Git forces us to stop using password authentication and then doesn't tell us how to use PAT. Great stuff guys thanks. – James Baird May 08 '22 at 19:54
11

I was a bit confused after reading the article from MS. After trying out some ways, I was finally able to use my PAT against TFS and VSTS GIT Repos.

The only way I was able to get a clone of my GIT repo using a PAT was setting the http.extraheader in the GIT commandline.
The authorization tag must point to basic authentication, the protocol must be HTTPS, and the token must be BASE64 encoded, including a (fictional) user name.

Example:

git -c http.extraheader="AUTHORIZATION: Basic TXlHaXRTeW5jVXNlcjo2bHFqNXJkcHEzdXBxZWVmd2o3bDduZXN5NTR3d3gxNHFobDVlanl5NTVkb2g0M3d4YzRh" clone https://tfs.address/tfs/Collection/Project/_git/RepoName

Used basic token BASE64 encoded:

TXlHaXRTeW5jVXNlcjo2bHFqNXJkcHEzdXBxZWVmd2o3bDduZXN5NTR3d3gxNHFobDVlanl5NTVkb2g0M3d4YzRh

Basic Token BASE64 decoded:

MyGitSyncUser:6lqj5rdpq3upqeefwj7l7nesy54wwx14qhl5ejyy55doh43wxc4a

Token is constructed from <fictional user name>:<PAT from a user with rights in the project>

In this example:

Fictional user name: MyGitSyncUser Used PAT: 6lqj5rdpq3upqeefwj7l7nesy54wwx14qhl5ejyy55doh43wxc4a

PAT scope: Code (Read)

The TFS/VSTS doesn't accept "AUTHORIZATION: Bearer" headers at the moment :(

Maybe this will help someone using the PATs in TFS/VSTS.

Note: HTTPS is needed for BASIC Authentication!

Community
  • 1
  • 1
Clemens Sutor
  • 136
  • 1
  • 4
  • 1
    i tried this and was prompted for username & password still. – Ben A Oct 10 '18 at 13:13
  • 1
    This works for me... you're my hero! Just to add some detail, though: my experience (with TFS Server, not Azure DevOps) suggests that the user name MUST be empty when a token is provided. My solution was: TFS_AUTH=$(echo -n ":${TFS_TOKEN}" | base64) , then use TFS_AUTH in conjunction with the HTTP basic auth header above. – Jeff W Apr 06 '22 at 12:48
  • steps to covert PAT to Base64 and use with git https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#use-a-pat – 31 bit Sep 21 '22 at 04:01
7

Just adding my 2c since I've spent hours on this.

I generated the PAT from DevOps and copied the clone URL but I kept get "repository not found"

GIT clone https://<PAT>@dev.azure.com/Organization/My%20Project/_git/MyRepo

Note the project has a space in it and is URLEncoded

This won't work in DOS - it resolves to

My0Project

You need to double escape it like so:

GIT clone https://<PAT>@dev.azure.com/Organization/My%%20Project/_git/MyRepo
Nick.Mc
  • 18,304
  • 6
  • 61
  • 91
4

You can use the CredentialManager by programmatically adding the token to the machine, the same way CredentialManager would do it.
On Windows I use the cmdkey tools as follow:

cmdkey /generic:"git:https://yourdomain.visualstudio.com" /user:"Personal Access Token" /pass:"yourtokenhere"

On MacOS add an entry in the keychain:

security add-generic-password -a "Personal Access Token" -D "Credential" -s "gcm4ml:git:https://yourdomain.visualstudio.com" -w "yourtokenhere" -A

Note: Avoid using -A which allows any application to access it.

As long as the CredentialManager is installed on Git, it should work.

Maxime
  • 1,095
  • 1
  • 11
  • 20
2

Thanks to Clemens on the excellent answer above, but I wanted to update his response with my experience on TFS server.

TFS Server (on premise, not Azure DevOps) will only take a token if the user name field is empty, meaning that the (non-base64-encoded) Basic authorization is of the format ":TFS_TOKEN".

I tried using GIT_ASKPASS with a script which returned an empty username and the token, but it would not work. When I began looking with wireshark, I found that my git CLI chose to use NTLM over Basic auth. There may be a way to tell git to use Basic over NTLM, but I couldn't find it.

This question (and Clemens' answer) led me to this approach:

$ TFS_TOKEN="...."
$ TFS_AUTH=$(echo -n ":${TFS_TOKEN}" | base64)
$ git clone -c http.extraheader="Authorization: Basic ${TFS_AUTH}" https://...
Jeff W
  • 414
  • 5
  • 16
0

For GitHub, use this format (https:// is a must):

git clone https://[PAT]@github.com/[your repo link].git
TheTechRobo the Nerd
  • 1,249
  • 15
  • 28