From c07164d5947f6f1a26f960c3926fcc711ef14f13 Mon Sep 17 00:00:00 2001 From: Harish Kesava Rao Date: Fri, 7 Aug 2026 07:50:08 +0530 Subject: [PATCH] docs(security): add reporter-unresponsiveness escalation per ASF policy to security-issue-sync --- docs/security/process.md | 18 +++++++++++++ docs/security/roles.md | 17 ++++++++++++ projects/_template/project.md | 12 +++++++++ skills/security-issue-sync/gather.md | 23 ++++++++++++++-- .../security-issue-sync/signals-to-actions.md | 27 +++++++++++++++++++ 5 files changed, 95 insertions(+), 2 deletions(-) diff --git a/docs/security/process.md b/docs/security/process.md index a0a7b176b..39d640c9a 100644 --- a/docs/security/process.md +++ b/docs/security/process.md @@ -219,6 +219,24 @@ rollup entries on the tracker (per [`tools/github/status-rollup.md`](../../tools/github/status-rollup.md)) with the action label `Sync (Step 4 escalation)`. +**This is separate from reporter unresponsiveness.** The escalation +above widens the audience when the *security team's own* discussion +has stalled; it says nothing about a reporter who has gone silent. +Per [ASF security policy](https://www.apache.org/security/committers.html), +reporter unresponsiveness must **not** block the project team from +moving to the next steps, particularly for a high-severity or +high-impact issue — the team agrees the fix, announcement, and +release schedule *with* the reporter when possible, but does not wait +indefinitely for that agreement. `security-issue-sync` operationalises +this: at every sync pass it checks the reporter thread for staleness +(the security team's last outbound message older than +`/project.md`'s `reporter_response_timeout_days`, +default 14, with no reply since) and, if stale, proposes proceeding +without further reporter sign-off as an explicit, user-confirmed +proposal item — see [`security-issue-sync` Step 1c/2b](../../skills/security-issue-sync/gather.md#1c-find-the-real-reporter-and-read-the-mailing-list-thread). +This never happens silently; the security team still confirms before +the process moves forward without the reporter. + ### Step 5 — Land the valid/invalid consensus If valid, apply exactly one scope label from diff --git a/docs/security/roles.md b/docs/security/roles.md index fc105410a..b3accb844 100644 --- a/docs/security/roles.md +++ b/docs/security/roles.md @@ -103,6 +103,23 @@ Reusable wording for the common cases lives in [`/canned-responses.md`](/canned-responses.md) — consult it before drafting a reply from scratch. +**A silent reporter does not block the process.** Keeping the reporter +informed is a commitment the team makes *to* the reporter — it is not +a requirement that the reporter respond before the team can move +forward. Per [ASF security policy](https://www.apache.org/security/committers.html), +if the reporter is unresponsive in a reasonable timeframe this should +not block the project team from moving to the next steps, particularly +if an issue is of high severity or impact. `security-issue-sync` tracks +this for you: when the security team's last outbound message on the +reporter thread is older than the project's configurable +`reporter_response_timeout_days` (declared in +`/project.md` → *Security inbox*, default 14 days) and +no reply has landed since, sync surfaces an explicit proposal item +asking whether to proceed with the fix and announcement without +further reporter sign-off. Confirming that proposal is a normal part +of the workflow, not an exception — you are not waiting on a reply +that never comes. + **When there's no direct reporter contact** (ASF-relay reports, read-only GHSA, anonymous tips), the team communicates with the *forwarder* instead — the security-team member or relay service diff --git a/projects/_template/project.md b/projects/_template/project.md index 53a424f49..8b2360d95 100644 --- a/projects/_template/project.md +++ b/projects/_template/project.md @@ -315,6 +315,18 @@ security_inbox: # The concrete inbound address / channel ID / form URL for this project. # Consumed by: security-issue-import, security-issue-sync, canned-responses. address: + + # Days of reporter silence, counted from the security team's most + # recent outbound message on the reporter thread, before + # security-issue-sync proposes proceeding with the fix and + # announcement without further reporter sign-off. Per ASF policy + # (https://www.apache.org/security/committers.html), an unresponsive + # reporter must not block the project team, particularly for a + # high-severity or high-impact issue. Tune to your own project's + # norms — a project handling especially sensitive reports may want a + # longer window; one under heavy report volume may want it shorter. + # Consumed by: security-issue-sync (Step 1c staleness check / Step 2b proposal). + reporter_response_timeout_days: 14 ``` ### Forwarders diff --git a/skills/security-issue-sync/gather.md b/skills/security-issue-sync/gather.md index 711df3eb4..7c0327ae8 100644 --- a/skills/security-issue-sync/gather.md +++ b/skills/security-issue-sync/gather.md @@ -208,7 +208,26 @@ Process for finding the real reporter and the original thread: - the latest message in the thread, *who* sent it, and whether the ball is in our court. -5. **Sync a reporter-confirmed credit line into the issue body** whenever +5. **Check for reporter staleness.** Using the message timestamps and + senders extracted in step 4, find the security team's **most recent + outbound message** to the reporter on this thread and the reporter's + **most recent reply**, if any. If the team's latest outbound message + is older than + [`/project.md`](../..//project.md#security-inbox)'s + `reporter_response_timeout_days` (default 14) **and** no reporter + reply has landed since that message, mark the thread **stale** and + surface it in Step 2b per the *Reporter unresponsiveness* row in + [`signals-to-actions.md`](signals-to-actions.md#step-2b--proposed-changes-signal-to-action-lookup-table). + Per [ASF security policy](https://www.apache.org/security/committers.html), + an unresponsive reporter must not block the project team from moving + to the next steps, particularly for a high-severity or high-impact + issue — but this is a **proposal, not an automatic action**; the + user still confirms before the team proceeds without the reporter. + Skip this check when the latest message on the thread is *from* the + reporter (the ball is already in the security team's court) — the + staleness clock only runs while we are the ones waiting on a reply. + +6. **Sync a reporter-confirmed credit line into the issue body** whenever the mail thread contains a clear credit confirmation from the reporter that has not yet been reflected in the tracker's *"Reporter credited as"* field. This is a dedicated check, not an afterthought — reporters @@ -264,7 +283,7 @@ Process for finding the real reporter and the original thread: world, hard to correct after publication, and directly undermines the trust the reporter extended to us. -5. **If you cannot find the original thread**, say so explicitly in the +7. **If you cannot find the original thread**, say so explicitly in the proposal and ask the user whether the GitHub issue author is also the reporter (which does happen for issues a security team member discovered themselves). Do not assume. diff --git a/skills/security-issue-sync/signals-to-actions.md b/skills/security-issue-sync/signals-to-actions.md index 4524155aa..5a5561e70 100644 --- a/skills/security-issue-sync/signals-to-actions.md +++ b/skills/security-issue-sync/signals-to-actions.md @@ -1149,6 +1149,33 @@ will change and *why*. Group them by category: this tracker's thread (check via the existing Gmail draft-scan the skill performs in Step 1e before proposing a new draft). +- **Reporter unresponsiveness (proceed-without-sign-off proposal)** — + when Step 1c's staleness check + ([`gather.md` 1c step 5](gather.md#1c-find-the-real-reporter-and-read-the-mailing-list-thread)) + marks the reporter thread **stale** (the security team's latest + outbound message is older than + [`/project.md`](../..//project.md#security-inbox)'s + `reporter_response_timeout_days`, default 14, with no reporter reply + since), propose a **numbered proposal item** — not a silent + status-comment entry — with this exact shape: + + > *N.* Reporter has not replied in **`` days** — propose + > proceeding with fix and announcement without further reporter + > sign-off, per [ASF security policy](https://www.apache.org/security/committers.html). + + Substitute the actual elapsed day count for ``. This item is + purely a proposal: it does not itself flip any label, close anything, + or send anything — it asks the user to confirm that the team should + keep moving through the remaining steps (discussion, fix, release, + advisory) treating the reporter's last-known position as final, + rather than waiting on a further reply. If the user confirms, continue + normally with whichever other Step 2b items this sync pass already + proposes; do **not** hold those items back pending reporter reply once + the user has confirmed proceeding without them. Re-surface this item + on every subsequent sync pass while the thread remains stale (the + reporter may reply at any time, at which point the check in + `gather.md` no longer fires and this item stops appearing). + - **Draft email to reporter (other reasons)** — whenever the ball is in our court on the email thread for any other reason (a question from the reporter, a follow-up needed for triage, communicating a negative