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
next prev 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