andrewmusselman opened a new issue, #598:
URL: https://github.com/apache/tooling-trusted-releases/issues/598

   ## Summary
   
   Personal Access Tokens (PATs) have a 180-day expiration with no mechanism to 
revoke all PATs when an account is disabled. PATs continue to work even when 
the owning account is disabled or deleted, allowing terminated users continued 
API access.
   
   ## ASVS Requirements
   
   - 7.4.2 - Verify that the application terminates all active sessions when a 
user account is disabled or deleted
   
   ## Related Audit Reports
   
   - [7.4.2.md](ASVS/reports/44ee502/L1/7.4.2.md) - ASVS-742-CRIT-002
   
   ## Affected Files
   
   - `atr/post/tokens.py` - PAT management endpoints
   - `atr/storage/writers/tokens.py` - Token storage operations (lines 107-108)
   - `atr/models/sql.py` - `PersonalAccessToken` model
   
   ## Current Behavior
   
   ```python
   # atr/storage/writers/tokens.py
   _EXPIRY_DAYS: Final[int] = 180
   
   async def delete_token(self, token_id: int) -> None:
       pat = await self.__data.query_one_or_none(
           sqlmodel.select(sql.PersonalAccessToken).where(
               sql.PersonalAccessToken.id == token_id,
               sql.PersonalAccessToken.asfuid == self.__asf_uid,  # Only user's 
own tokens
           )
       )
       # No admin capability to revoke all tokens for a user
       # No account status validation when PAT is used
   ```
   
   ## Risk
   
   - Terminated employees retain API access for up to 180 days
   - No administrative capability to revoke access immediately
   - PATs can be used to generate JWTs, extending access further
   - Insider threat from terminated employees
   
   ## Recommended Fix
   
   ```python
   # 1. Add admin endpoint to revoke all user tokens
   # atr/admin/__init__.py
   @admin.route("/users/<asf_uid>/revoke-tokens", methods=["POST"])
   @require(Requirements.root)
   async def revoke_user_tokens(session: web.Admin, asf_uid: str) -> 
web.WerkzeugResponse:
       """Revoke all PATs for a user (for account termination)."""
       async with storage.write.as_admin(session) as write:
           count = await write.revoke_all_user_tokens(asf_uid)
       flash_success(f"Revoked {count} tokens for {asf_uid}")
       return redirect(url_for("admin.users"))
   
   # 2. Add account status check when using PAT
   # atr/storage/writers/tokens.py
   async def issue_jwt(self, pat_text: str) -> str:
       pat_hash = hashlib.sha3_256(pat_text.encode()).hexdigest()
       pat = await self.__data.query_one_or_none(...)
       if (pat is None) or (pat.expires < datetime.datetime.now(datetime.UTC)):
           raise storage.AccessError("Authentication failed")
       
       # ADD: Check if user account is still active
       if not await self._is_account_active(self.__asf_uid):
           raise storage.AccessError("Account has been disabled")
       
       issued_jwt = jwtoken.issue(self.__asf_uid)
       return issued_jwt
   
   # 3. Add bulk revocation function
   # atr/storage/writers/tokens.py
   async def revoke_all_user_tokens(self, asf_uid: str) -> int:
       """Revoke all PATs for a user. Returns count of revoked tokens."""
       result = await self.__data.execute(
           sqlmodel.delete(sql.PersonalAccessToken).where(
               sql.PersonalAccessToken.asfuid == asf_uid
           )
       )
       return result.rowcount
   ```
   ### Additional manual admin
   
   - Provide "remove user" capability
   - Add policy for INFRA to remove user during urgent offboarding
   - More TBD
   
   ## Acceptance Criteria
   
   - [ ] Admin endpoint to revoke all tokens for a user
   - [ ] Account status checked when PAT is used to issue JWT
   - [ ] Bulk token revocation function implemented
   - [ ] Logging of token revocations for audit trail
   - [ ] Integration with account disable workflow (if applicable)
   - [ ] Test coverage for revocation scenarios


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