Re: credential-helpers + remote-helper, starting point?

Subsystems: documentation, the rest

2 messages, 2 authors, 2016-06-15 · open the first message on its own page

Re: credential-helpers + remote-helper, starting point?

From: Matthieu Moy <hidden>
Date: 2016-06-15 22:53:54

Jeff King [off-list ref] writes:
  https://github.com/git/git/blob/master/Documentation/technical/api-credentials.txt
I just re-read that document (I had a quick glance only before), and
started to understand. I think the document really lacks the "big
picture". I took time to understand whether the API was to call
credential helpers, or to write a new one. Actually, there are two
"API": the C one, and the specification of what may flow on the pipe
between the two processes.

Perhaps something like this should be added:

Subject: [PATCH] credential-helper documentation: show the big picture first

---
 Documentation/technical/api-credentials.txt |   47 +++++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 3 deletions(-)
diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt
index 21ca6a2..5a872c0 100644
--- a/Documentation/technical/api-credentials.txt
+++ b/Documentation/technical/api-credentials.txt
@@ -6,8 +6,40 @@ password credentials from the user (even though credentials in the wider
 world can take many forms, in this document the word "credential" always
 refers to a username and password pair).
 
+When a function in Git or one of its remote-helpers needs to obtain
+credentials (either by asking the user or by fetching from a store),
+it can call the functions in the C API. These functions will fork a
+new process, and communicate with it by passing command-line arguments
+and then communicating through a pipe (see 'Credential Helpers'
+below). The credential helper process will be in charge of actually
+prompting the user and/or storing and fetching the credentials.
+
+For example, the execution of a command connecting to an HTTP server
+and using the credential helper "cache" will have the following
+structure:
+
+------------
++-----+ -----> +-----------------+
+| git |  pipe  | git remote-http | --- to HTTP server --->
++-----+ <----- +-----------------+
+                    ^      |
+                    | pipe |
+                    |      v
+             +----------------------+
+             | git credential-cache |
+             +----------------------+
+------------
+
+git remote-http will take care of contacting the HTTP server, do the
+actual authentication and see if it's accepted by the server. The
+credential helper will deal with the credential store (which can be
+done by contacting a keyring daemon) and the prompting if needed.
+
+C API
+-----
+
 Data Structures
----------------
+~~~~~~~~~~~~~~~
 
 `struct credential`::
 
@@ -28,7 +60,7 @@ This struct should always be initialized with `CREDENTIAL_INIT` or
 
 
 Functions
----------
+~~~~~~~~~
 
 `credential_init`::
 
@@ -72,7 +104,7 @@ Functions
 	Parse a URL into broken-down credential fields.
 
 Example
--------
+~~~~~~~
 
 The example below shows how the functions of the credential API could be
 used to login to a fictitious "foo" service on a remote host:
@@ -130,6 +162,9 @@ int foo_login(struct foo_connection *f)
 Credential Helpers
 ------------------
 
+Choosing the credential helper command
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 Credential helpers are programs executed by git to fetch or save
 credentials from and to long-term storage (where "long-term" is simply
 longer than a single git process; e.g., credentials may be stored
@@ -176,6 +211,9 @@ users by naming their program "git-credential-$NAME", and putting it in
 the $PATH or $GIT_EXEC_PATH during installation, which will allow a user
 to enable it with `git config credential.helper $NAME`.
 
+Credential helper command-line arguments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 When a helper is executed, it will have one "operation" argument
 appended to its command line, which is one of:
 
@@ -191,6 +229,9 @@ appended to its command line, which is one of:
 
 	Remove a matching credential, if any, from the helper's storage.
 
+Credential helper protocol
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 The details of the credential will be provided on the helper's stdin
 stream. The credential is split into a set of named attributes.
 Attributes are provided to the helper, one per line. Each attribute is
-- 
1.7.10.363.g7fcd3d.dirty

Also, shouldn't the documentation about choosing the command name be
moved to git-config.txt, to document credential.helper? It really seems
to be a user documentation, not a technical one meant for Git
developers.

> But that is the C API, and I assume you are building on the existing
> mediawiki helper that is written in perl.

Right.

> So I think what you really want is a "git credential" command that
> will let scripts hook into the credential API. Something like:
>
>   $ git credential get https://example.com
>   username=bob
>   password=secret
> [...]

This is almost already done by test-credential.c indeed. But that's
probably the simplest way to expose the C API to a perl program.

> Do you guys want to try writing "git credential" as above? It might be a
> fun side project, but I know you are also on a limited timeframe for
> your project. I can work on it if you don't have time.

I leave it up to the students.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

Re: credential-helpers + remote-helper, starting point?

From: Jeff King <hidden>
Date: 2016-06-15 22:53:54

On Thu, May 24, 2012 at 09:20:08PM +0200, Matthieu Moy wrote:
Jeff King [off-list ref] writes:
quoted
  https://github.com/git/git/blob/master/Documentation/technical/api-credentials.txt
I just re-read that document (I had a quick glance only before), and
started to understand. I think the document really lacks the "big
picture". I took time to understand whether the API was to call
credential helpers, or to write a new one. Actually, there are two
"API": the C one, and the specification of what may flow on the pipe
between the two processes.
Right. There are really two audiences for this document: people who are
writing git code that wants to use credentials, and people who want to
write a helper. And it probably makes sense to say that up front, and
point people to the right section.
quoted hunk
diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt
index 21ca6a2..5a872c0 100644
--- a/Documentation/technical/api-credentials.txt
+++ b/Documentation/technical/api-credentials.txt
@@ -6,8 +6,40 @@ password credentials from the user (even though credentials in the wider
 world can take many forms, in this document the word "credential" always
 refers to a username and password pair).
 
+When a function in Git or one of its remote-helpers needs to obtain
+credentials (either by asking the user or by fetching from a store),
+it can call the functions in the C API. These functions will fork a
+new process, and communicate with it by passing command-line arguments
+and then communicating through a pipe (see 'Credential Helpers'
+below).
We might or might not fork a new process. It depends on which helpers
are defined.
The credential helper process will be in charge of actually
+prompting the user and/or storing and fetching the credentials.
That's not exactly true; the C credential code will actually prompt the
user if no helper provides it (in early versions, the helpers were
responsible for prompting, but that is no longer the case).
+For example, the execution of a command connecting to an HTTP server
+and using the credential helper "cache" will have the following
+structure:
+
+------------
++-----+ -----> +-----------------+
+| git |  pipe  | git remote-http | --- to HTTP server --->
++-----+ <----- +-----------------+
+                    ^      |
+                    | pipe |
+                    |      v
+             +----------------------+
+             | git credential-cache |
+             +----------------------+
+------------
+
+git remote-http will take care of contacting the HTTP server, do the
+actual authentication and see if it's accepted by the server. The
+credential helper will deal with the credential store (which can be
+done by contacting a keyring daemon) and the prompting if needed.
I feel like adding remote-helpers into the mix just makes the situation
more complex (and necessitates the diagram). I also don't want to get
too much into "how it works inside" and would rather stay at the level
of "here's how you use it".

What do you think of the patch below? It tries to route the reader to
the most useful spot, and it would naturally extend to mentioning a "git
credential" command when one exists (which would be separately
documented in git-credential.txt).

---
diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt
index 21ca6a2..f6fa203 100644
--- a/Documentation/technical/api-credentials.txt
+++ b/Documentation/technical/api-credentials.txt
@@ -6,8 +6,27 @@ password credentials from the user (even though credentials in the wider
 world can take many forms, in this document the word "credential" always
 refers to a username and password pair).
 
+This document describes two interfaces: the C API that the credential
+subsystem provides to the rest of git, and the protocol that git uses to
+communicate with system-specific "credential helpers". If you are
+writing git code that wants to look up or prompt for credentials, see
+the section "C API" below. If you want to write your own helper, see
+the section on "Credential Helpers" below.
+
+
+C API
+-----
+
+The credential C API is meant to be called by git code which needs to
+acquire or store a credential. It is centered around an object
+representing a single credential and provides three basic operations:
+fill (acquire credentials by calling helpers and/or prompting the user),
+approve (mark a credential as successfully used so that it can be stored
+for later use), and reject (mark a credential as unsuccessful so that it
+can be erased from any persistent storage).
+
 Data Structures
----------------
+~~~~~~~~~~~~~~~
 
 `struct credential`::
 
@@ -28,7 +47,7 @@ This struct should always be initialized with `CREDENTIAL_INIT` or
 
 
 Functions
----------
+~~~~~~~~~
 
 `credential_init`::
 
@@ -72,7 +91,7 @@ Functions
 	Parse a URL into broken-down credential fields.
 
 Example
--------
+~~~~~~~
 
 The example below shows how the functions of the credential API could be
 used to login to a fictitious "foo" service on a remote host:
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help