From 7ee0884bbae608f2d3b1ff79ecbeb17a614dc659 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Tue, 14 Apr 2026 23:42:10 +0200 Subject: [PATCH 1/3] Document allowlist automation workflows in README --- README.md | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index ad89586b..90b4d449 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ This repository hosts GitHub Actions developed by the ASF community and approved - [Organization-wide GitHub Actions Allow List](#management-of-organization-wide-github-actions-allow-list) - [Adding a New Action](#adding-a-new-action-to-the-allow-list) - [Reviewing](#reviewing) - - [Adding a New Version](#adding-a-new-version-to-the-allow-list) + - [Updating Version of Already Approved Action](#updating-version-of-already-approved-action) - [Automated Verification in CI](#automated-verification-in-ci) - [Dependabot Cooldown Period](#dependabot-cooldown-period) - [Manual Version Addition](#manual-addition-of-specific-versions) @@ -77,16 +77,21 @@ As stated in the [ASF GitHub Actions Policy](https://infra.apache.org/github-act All other actions must be explicitly added to the allow list after undergoing a security review. This review process applies to both new actions and new versions of previously approved actions (though reviews for new versions are typically expedited). +`actions.yml` is the source of truth for approved actions. From it, two generated files are kept in sync automatically: `approved_patterns.yml` (consumed by the ASF org-wide allow list) and `.github/actions/for-dependabot-triggered-reviews/action.yml` (the composite action Dependabot watches, so it can propose version bumps). The sections below describe the two entry points — manual PRs to add a new action, and the Dependabot-driven flow for updating versions of already-approved actions — and the workflows that implement each. + +> [!NOTE] +> `check_approved_limit.yml` guards the whole pipeline: the org-wide allow list has a hard cap of 1000 entries, and this workflow fails at 800 to give maintainers room to clean up before hitting the wall. + +### Adding a New Action to the Allow List + ```mermaid graph TD; - manual["manual PRs"]--new entries-->actions.yml - dependabot--updates (after review)-->composite-action[".github/actions/for-dependabot-triggered-reviews/action.yml"]; - composite-action--updates-->actions.yml - actions.yml--new entries-->composite-action - actions.yml--generates-->approved_patterns.yml + manual["manual PR"]--new entry-->actions.yml + actions.yml--"update_composite_action.yml"-->composite[".github/actions/for-dependabot-triggered-reviews/action.yml"] + actions.yml--"update_composite_action.yml"-->approved["approved_patterns.yml"] ``` -### Adding a New Action to the Allow List +A human-authored PR edits `actions.yml` directly. Once it merges to `main`, the **`update_composite_action.yml`** workflow regenerates both `.github/actions/for-dependabot-triggered-reviews/action.yml` and `approved_patterns.yml` from the new entries, so contributors never have to hand-edit the generated files. To request addition of an action to the allow list: @@ -112,12 +117,23 @@ repo/owner: The infrastructure team will review your request and either approve, request changes, or provide feedback on alternatives. -### Adding a new _version_ to the allow list +### Updating version of already approved action + +```mermaid +graph TD; + dependabot--"PR updates"-->composite[".github/actions/for-dependabot-triggered-reviews/action.yml"] + dependabot-.verified by.-verify["verify_dependabot_action.yml"] + composite--"update_actions.yml (on merge)"-->actions.yml + actions.yml--"update_actions.yml"-->approved["approved_patterns.yml"] + actions.yml--"remove_expired.yml (daily)"-->actions.yml +``` In most cases, new versions are automatically added through Dependabot: -- Dependabot opens PRs to update actions to the newest releases -- The previously approved version will be marked to expire in 3 months -- This grace period gives projects sufficient time to update their workflows +- Dependabot opens PRs against `.github/actions/for-dependabot-triggered-reviews/action.yml` to update actions to the newest releases +- **`verify_dependabot_action.yml`** runs on each such PR, rebuilds the action's compiled JavaScript in Docker, and diffs it against the published version (see [Automated Verification in CI](#automated-verification-in-ci)) +- Once a reviewer merges the PR, **`update_actions.yml`** reflects the new commit SHAs back into `actions.yml` and regenerates `approved_patterns.yml` +- The previously approved version is marked with an `expires_at` date 3 months out, giving projects a grace period to update their workflows +- Once that date passes, the daily **`remove_expired.yml`** workflow (02:04 UTC) deletes the entry and regenerates `approved_patterns.yml` — no manual PR needed Projects are encouraged to help review updates to actions they use. Please have a look at the diff and mention in your approval what you have checked and why you think the action is safe. @@ -269,6 +285,8 @@ If you add older version of the action and want to set an expiration date for it ### Removing a version manually +Routine removal is already automated: set `expires_at` on the entry and the daily `remove_expired.yml` workflow will delete it once the date passes. Use the manual process below only when you need an immediate removal that can't wait for the next daily run. + > [!IMPORTANT] > If a version or entire action needs to be removed immediately due to a security vulnerability: From c07be58cc7c4dc8aa65a04efc93aa43a2080fd37 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Sat, 18 Apr 2026 13:51:10 +0200 Subject: [PATCH 2/3] README: split auto-expiration into its own section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses @raboof review feedback on #714: - Pull the `expires_at` + `remove_expired.yml` explanation out of the "Updating Version" section into its own "Automatic Expiration of Old Versions" subsection between "Manual Version Addition" and "Removing a Version Manually", with its own mini mermaid graph showing the daily cleanup edge that was previously a self-loop on the updating diagram. - Apply the line-288 wording suggestion: the manual-removal intro now says the manual path is needed only when you "can't wait for the entry to expire" rather than "the next daily run" — the daily cadence is a detail of the new section, not of the manual flow. Rebased onto current main; no content changes beyond the review feedback. Generated-by: Claude Opus 4.7 (1M context) --- README.md | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 90b4d449..d5ac2de9 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ This repository hosts GitHub Actions developed by the ASF community and approved - [Automated Verification in CI](#automated-verification-in-ci) - [Dependabot Cooldown Period](#dependabot-cooldown-period) - [Manual Version Addition](#manual-addition-of-specific-versions) + - [Automatic Expiration of Old Versions](#automatic-expiration-of-old-versions) - [Removing a Version](#removing-a-version-manually) ## Submitting an Action @@ -125,15 +126,13 @@ graph TD; dependabot-.verified by.-verify["verify_dependabot_action.yml"] composite--"update_actions.yml (on merge)"-->actions.yml actions.yml--"update_actions.yml"-->approved["approved_patterns.yml"] - actions.yml--"remove_expired.yml (daily)"-->actions.yml ``` In most cases, new versions are automatically added through Dependabot: - Dependabot opens PRs against `.github/actions/for-dependabot-triggered-reviews/action.yml` to update actions to the newest releases - **`verify_dependabot_action.yml`** runs on each such PR, rebuilds the action's compiled JavaScript in Docker, and diffs it against the published version (see [Automated Verification in CI](#automated-verification-in-ci)) - Once a reviewer merges the PR, **`update_actions.yml`** reflects the new commit SHAs back into `actions.yml` and regenerates `approved_patterns.yml` -- The previously approved version is marked with an `expires_at` date 3 months out, giving projects a grace period to update their workflows -- Once that date passes, the daily **`remove_expired.yml`** workflow (02:04 UTC) deletes the entry and regenerates `approved_patterns.yml` — no manual PR needed +- The previously approved version is marked with an `expires_at` date 3 months out, giving projects a grace period to update their workflows; see [Automatic Expiration of Old Versions](#automatic-expiration-of-old-versions) for how the cleanup runs Projects are encouraged to help review updates to actions they use. Please have a look at the diff and mention in your approval what you have checked and why you think the action is safe. @@ -283,9 +282,27 @@ If you add older version of the action and want to set an expiration date for it > [!WARNING] > Older versions may contain security vulnerabilities or performance issues. Always evaluate if using the latest version is possible before requesting older versions. +### Automatic Expiration of Old Versions + +```mermaid +graph TD; + entry["actions.yml entry
with expires_at"]--"remove_expired.yml (daily, 02:04 UTC)"-->actions.yml + actions.yml--"update_composite_action.yml"-->composite[".github/actions/for-dependabot-triggered-reviews/action.yml"] + actions.yml--"update_composite_action.yml"-->approved["approved_patterns.yml"] +``` + +Routine cleanup of superseded versions is automated: + +- Any entry in `actions.yml` with an `expires_at: YYYY-MM-DD` field is a candidate for removal. +- Dependabot-driven updates (see [Updating Version of Already Approved Action](#updating-version-of-already-approved-action)) set `expires_at` to **3 months out** on the previously approved version. For manually added older versions, set `expires_at` explicitly (see [Manual Addition of Specific Versions](#manual-addition-of-specific-versions)). +- The **`remove_expired.yml`** workflow runs daily at **02:04 UTC**. Every entry whose `expires_at` date has passed is deleted from `actions.yml`; the workflow then commits the change and lets `update_composite_action.yml` regenerate `approved_patterns.yml` and the dependabot composite. +- Entries without `expires_at` (for example, `keep: true` wildcards and the current approved version) are never auto-removed — removal of those requires a manual PR. + +No human action is required for the routine case: projects get a 3-month grace window after a version bump, and the old entry disappears on its own afterwards. + ### Removing a version manually -Routine removal is already automated: set `expires_at` on the entry and the daily `remove_expired.yml` workflow will delete it once the date passes. Use the manual process below only when you need an immediate removal that can't wait for the next daily run. +Routine removal is already automated: set `expires_at` on the entry and the daily `remove_expired.yml` workflow will delete it once the date passes. Use the manual process below only when you need an immediate removal that can't wait for the entry to expire. > [!IMPORTANT] > If a version or entire action needs to be removed immediately due to a security vulnerability: From 75f87e4e85f94e653e1caf04a1c2c0a82a395fdc Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Sat, 18 Apr 2026 14:00:39 +0200 Subject: [PATCH 3/3] README: add a full-pipeline summary diagram Address @raboof's review idea of "one full graph" that ties the per-section diagrams together. Adds a Pipeline Overview subsection at the top of the allow-list management section with a single mermaid graph covering every entry point (human PR, Dependabot PR, daily cron), every workflow (update_actions, update_composite_action, remove_expired, verify_dependabot_action, check_approved_limit) and the three files they keep in sync (actions.yml, approved_patterns.yml, for-dependabot-triggered-reviews/action.yml). Edge styling carries meaning: thick arrows are regeneration flows that rewrite the generated files, thin arrows feed new content into the pipeline, dotted arrows are observer workflows. Node colors separate the source of truth, generated files, triggers and observer workflows. The existing per-section diagrams remain as focused zooms into each slice of the overall flow. Generated-by: Claude Opus 4.7 (1M context) --- README.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/README.md b/README.md index d5ac2de9..3beb251a 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ This repository hosts GitHub Actions developed by the ASF community and approved - [Submitting an Action](#submitting-an-action) - [Available GitHub Actions](#available-github-actions) - [Organization-wide GitHub Actions Allow List](#management-of-organization-wide-github-actions-allow-list) + - [Pipeline Overview](#pipeline-overview) - [Adding a New Action](#adding-a-new-action-to-the-allow-list) - [Reviewing](#reviewing) - [Updating Version of Already Approved Action](#updating-version-of-already-approved-action) @@ -80,6 +81,44 @@ All other actions must be explicitly added to the allow list after undergoing a `actions.yml` is the source of truth for approved actions. From it, two generated files are kept in sync automatically: `approved_patterns.yml` (consumed by the ASF org-wide allow list) and `.github/actions/for-dependabot-triggered-reviews/action.yml` (the composite action Dependabot watches, so it can propose version bumps). The sections below describe the two entry points — manual PRs to add a new action, and the Dependabot-driven flow for updating versions of already-approved actions — and the workflows that implement each. +#### Pipeline Overview + +The diagram below summarizes every entry point, workflow and generated file involved in keeping the allow list in shape. Each subsequent section zooms in on one slice of this flow. + +```mermaid +graph LR + human["Human PR
(add action / older version /
urgent removal)"] + dependabot["Dependabot PR
(version bump)"] + cron["Daily 02:04 UTC"] + + actions["actions.yml
source of truth"] + composite[".github/actions/
for-dependabot-triggered-reviews/
action.yml"] + approved["approved_patterns.yml
ASF org allow list"] + + human-->actions + dependabot-->composite + dependabot-.verified by.-verify["verify_dependabot_action.yml
(rebuild & diff)"] + + composite=="update_actions.yml
(on merge)"==>actions + cron=="remove_expired.yml"==>actions + + actions=="update_composite_action.yml"==>composite + actions=="update_composite_action.yml"==>approved + + guard["check_approved_limit.yml
(fails at 800 / 1000)"]-.monitors.-approved + + classDef source fill:#fff3b0,stroke:#8a6d0b,color:#333 + classDef generated fill:#e0f0ff,stroke:#2563a6,color:#333 + classDef trigger fill:#f3e0ff,stroke:#6a1b9a,color:#333 + classDef workflow fill:#e6ffe6,stroke:#1b5e20,color:#333 + class actions source + class composite,approved generated + class human,dependabot,cron trigger + class verify,guard workflow +``` + +Solid arrows (`==>`) are workflow regeneration edges — the "source → generated" flows that keep `actions.yml`, `approved_patterns.yml` and the dependabot composite in sync. Thin arrows feed the pipeline with new content (human or Dependabot PRs, cron), and dotted arrows are observer workflows that verify or guard rather than mutate. + > [!NOTE] > `check_approved_limit.yml` guards the whole pipeline: the org-wide allow list has a hard cap of 1000 entries, and this workflow fails at 800 to give maintainers room to clean up before hitting the wall.