You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by ar...@apache.org on 2026/04/22 12:55:28 UTC

(tooling-trusted-releases) branch arm updated: #1129 - purge expired PATs every 30 days as part of background maintenance

This is an automated email from the ASF dual-hosted git repository.

alitheg pushed a commit to branch arm
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git


The following commit(s) were added to refs/heads/arm by this push:
     new e291b103 #1129 - purge expired PATs every 30 days as part of background maintenance
e291b103 is described below

commit e291b10398449b71d6d4de9617a24fcbdc9b3867
Author: Alastair McFarlane <ar...@apache.org>
AuthorDate: Wed Apr 22 13:54:24 2026 +0100

    #1129 - purge expired PATs every 30 days as part of background maintenance
---
 atr/tasks/maintenance.py | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/atr/tasks/maintenance.py b/atr/tasks/maintenance.py
index 76bc6d0f..50b23d28 100644
--- a/atr/tasks/maintenance.py
+++ b/atr/tasks/maintenance.py
@@ -15,6 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
+import datetime
 import time
 from typing import Final
 
@@ -28,6 +29,7 @@ import atr.models.sql as sql
 import atr.tasks as tasks
 import atr.tasks.checks as checks
 
+_EXPIRED_TOKEN_RETENTION_DAYS: Final[int] = 30
 _FORM_ERROR_TTL_SECONDS: Final[int] = 24 * 60 * 60
 
 
@@ -45,8 +47,9 @@ async def run(task_args: args.MaintenanceArgs) -> results.Results | None:
         # (and knowing this task will finish before it's re-scheduled)
         await tasks.schedule_next(task_args.asf_uid, task_args.next_schedule_seconds, tasks.run_maintenance)
 
-        await _storage_maintenance()
+        await _expired_pats_maintenance()
         await _session_data_maintenance()
+        await _storage_maintenance()
         await _workflow_ssh_keys_maintenance()
 
         log.info(
@@ -62,6 +65,18 @@ async def run(task_args: args.MaintenanceArgs) -> results.Results | None:
         raise MaintenanceError(error_msg) from e
 
 
+async def _expired_pats_maintenance() -> None:
+    via = sql.validate_instrumented_attribute
+    cutoff = datetime.datetime.now(datetime.UTC) - datetime.timedelta(days=_EXPIRED_TOKEN_RETENTION_DAYS)
+    async with db.session() as data:
+        statement = sqlmodel.delete(sql.PersonalAccessToken).where(via(sql.PersonalAccessToken.expires) < cutoff)
+        result = await data.execute(statement)
+        await data.commit()
+        deleted = getattr(result, "rowcount", 0) or 0
+        if deleted > 0:
+            log.info(f"Purged {deleted} expired personal access tokens")
+
+
 async def _session_data_maintenance() -> None:
     via = sql.validate_instrumented_attribute
     cutoff = time.time() - _FORM_ERROR_TTL_SECONDS


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org