asf-tooling commented on issue #326:
URL: 
https://github.com/apache/tooling-trusted-releases/issues/326#issuecomment-4410381746

   <!-- gofannon-issue-triage-bot v2 -->
   
   **Automated triage** — analyzed at `main@2da7807a`
   
   **Type:** `new_feature`  •  **Classification:** `no_action`  •  
**Confidence:** `high`
   **Application domain(s):** `authentication_authorization`, 
`distribution_tracking`, `admin_operations`
   
   ### Summary
   Issue #326 requests a two-approval workflow for critical/irreversible 
actions (project deletion/archival, release deployment, vote-period bypass). 
After extensive discussion spanning 6 months, @dave2wave's most recent comment 
(1 day ago) directs to #1230, indicating the implementation is being tracked 
there. @dave2wave also noted (2026-04-05) that the team has been discussing a 
'separate service to handle contingent approvals and other approval evidence.' 
No two-approval mechanism currently exists in the codebase.
   
   ### Where this lives in the code today
   
   #### `atr/blueprints/admin.py` — `_check_admin_access` (lines 156-163)
   _extension point_
   Current admin access check only verifies single-user authentication; a 
two-approval gate would extend or wrap this authorization model.
   
   ```python
   @_BLUEPRINT.before_request
   async def _check_admin_access() -> None:
       web_session = await sessions.read()
       if not isinstance(web_session, sql.UserSession):
           raise base.ASFQuartException("Not authenticated", errorcode=401)
   
       if not user.is_admin(web_session.uid):
           raise base.ASFQuartException("You are not authorized to access the 
admin interface", errorcode=403)
   ```
   
   #### `atr/admin/__init__.py` — `delete_release_post` (lines 145-156)
   _extension point_
   Release deletion is one of the actions @dave2wave identified as requiring a 
two-approval gate.
   
   ```python
   @admin.typed
   async def delete_release_post(
       session: web.Committer, _delete_release_get: Literal["delete-release"], 
delete_form: DeleteReleaseForm
   ) -> str | web.WerkzeugResponse:
       """
       URL: POST /delete-release
   
       Delete selected releases and their associated data and files.
       """
       await _delete_releases(session, delete_form.releases_to_delete)
   
       return await session.redirect(delete_release_get)
   ```
   
   #### `atr/storage/writers/distributions.py` — `CommitteeMember.automate` 
(lines 95-108)
   _extension point_
   Distribution automation (pushing to Maven Central) was the original example 
@killerbees cited as needing two-key approval.
   
   ```python
       async def automate(
           self,
           release_key: models.safe.ReleaseKey,
           platform: models.sql.DistributionPlatform,
           committee_key: str,
           owner_namespace: models.safe.Alphanumeric | None,
           project_key: models.safe.ProjectKey,
           version_key: models.safe.VersionKey,
           phase: str,
           revision_number: str | None,
           package: models.safe.Alphanumeric,
           version: models.safe.VersionKey,
           staging: bool,
       ) -> models.sql.Task:
   ```
   
   #### `atr/post/distribution.py` — `automate_form_process_page` (lines 41-57)
   _extension point_
   The POST handler for distribution automation would need to incorporate 
approval gating before executing the action.
   
   ```python
   async def automate_form_process_page(
       session: web.Committer,
       form_data: shared.distribution.DistributionAutomateForm,
       project: safe.ProjectKey,
       version: safe.VersionKey,
       /,
       staging: bool = False,
   ) -> web.WerkzeugResponse:
       allowed_platforms = _AUTOMATED_PLATFORMS_STAGE if staging else 
_AUTOMATED_PLATFORMS
       if form_data.platform not in allowed_platforms:
           platform_str = form_data.platform.value
           return await session.redirect(
               get.distribution.stage_automate if staging else 
get.distribution.automate,
               project_key=str(project),
               version_key=str(version),
               error=f"Platform {platform_str} is not supported for automated 
distribution",
           )
   ```
   
   ### Where new code would go
   - `atr/models/sql.py` — new table alongside existing models
     A new Approval or PendingAction table would be needed to store approval 
requests, who initiated them, who approved them, and timestamps.
   - `atr/tasks/approval.py` — new file
     A background task to send approval emails to PMC private lists and handle 
expiration would live here, per @dave2wave's 4-step workflow design.
   - `atr/get/approval.py` — new file
     GET route for displaying the approval confirmation page (step 4 of 
@dave2wave's design) when a PMC member clicks the approval link from email.
   - `atr/post/approval.py` — new file
     POST handler for submitting an approval, which then triggers the guarded 
action if sufficient approvals are collected.
   
   ### Proposed approach
   The team has redirected this work to issue #1230 (per @dave2wave's comment 
from 2026-05-07). Additionally, @dave2wave noted on 2026-04-05 that they are 
discussing a 'separate service to handle contingent approvals and other 
approval evidence.' Given that (a) the latest comment explicitly points to 
#1230 as the locus of work, and (b) the team is considering a separate service 
rather than inline implementation, no diff should be proposed here. The work 
should be tracked and reviewed in #1230.
   
   The general architectural shape, per the discussion, would involve: a new 
database model for pending approvals, email integration to notify PMC private 
lists, a URL-based approval mechanism with access_check_committee guards, and 
guards on specific transitions (project archival/deletion, release deployment, 
vote-period overrides).
   
   ### Open questions
   - What is the scope and status of issue #1230 that @dave2wave referenced?
   - Is the 'separate service' for approvals being developed in another 
repository, or will it be integrated into ATR?
   - Which specific SQL model fields/tables would the approval service need?
   - Should the approval mechanism use email-based links (as @dave2wave 
proposed in the 4-step flow) or an in-app approval UI, or both?
   - How does this interact with the existing vote mechanism that already 
requires 3 +1 PMC votes for releases?
   
   _The agent reviewed this issue and is not proposing patches in this run. 
Review the existing-code citations and open questions above before deciding 
next steps._
   
   ### Files examined
   - `atr/get/distribution.py`
   - `atr/post/distribution.py`
   - `atr/shared/distribution.py`
   - `atr/storage/writers/distributions.py`
   - `atr/admin/__init__.py`
   - `atr/tasks/distribution.py`
   - `atr/blueprints/admin.py`
   - `atr/models/distribution.py`
   
   ---
   *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