public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
From: Christian Couder <christian.couder@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
	Patrick Steinhardt <ps@pks.im>, Taylor Blau <me@ttaylorr.com>,
	Karthik Nayak <karthik.188@gmail.com>,
	Elijah Newren <newren@gmail.com>,
	Christian Couder <christian.couder@gmail.com>
Subject: [PATCH 00/16] Auto-configure advertised remotes via URL whitelist
Date: Mon, 23 Mar 2026 09:05:03 +0100	[thread overview]
Message-ID: <20260323080520.887550-1-christian.couder@gmail.com> (raw)

Currently, the "promisor-remote" protocol capability allows a server
to advertise promisor remotes (and their tokens/filters), but the
client's `promisor.acceptFromServer` mechanism requires these remotes
to already exist in the config.

This is a significant burden for users and administrators who have to
pre-configure remotes.

This patch series improves on this by introducing a new
`promisor.acceptFromServerUrl` config option, which provides an
additive, URL-based security whitelist.

Multiple `promisor.acceptFromServerUrl` config options can be provided
in different config files. Each one should contain a URL glob pattern
which can optionally be prefixed with a remote name in the
"[<name>=]<pattern>" format.

With this new config option:

 - The server can update fields (like tokens) for known remotes,
   provided their URL matches the whitelist, even if
   `acceptFromServer` is set to `None`.

 - Unknown remotes advertised by the server can be automatically
   configured on the client if their URL matches the whitelist.

 - If there is no `<name>` prefix before the glob pattern matched, the
   auto-configured remote is named using the
   "promisor-auto-<sanitized-url>" format. So the same auto-configured
   remote config entry will be reused for the same URL.

 - If a `<name>` prefix is provided, it will be used for the
   auto-configured remote config entry.

 - If the chosen name (auto-generated or prefixed) already exists but
   points to a different URL, overwriting the existing config is
   prevented by appending a numeric suffix (e.g., -1, -2) to the name
   and auto-configuring using that name.

 - The server's originally advertised name is always saved in the
   `remote.<name>.advertisedAs` config variable of the auto-configured
   remote for tracing and debugging.

 - To honor the server's recommendation, promisor_remote_get_direct()
   is updated to try accepted remotes first before falling back to
   other configured promisor remotes. This ensures auto-configured
   remotes are preferred over other remotes especially the
   partial-clone origin.

Security considerations:

 - Advertised URLs are routed through url_normalize() before matching
   against the user's glob patterns to prevent percent-encoding, case
   variation, or path-traversal (../) bypasses.

 - Auto-generated remote names are sanitized (non-alphanumeric
   characters are replaced with '-' and prefixed with
   'promisor-auto-'). This guarantees safe config section names and
   prevents a server from maliciously overwriting standard remotes
   (like origin).

 - The documentation explains in detail how to use secure glob
   patterns in `promisor.acceptFromServerUrl`.

High level description of the patches
=====================================

 - Patch 1/16 ("promisor-remote: try accepted remotes before others in
   get_direct()"):

   Fixes promisor_remote_get_direct() to prioritize accepted
   remotes. This could be a separate fix, but is needed towards the
   end of the series.

 - Patches 2-3/16 ("urlmatch:*"):

   Exposes and adapts helpers in the urlmatch API.

 - Patches 4-11/16 ("promisor-remote:*"):

   Big refactoring of filter_promisor_remote() and
   should_accept_remote(). This keeps `struct promisor_info` instances
   alive longer to anticipate possible state-desync bugs, decouples
   the server's advertised name from the local config name, and
   sanitizes control flow without changing the existing behavior.

 - Patch 12/16 ("t5710:*"):

   Cleans up how "file://" URIs are managed in the test script to
   prepare for URI normalization later in the series and avoid issues
   on Windows.

 - Patches 13-15/16 ("promisor-remote:*"):

   The core feature. Introduces the parsing machinery, adds the
   additive whitelist for known remotes (with url_normalize()
   security), and finally implements the auto-creation and collision
   resolution for unknown remotes.

 - Patch 16/16 ("doc: promisor: improve acceptFromServer entry"):

   Cleans up and modernizes the existing `promisor.acceptFromServer`
   documentation.

CI tests
========

They all pass, see:

https://github.com/chriscool/git/actions/runs/23350745268


Christian Couder (16):
  promisor-remote: try accepted remotes before others in get_direct()
  urlmatch: change 'allow_globs' arg to bool
  urlmatch: add url_is_valid_pattern() helper
  promisor-remote: clarify that a remote is ignored
  promisor-remote: refactor has_control_char()
  promisor-remote: refactor accept_from_server()
  promisor-remote: keep accepted promisor_info structs alive
  promisor-remote: remove the 'accepted' strvec
  promisor-remote: add 'local_name' to 'struct promisor_info'
  promisor-remote: pass config entry to all_fields_match() directly
  promisor-remote: refactor should_accept_remote() control flow
  t5710: use proper file:// URIs for absolute paths
  promisor-remote: introduce promisor.acceptFromServerUrl
  promisor-remote: trust known remotes matching acceptFromServerUrl
  promisor-remote: auto-configure unknown remotes
  doc: promisor: improve acceptFromServer entry

 Documentation/config/promisor.adoc    | 118 +++++-
 Documentation/config/remote.adoc      |   9 +
 Documentation/gitprotocol-v2.adoc     |   9 +-
 promisor-remote.c                     | 532 +++++++++++++++++++++-----
 t/t5710-promisor-remote-capability.sh | 250 ++++++++++--
 urlmatch.c                            |  18 +-
 urlmatch.h                            |  11 +
 7 files changed, 802 insertions(+), 145 deletions(-)

-- 
2.53.0.625.g20f70b52bb


             reply	other threads:[~2026-03-23  8:05 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-23  8:05 Christian Couder [this message]
2026-03-23  8:05 ` [PATCH 01/16] promisor-remote: try accepted remotes before others in get_direct() Christian Couder
2026-03-26 12:20   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 02/16] urlmatch: change 'allow_globs' arg to bool Christian Couder
2026-03-23  8:05 ` [PATCH 03/16] urlmatch: add url_is_valid_pattern() helper Christian Couder
2026-03-26 12:20   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 04/16] promisor-remote: clarify that a remote is ignored Christian Couder
2026-03-26 12:20   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 05/16] promisor-remote: refactor has_control_char() Christian Couder
2026-03-23  8:05 ` [PATCH 06/16] promisor-remote: refactor accept_from_server() Christian Couder
2026-03-23  8:05 ` [PATCH 07/16] promisor-remote: keep accepted promisor_info structs alive Christian Couder
2026-03-26 12:21   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 08/16] promisor-remote: remove the 'accepted' strvec Christian Couder
2026-03-26 12:21   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 09/16] promisor-remote: add 'local_name' to 'struct promisor_info' Christian Couder
2026-03-26 12:21   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 10/16] promisor-remote: pass config entry to all_fields_match() directly Christian Couder
2026-03-26 12:21   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 11/16] promisor-remote: refactor should_accept_remote() control flow Christian Couder
2026-03-26 12:21   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 12/16] t5710: use proper file:// URIs for absolute paths Christian Couder
2026-03-26 12:21   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 13/16] promisor-remote: introduce promisor.acceptFromServerUrl Christian Couder
2026-03-26 12:21   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 14/16] promisor-remote: trust known remotes matching acceptFromServerUrl Christian Couder
2026-03-23 18:54   ` Junio C Hamano
2026-03-23 23:47     ` Junio C Hamano
2026-03-27 12:17     ` Christian Couder
2026-03-26 12:21   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 15/16] promisor-remote: auto-configure unknown remotes Christian Couder
2026-03-26 12:21   ` Patrick Steinhardt
2026-03-23  8:05 ` [PATCH 16/16] doc: promisor: improve acceptFromServer entry Christian Couder
2026-03-26 12:21 ` [PATCH 00/16] Auto-configure advertised remotes via URL whitelist Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260323080520.887550-1-christian.couder@gmail.com \
    --to=christian.couder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=karthik.188@gmail.com \
    --cc=me@ttaylorr.com \
    --cc=newren@gmail.com \
    --cc=ps@pks.im \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox