On Thu, 19 Dec 2024 at 02:02, brian m. carlson <sandals@xxxxxxxxxxxxxxxxxxxx> wrote: > > On 2024-12-18 at 20:42:31, M Hickford wrote: > > Hi. Is this a bug in git version 2.47.1? Or am I using it incorrectly? > > > > # erase existing example.com credentials > > printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential reject > > # store bearer token with expiry in far future in credential-cache > > printf "host=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n" > > | git credential-cache store > > # try to retrieve credential > > printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential fill > > > > Expected output (complete credential): > > > > protocol=https > > host=example.com > > authtype=bearer > > credential=letmein > > password_expiry_utc=2147483640 > > > > Actual output (incomplete credential, no prompt for username or password): > > > > protocol=https > > host=example.com > > password_expiry_utc=2147483640 > > This is expected. Every request to a credential helper should include > all of the capabilities that the caller supports on input, and the > credential helper will always emit those on output. `git credential`, > however, will only emit the capabilities that were actually supported, > so that general callers (including Git LFS) can determine the actual > set of supported capabilities. > > In this case, you asked the cache helper for a credential, but didn't > tell it that you supported `authtype` and `credential`. Therefore, the > only safe thing it can assume is that you are incapable of parsing and > understanding those fields, so it doesn't emit them. This is a benefit > for security, because some tooling logs all fields but the `password` > field, and we don't want to include new secret fields that the caller is > going to shovel into a file or syslog. > > In addition, the helper could actually store two different sets of > credentials, one which is a username and password, and one which is an > authtype and credential. If you provided the capability, the latter > would be omitted, but otherwise the former would. That can be helpful > if you have a stronger credential type but might occasionally need to > use older software (say, older versions of Git or Git LFS). > > However, if you provide the proper capability, this works as you expect: > > ---- > % printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential reject > % printf "capability[]=authtype\nhost=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n" | git credential-cache store > % printf "capability[]=authtype\nhost=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential fill > capability[]=authtype > authtype=bearer > credential=letmein > protocol=https > host=example.com > password_expiry_utc=2147483640 > ---- > > Note that `capability[]` directives should always start the request to > allow one-pass parsing. I think a bug exists in credential-cache. Below it receives a query *without* capability authtype, upgrades it *with* capability authtype and prints a bearer credential. git credential-cache exit # store bearer credential printf "capability[]=authtype\nhost=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n" | git credential-cache store # query with capability authtype (prints bearer credential as expected) printf "capability[]=authtype\nhost=example.com\nprotocol=https\n" | git credential-cache get # query without capability authtype (expect nothing) printf "host=example.com\nprotocol=https\n" | git credential-cache get If you agree that this is a bug, we could add a test case to helper_test_authtype. Here's a second simpler example of credential-cache of upgrading a request: git credential-cache exit # store credential printf "host=example.com\nprotocol=https\nusername=tim\npassword=hunter2\n" | git credential-cache store # get credential (response is upgraded with capability authtype) printf "host=example.com\nprotocol=https" | git credential-cache get > > Hopefully this is helpful. > -- > brian m. carlson (they/them or he/him) > Toronto, Ontario, CA