Subject: Re: [PATCH v4 2/6] config: add new way to pass config via `--config-env`

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Wed, 09 Dec 2020 15:40:17 +0100

On Wed, Dec 09 2020, Patrick Steinhardt wrote:

> While it's already possible to pass runtime configuration via `git -c
> <key>=<value>`, it may be undesirable to use when the value contains
> sensitive information. E.g. if one wants to set `http.extraHeader` to
> contain an authentication token, doing so via `-c` would trivially leak
> those credentials via e.g. ps(1), which typically also shows command
> arguments.
>
> To enable this usecase without leaking credentials, this commit
> introduces a new switch `--config-env=<key>=<envvar>`. Instead of
> directly passing a value for the given key, it instead allows the user
> to specify the name of an environment variable. The value of that
> variable will then be used as value of the key.
> [...]
> +--config-env=<name>=<envvar>::
> +	Pass a configuration parameter to the command. The <envvar>
> +	given will be replaced with the contents of the environment
> +	variable of that name. In contrast to `-c`, an envvar must
> +	always be given and exist in the environment. Passing an
> +	environment variable with empty value will set <name> to the
> +	empty string which `git config --type=bool` will convert to
> +	`false`.

Okey, because "-c foo.bar" (true) "-c foo.bar=" is the empty string, but
that doesn't make sene with "--config-env". Also the whole part about
--type=bool is just confusing, because it's referring to `-c`'s magic
behavior when it comes to `bool` which we don't have here.

I think it's also worth describing what this is for & what the
limitations are. Maybe:

    --config-env=<name>=<envvar>

        Like `-c <name>=<var>` except the value is the name of an
        environment variable from which to retrieve the value. Unlike
        `-c` there is no shortcut for directly setting the value to an
        empty string, instead the environment variable itself must be
        set to the empty strin. Errors if the `<envvar>` does not exist
        in the environment.

        This is useful for cases where you want to pass transitory
        configuration options to git, but are doing so on OS's where
        other processes might be able to read your cmdline
        (e.g. `/proc/self/cmdline`), but not your environ
        (e.g. `/proc/self/environ`). That behavior is the default on
        Linux, but may not be on your system.

	Note that this might add security for variables such as
	`http.extraHeader` where the sensitive information is part of
	the value, but not e.g. `url.<base.insteadOf` where the
	sensitive information can be part of the key.

> +void git_config_push_env(const char *spec)
> +{
> +	struct strbuf buf = STRBUF_INIT;
> +	const char *env_name;
> +	const char *env_value;
> +
> +	env_name = strrchr(spec, '=');
> +	if (!env_name)
> +		die("invalid config format: %s", spec);
> +	env_name++;

Not something new, and maybe not something for this series, but I wish
-c and --config-env would document this limitation that we support "="
in keys in config, but not via those parameters.