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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.