Linux maintainer tooling and workflows
 help / color / mirror / Atom feed
From: Brian Masney <masneyb@kernel.org>
To: "Kernel.org Tools" <tools@kernel.org>
Cc: Konstantin Ryabitsev <konstantin@linuxfoundation.org>,
	 Jerome Brunet <jbrunet@baylibre.com>,
	 Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	 Brian Masney <masneyb@kernel.org>
Subject: [PATCH b4 v2 2/3] review: add support for fetching patchwork key via git credentials
Date: Fri, 30 Oct 2026 09:47:29 -0400	[thread overview]
Message-ID: <20261030-pw-key-command-v2-2-95fb0f822834@kernel.org> (raw)
In-Reply-To: <20261030-pw-key-command-v2-0-95fb0f822834@kernel.org>

Introduce a b4.pw-user and support for fetching the patchwork key via
git credentials.

Assisted-by: LLM
Signed-off-by: Brian Masney <masneyb@kernel.org>
---
 docs/config.rst    | 29 +++++++++++++++++++++++++++++
 src/b4/__init__.py | 48 +++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/docs/config.rst b/docs/config.rst
index 593129e8ae70..7087883c0a22 100644
--- a/docs/config.rst
+++ b/docs/config.rst
@@ -1022,6 +1022,35 @@ integrate your b4 workflow with patchwork.
 
      Default: ``None``
 
+   :term:`b4.pw-user`
+     Your username on the patchwork server. When this is set and
+     :term:`b4.pw-key` is not, b4 asks your git credential helpers for the
+     password of this user on the :term:`b4.pw-url` host, and uses it as
+     the API key. This lets you keep the key in a password manager instead
+     of storing it in plain text in your git config. b4 asks at most once
+     per invocation. For example::
+
+         pw-url = https://patchwork.kernel.org/
+         pw-user = jdoe
+
+     To store the key with a credential helper that supports it::
+
+         printf 'protocol=https\nhost=patchwork.kernel.org\nusername=jdoe\npassword=%s\n' \
+             "$PW_API_KEY" | git credential approve
+
+     You can also inject the key via a password manager by placing the following
+     in your .gitconfig:
+
+        [credential "https://user@patchwork.kernel.org"]
+        helper = "!f() { echo password=$(pass korg-patchwork-token); }; f"
+
+     If no helper returns a password, git may prompt for one on the
+     terminal. This setting is ignored in the in-tree ``.b4-config`` file.
+
+     Default: ``None``
+
+     .. versionadded:: v0.17
+
 .. _contributor_settings:
 
 Contributor-oriented settings
diff --git a/src/b4/__init__.py b/src/b4/__init__.py
index 16b7208f0b09..045e5f6e7b08 100644
--- a/src/b4/__init__.py
+++ b/src/b4/__init__.py
@@ -392,6 +392,8 @@ LORENODE: Optional[liblore.LoreNode] = None
 URL_SERVERS: Dict[str, Tuple[str, bool]] = dict()
 # Indicates that we've cleaned cache already
 _CACHE_CLEANED = False
+# Patchwork API keys returned by git credential helpers, keyed by (url, user)
+_PW_KEY_CACHE: Dict[Tuple[str, str], str] = dict()
 # DNS answers for the life of the process (see _setup_dns_resolver)
 _DNS_CACHE = dns.resolver.LRUCache()
 # Used to track send-email alias replacements
@@ -5000,6 +5002,11 @@ def _setup_main_config(
         'trailer*',
         'pw-*',
     ]
+    # Never take these from an in-tree .b4-config: they are personal and
+    # they make b4 ask git credential helpers for a secret.
+    wtdeny = [
+        'pw-user',
+    ]
     multivals = [
         'keyringsrc',
         'am-perpatch-check-cmd',
@@ -5015,6 +5022,9 @@ def _setup_main_config(
             wtconfig = get_config_from_git(r'b4\..*', multivals=multivals, source=wtcfg)
             logger.debug('wtcfg=%s', wtconfig)
             for key, val in wtconfig.items():
+                if key in wtdeny:
+                    logger.debug('wtcfg: ignoring %s', key)
+                    continue
                 if key in multivals:
                     val = [_val_to_path(topdir, x) for x in val]
                 else:
@@ -6403,13 +6413,45 @@ def get_smtp(
 
 
 def get_pw_key(config: Optional[ConfigDictT] = None) -> str:
-    """Return the Patchwork API key from b4.pw-key.
+    """Return the Patchwork API key.
 
-    Returns an empty string when no key is configured.
+    Use b4.pw-key when it is set.  Otherwise, if b4.pw-user is set, ask the
+    git credential helpers for the password of that user on the b4.pw-url
+    host, so the key can live in a password manager instead of the git
+    config.  The result is cached for the life of the process, so the
+    helpers are asked at most once.  Returns an empty string when no key is
+    configured or the lookup fails.
     """
     if config is None:
         config = get_main_config()
-    return str(config.get('pw-key', '') or '')
+    pwkey = str(config.get('pw-key', '') or '')
+    pwuser = str(config.get('pw-user', '') or '')
+    pwurl = str(config.get('pw-url', '') or '')
+    if pwkey or not (pwuser and pwurl):
+        return pwkey
+
+    cachekey = (pwurl, pwuser)
+    if cachekey in _PW_KEY_CACHE:
+        return _PW_KEY_CACHE[cachekey]
+
+    parsed = urllib.parse.urlparse(pwurl)
+    if parsed.scheme and parsed.netloc:
+        logger.debug('Asking git credential helpers for the patchwork key')
+        gc_pass = git_credential_fill(
+            None, protocol=parsed.scheme, host=parsed.netloc, username=pwuser
+        )
+        pwkey = gc_pass or ''
+        if not pwkey:
+            logger.critical(
+                'No patchwork key for %s@%s from git credential helpers',
+                pwuser,
+                parsed.netloc,
+            )
+    else:
+        logger.critical('Could not parse pw-url: %s', pwurl)
+
+    _PW_KEY_CACHE[cachekey] = pwkey
+    return pwkey
 
 
 def get_patchwork_session(pwkey: str, pwurl: str) -> Tuple[requests.Session, str]:

-- 
2.56.0


  parent reply	other threads:[~2026-10-30 13:47 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-30 13:47 [PATCH b4 v2 0/3] review: add support for fetching patchwork token via git credentials Brian Masney
2026-10-30 13:47 ` [PATCH b4 v2 1/3] review: centralize lookup of patchwork key in one place Brian Masney
2026-10-30 13:47 ` Brian Masney [this message]
2026-10-30 13:47 ` [PATCH b4 v2 3/3] review: tests: add tests for the patchwork key Brian Masney

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=20261030-pw-key-command-v2-2-95fb0f822834@kernel.org \
    --to=masneyb@kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=jbrunet@baylibre.com \
    --cc=konstantin@linuxfoundation.org \
    --cc=tools@kernel.org \
    /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