gitgithubpasswordshelpercredential-manager

How to create a Git credential helper? (Windows)


I'm trying to create basic credential helper for Git (Windows version).

Based on documentation it seemed to be trivial:

@echo off
echo username=USER
echo password=ghp_<rest of the token>

After trying it I've got an error: remote: Invalid username or token. Password authentication is not supported for Git operations.

First I've doublechecked the password (= token), but I always got the same error.

Nevertheless, when I enter username and password (= token) manually from keyboard (= without GIT_ASKPASS and token.bat), authentication is successful and push command (or any other request requiring authentication) is correctly performed.

After long googling I've found possibility to debug the Git:

set GIT_TRACE=1
set GIT_CURL_VERBOSE=1

and compared outputs after manually entered username and password (token) and for generated username and password (token) from token.bat credential helper (please note username and project name have been edited to "USER" and "PROJECT"):

Manually entered credentials:

10:10:31.884654 http.c:868              == Info: Server auth using Basic with user 'USER'
10:10:31.884654 http.c:815              => Send header, 0000000305 bytes (0x00000131)
10:10:31.884654 http.c:827              => Send header: GET /USER/PROJECT/info/refs?service=git-receive-pack HTTP/1.1
10:10:31.884654 http.c:827              => Send header: Host: github.com
10:10:31.884654 http.c:827              => Send header: Authorization: Basic <redacted>
10:10:31.884654 http.c:827              => Send header: User-Agent: git/2.45.2.windows.1
10:10:31.884654 http.c:827              => Send header: Accept: */*
10:10:31.884654 http.c:827              => Send header: Accept-Encoding: deflate, gzip, br, zstd
10:10:31.884654 http.c:827              => Send header: Pragma: no-cache
10:10:31.884654 http.c:827              => Send header:
10:10:31.884654 http.c:868              == Info: Request completely sent off
10:10:32.197182 http.c:815              <= Recv header, 0000000017 bytes (0x00000011)
10:10:32.197182 http.c:827              <= Recv header: HTTP/1.1 200 OK

Credentials from token.bat helper:

09:59:34.551416 http.c:868              == Info: Server auth using Basic with user 'username=USER'
09:59:34.551416 http.c:815              => Send header, 0000000289 bytes (0x00000121)
09:59:34.551416 http.c:827              => Send header: GET /USER/PROJECT/info/refs?service=git-receive-pack HTTP/1.1
09:59:34.551416 http.c:827              => Send header: Host: github.com
09:59:34.551416 http.c:827              => Send header: Authorization: Basic <redacted>
09:59:34.551416 http.c:827              => Send header: User-Agent: git/2.45.2.windows.1
09:59:34.551416 http.c:827              => Send header: Accept: */*
09:59:34.551416 http.c:827              => Send header: Accept-Encoding: deflate, gzip, br, zstd
09:59:34.551416 http.c:827              => Send header: Pragma: no-cache
09:59:34.551416 http.c:827              => Send header:
09:59:34.551416 http.c:868              == Info: Request completely sent off
09:59:34.739252 http.c:815              <= Recv header, 0000000027 bytes (0x0000001b)
09:59:34.739252 http.c:827              <= Recv header: HTTP/1.1 401 Unauthorized

It looks like Git parses the username from "echo username=USER" as "username=USER" instead of just "USER".

Is it a Git bug, or do I understand the online documentation and lots of examples incorrectly?


Solution

  • As mentioned phd in comments, script is not used as a credential helper, but just a password filler.

    Solution is either

    1. echo ghp_<rest of the token> in case of triggering using `GIT_ASKPASS`

      or

    2. keep script from the question, but trigger it using configuration of credential helpers, e.g. git config --global credential.helper "token.bat"` or temporarily `git -c credential.helper="token.bat" <further commands>