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]

Reply via email to