git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 05/13] credential: gate new fields on capability

From
brian m. carlson <sandals@crustytoothpaste.net>
Date
Mar 27, 2024, 21:33 UTC
Message-ID
<ZgSQr7uQdIA8oVNn@tapette.crustytoothpaste.net>
In-Reply-To
<ZgPSn_D8luXQyZGf@tanuki>
On 2024-03-27 at 08:02:39, Patrick Steinhardt wrote:
Show 40 quoted lines
> On Sun, Mar 24, 2024 at 01:12:53AM +0000, brian m. carlson wrote:
> > +static int credential_has_capability(const struct credential_capability *capa, int op_type)
> > +{
> > +	/*
> > +	 * We're checking here if each previous step indicated that we had the
> > +	 * capability.  If it did, then we want to pass it along; conversely, if
> > +	 * it did not, we don't want to report that to our caller.
> > +	 */
> > +	switch (op_type) {
> > +	case CREDENTIAL_OP_HELPER:
> > +		return capa->request_initial;
> > +	case CREDENTIAL_OP_RESPONSE:
> > +		return capa->request_initial && capa->request_helper;
> > +	default:
> > +		return 0;
> > +	}
> > +}
> 
> I think I'm missing the bigger picture here, so please bear with me.
> 
> What you provide here is simply an `op_type` that indicates the phase we
> are currently in and thus allows us to check whether all of the
> preceding phases had the capability set. But to me it seems like a phase
> and the actual capability should be different things. So why is it that
> the capability seems to be a mere boolean value instead of something
> like a bitfield indicating whether a specific capability is supported or
> not? Or is all of this infra really only to support a single capability,
> namely the credential capability?
> 
> I'm mostly coming from the angle of how capabilities work with remote
> helpers. When asked, the helper will announce a set of capabilities that
> it supports, e.g. "capabilities stateless-connect". So from thereon the
> client of the helper knows that it can assume "stateless-connect" to be
> understood by the helper.
> 
> I would have expected capabilities to work similarly for the credential
> helper, where it announces "I know to handle pre-encoded credentials".
> But given that I have basically no clue at all for how the credential
> helper works there may very well be good reasons why things work so
> differently here.

Let me explain a little bit. There are two possible flows that we can have for a credential request:

  git-credential input -> credential.c -> helper -> credential.c -> git-credential output
  git-http-backend -> credential.c -> helper -> credential.c -> git-http-backend

Let's look at the first one (which might, say, come from Git LFS or another external tool), but the second one works similarly. When we get a request from `git credential fill`, we need to know first whether the requester supports the capability. If we're using an external tool from last decade, it's not going to do so.

If it _does_ support that, then we want to pass that along to the helper, but if it doesn't, we don't. That's because if the caller doesn't support `credential` and `authtype`, the helper might legitimately want to provide a username and password (or token) instead, knowing that that's more likely to work.

Similarly, in the final response, we want to indicate to the external caller whether the capability was in fact supported. That's useful to know in case we want to pass the response back to `git credential store`, and it also discloses functionality about what the credential helper in use supports.

We can't assume that the helper does or doesn't support the same capabilities as Git because it might come from outside Git (e.g., Git Credential Manager Core, or a site-specific credential helper) or it just might not be capable of storing or handling that kind of credential. By not making the assumption that the helper is implicitly capable, we allow users to continue to use very simple shell scripts as credential helpers.

As to why this functionality exists, it exists to support the two new capabilities in this series, `credential` and `state`. A pie in the sky goal for the future is to support additional request signing functionality, so it might learn things like method, URI, and TLS channel binding info, which would be an additional capability. (I might implement that, or I might not.) All of those are boolean: they either are supported, or not. If folks in the future want to expose non-boolean capabilities, I don't think that should be a problem.

Show 17 quoted lines
> > +/*
> > + * These values define the kind of operation we're performing and the
> > + * capabilities at each stage.  The first is either an external request (via git
> > + * credential fill) or an internal request (e.g., via the HTTP) code.  The
> > + * second is the call to the credential helper, and the third is the response
> > + * we're providing.
> > + *
> > + * At each stage, we will emit the capability only if the previous stage
> > + * supported it.
> > + */
> > +#define CREDENTIAL_OP_INITIAL  1
> > +#define CREDENTIAL_OP_HELPER   2
> > +#define CREDENTIAL_OP_RESPONSE 3
> 
> Is there any specific reason why you're using defines instead of an enum
> here? I think the latter would be more self-explanatory when you see
> that functions take `enum credential_op` as input instead of an `int`.

I think an enum would be a nice improvement. I'll include that in a reroll.

-- 
brian m. carlson (they/them or he/him)
Toronto, Ontario, CA
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 9 of 66 in “Support for arbitrary schemes in credentials”
  1. 00/13 Support for arbitrary schemes in credentialsbrian m. carlson, Mar 24, 2024
  2. 09/13 credential: enable state capabilitybrian m. carlson, Mar 24, 2024
  3. 08/13 credential: add an argument to keep statebrian m. carlson, Mar 24, 2024
  4. mirth hickfordApr 1, 2024
  5. brian m. carlsonApr 1, 2024
  6. 10/13 docs: set a limit on credential line lengthbrian m. carlson, Mar 24, 2024
  7. 05/13 credential: gate new fields on capabilitybrian m. carlson, Mar 24, 2024
  8. Patrick SteinhardtMar 27, 2024
  9. brian m. carlsonMar 27, 2024
  10. Patrick SteinhardtApr 2, 2024
  11. brian m. carlsonApr 4, 2024
  12. Patrick SteinhardtApr 4, 2024
  13. Jeff KingMar 28, 2024
  14. Junio C HamanoMar 28, 2024
  15. Jeff KingMar 28, 2024
  16. Junio C HamanoMar 28, 2024
  17. brian m. carlsonMar 28, 2024
  18. 07/13 http: add support for authtype and credentialbrian m. carlson, Mar 24, 2024
  19. 06/13 docs: indicate new credential protocol fieldsbrian m. carlson, Mar 24, 2024
  20. M HickfordMar 25, 2024
  21. brian m. carlsonMar 25, 2024
  22. M HickfordMar 30, 2024
  23. brian m. carlsonMar 31, 2024
  24. 12/13 strvec: implement swapping two strvecsbrian m. carlson, Mar 24, 2024
  25. Patrick SteinhardtMar 27, 2024
  26. Junio C HamanoMar 27, 2024
  27. brian m. carlsonMar 27, 2024
  28. 11/13 t5563: refactor for multi-stage authenticationbrian m. carlson, Mar 24, 2024
  29. 13/13 credential: add support for multistage credential roundsbrian m. carlson, Mar 24, 2024
  30. M HickfordMar 28, 2024
  31. brian m. carlsonMar 28, 2024
  32. M HickfordApr 1, 2024
  33. 02/13 remote-curl: reset headers on new requestbrian m. carlson, Mar 24, 2024
  34. 03/13 http: use new headers for each object requestbrian m. carlson, Mar 24, 2024
  35. Patrick SteinhardtMar 27, 2024
  36. 04/13 credential: add a field for pre-encoded credentialsbrian m. carlson, Mar 24, 2024
  37. 01/13 credential: add an authtype fieldbrian m. carlson, Mar 24, 2024
  38. Junio C HamanoMar 24, 2024
  39. brian m. carlsonMar 24, 2024
  40. Junio C HamanoMar 24, 2024
  41. M HickfordMar 30, 2024
  42. M HickfordMar 30, 2024
  43. Calvin WanApr 2, 2024
  44. brian m. carlsonApr 4, 2024
  45. Jackson ToeniskoetterApr 8, 2024
  46. M HickfordApr 11, 2024
  47. brian m. carlsonApr 12, 2024
  48. M HickfordApr 11, 2024
  49. brian m. carlsonApr 12, 2024
  50. 00/16 Support for arbitrary schemes in credentialsbrian m. carlson, Apr 17, 2024
  51. 02/16 remote-curl: reset headers on new requestbrian m. carlson, Apr 17, 2024
  52. 03/16 http: use new headers for each object requestbrian m. carlson, Apr 17, 2024
  53. 04/16 credential: add a field for pre-encoded credentialsbrian m. carlson, Apr 17, 2024
  54. 01/16 credential: add an authtype fieldbrian m. carlson, Apr 17, 2024
  55. 06/16 credential: add a field called "ephemeral"brian m. carlson, Apr 17, 2024
  56. 05/16 credential: gate new fields on capabilitybrian m. carlson, Apr 17, 2024
  57. 07/16 docs: indicate new credential protocol fieldsbrian m. carlson, Apr 17, 2024
  58. 11/16 docs: set a limit on credential line lengthbrian m. carlson, Apr 17, 2024
  59. 09/16 credential: add an argument to keep statebrian m. carlson, Apr 17, 2024
  60. 10/16 credential: enable state capabilitybrian m. carlson, Apr 17, 2024
  61. 12/16 t5563: refactor for multi-stage authenticationbrian m. carlson, Apr 17, 2024
  62. 08/16 http: add support for authtype and credentialbrian m. carlson, Apr 17, 2024
  63. 14/16 t: add credential tests for authtypebrian m. carlson, Apr 17, 2024
  64. 13/16 credential: add support for multistage credential roundsbrian m. carlson, Apr 17, 2024
  65. 15/16 credential-cache: implement authtype capabilitybrian m. carlson, Apr 17, 2024
  66. 16/16 credential: add method for querying capabilitiesbrian m. carlson, Apr 17, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.