asf-tooling commented on issue #1196:
URL:
https://github.com/apache/tooling-trusted-releases/issues/1196#issuecomment-4409713554
<!-- gofannon-issue-triage-bot v2 -->
**Automated triage** — analyzed at `main@2da7807a`
**Type:** `documentation` • **Classification:** `actionable` •
**Confidence:** `high`
**Application domain(s):** `cryptographic_keys`
### Summary
The issue requests that the OpenPGP key addition page explain the email
address criteria used to link a key to an ASF identity. Currently, the 'Add
your OpenPGP key' page (atr/get/keys.py, `add()`) provides minimal guidance.
The underlying logic in `atr/storage/writers/keys.py` (`__uids_asf_uid()`)
resolves identity via @apache.org emails or LDAP-linked addresses from
id.apache.org. @sbp noted the explanation should cover linked addresses,
id.apache.org, and the permanent nature of the record.
### Where this lives in the code today
#### `atr/get/keys.py` — `add` (lines 40-73)
_needs modification_
This is the GET handler that renders the 'Add your OpenPGP key' page - the
primary location where email address selection criteria should be explained to
the user.
```python
@get.typed
async def add(_session: web.Committer, _keys_add: Literal["keys/add"]) ->
str:
"""
URL: /keys/add
Add a new public signing key to the user's account.
"""
async with storage.write() as write:
participant_of_committees = await write.participant_of_committees()
committee_choices = [(c.key, c.display_name or c.key) for c in
participant_of_committees]
page = htm.Block()
page.p[htm.a(".atr-back-link", href=util.as_url(keys))["← Back to Manage
keys"],]
page.div(".my-4")[
htm.h1(".mb-4")["Add your OpenPGP key"],
htm.p["Add your public key to use for signing release artifacts."],
]
await form.render_block(
page,
model_cls=shared.keys.AddOpenPGPKeyForm,
action=util.as_url(post.keys.add),
submit_label="Add OpenPGP key",
cancel_url=util.as_url(keys),
defaults={
"selected_committees": committee_choices,
},
)
return await template.blank(
"Add your OpenPGP key",
content=page.collect(),
description="Add your public signing key to your ATR account.",
javascripts=["keys-add-toggle"],
)
```
#### `atr/storage/writers/keys.py` — `FoundationCommitter.__uids_asf_uid`
(lines 554-583)
_currently does this_
This method implements the actual email resolution logic: first checks for
@apache.org emails, then falls back to LDAP-linked email addresses. The UI
explanation should reflect this logic.
```python
def __uids_asf_uid(self, uids: list[str], ldap_data: dict[str, str]) ->
str | None:
# Test data
test_key_uids = [
"Apache Tooling (For test use only)
<[email protected]>",
]
if uids == test_key_uids:
# Allow the test key
if config.is_test_mode() and (self.__asf_uid == "test"):
# TODO: "test" is already an admin user
# But we want to narrow that down to only actions like this
# TODO: Add include_test: bool to user.is_admin?
return "test"
if user.is_admin(self.__asf_uid):
return self.__asf_uid
# Regular data
emails = []
for uid in uids:
# This returns a lower case email address, whatever the case of
the input
if email := util.email_from_uid(uid):
if email.endswith("@apache.org"):
return email.removesuffix("@apache.org")
emails.append(email)
# We did not find a direct @apache.org email address
# Therefore, search cached LDAP data
for email in emails:
if email in ldap_data:
return ldap_data[email]
return None
```
#### `atr/post/keys.py` — `_openpgp_key_uid_warning` (lines 346-366)
_currently does this_
This provides after-the-fact warnings when UID resolution fails, but the
issue requests proactive guidance before the user adds a key.
```python
def _openpgp_key_uid_warning(key_model: sql.PublicSigningKey,
current_asf_uid: str) -> htm.Element | None:
fingerprint_upper = key_model.fingerprint.upper()
if key_model.apache_uid is None:
details_url = util.as_url(get.keys.details,
fingerprint=key_model.fingerprint)
return htm.p[
f"OpenPGP key {fingerprint_upper} was uploaded and associated,
but ATR could not determine an ASF UID "
"from the key user IDs. ",
htm.a(href=details_url)["Review key details"],
".",
]
if key_model.apache_uid.lower() != current_asf_uid.lower():
details_url = util.as_url(get.keys.details,
fingerprint=key_model.fingerprint)
return htm.p[
f"OpenPGP key {fingerprint_upper} was uploaded and associated,
but it appears to belong to ASF UID "
f"{key_model.apache_uid}, not {current_asf_uid}. ",
htm.a(href=details_url)["Review key details"],
".",
]
return None
```
### Proposed approach
Add explanatory text to the 'Add your OpenPGP key' page in `atr/get/keys.py`
(`add()` function) that explains the email address criteria. The text should
clarify: (1) the key's User ID must contain an email address that ATR can link
to the user's ASF identity, (2) an `@apache.org` email is the simplest option,
(3) alternatively, any email address linked to the user's ASF account via
`id.apache.org` will work, (4) this is a permanent record analogous to a
commit. The guidance should appear between the page heading and the form, as a
clear informational section.
### Suggested patches
#### `atr/get/keys.py`
Add explanatory guidance about email address selection criteria to the key
addition page, as requested in the issue and elaborated by @sbp.
````diff
--- a/atr/get/keys.py
+++ b/atr/get/keys.py
@@ -47,7 +47,26 @@
page.p[htm.a(".atr-back-link", href=util.as_url(keys))["← Back to
Manage keys"],]
page.div(".my-4")[
htm.h1(".mb-4")["Add your OpenPGP key"],
- htm.p["Add your public key to use for signing release artifacts."],
+ htm.p["Add your public key to use for signing release artifacts. "
+ "Your key's User ID (UID) must contain an email address that
ATR can link to your ASF identity."],
+ ]
+
+ page.div(".alert.alert-info.mb-4")[
+ htm.p(".fw-semibold.mb-2")["Which email address should your key
use?"],
+ htm.ul(".mb-2")[
+ htm.li[
+ htm.strong["Recommended: "],
+ "Use your ",
+ htm.code["@apache.org"],
+ " email address (e.g. ",
+ htm.code["[email protected]"],
+ "). This is the simplest way for ATR to identify you.",
+ ],
+ htm.li[
+ htm.strong["Alternative: "],
+ "Use any email address that is linked to your ASF account
via ",
+ htm.a(href="https://id.apache.org")["id.apache.org"],
+ ". ATR checks LDAP records to resolve linked addresses.",
+ ],
+ ],
+ htm.p(".mb-0.text-muted")[
+ "Adding a key is a permanent record, similar to a commit. "
+ "Choose your email address carefully, as it will be publicly
associated with your signed releases.",
+ ],
]
await form.render_block(
page,
````
### Open questions
- Should additional guidance also be added to a separate
tutorial/documentation page outside the key addition form?
- Should the explanation mention that if no matching email is found, ATR
will still store the key but warn about the unresolved UID?
- Are there any other pages (e.g., a key generation tutorial page not shown
in this inventory) where this guidance should also appear?
### Files examined
- `atr/shared/keys.py`
- `atr/storage/writers/keys.py`
- `atr/post/keys.py`
- `atr/get/keys.py`
### Related issues
This issue appears related to: #1198.
_Both address clarity and documentation gaps in OpenPGP key management UI
during user testing_
---
*Draft from a triage agent. A human reviewer should validate before merging
any change. The agent did not run tests or verify diffs apply.*
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]