blob: c018d912b712179bdd4ed7569e25d26636f1bbec [file] [view]
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Gmail — ASF-security-relay drafting](#gmail--asf-security-relay-drafting)
- [Rules](#rules)
- [How the skills detect relay cases](#how-the-skills-detect-relay-cases)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Gmail — ASF-security-relay drafting
Some reports reach the project's security list via the ASF security
team — `security@apache.org` itself, or a personal `@apache.org`
address of an ASF security-team member — forwarding a report that
came in through GHSA, HackerOne, or another channel the project's
security team does not have direct access to. In those cases the
"reporter" on the Gmail thread is the ASF forwarder, and the
**actual external reporter is unreachable to us directly**: we can
only reach them by asking the ASF forwarder to relay questions
through the same external channel.
When drafting any reply on an ASF-security-relay tracker — receipt
of confirmation, credit-preference request, status update — the
threading rules from [`threading.md`](threading.md) all still apply;
the differences are in the headers and body shape.
**Scope of this file: relay thread is the *only* thread.** The
relay-specific shape below (different `To:`, brevity, link to the
external reference) applies when the inbound relay thread is the
**only** thread recorded on the tracker — i.e. the external
reporter never sent a direct message to the project's security
list, so the relay is the only path back to them. When the tracker
records **two threads** — a direct primary reporter thread *and* a
separate forwarder/relay thread (typical when an external reporter
filed directly *and* the same bug was later relayed by huntr.com /
GHSA / ASF-security) — default drafts go to the **primary** thread
per [`threading.md` — Selecting the inbound thread when multiple
are recorded](threading.md#selecting-the-inbound-thread-when-multiple-are-recorded),
and the relay-specific shape below applies only to the rarer
back-channel message the project sends *through* the relay
channel (e.g. *"please ask the external reporter to confirm a
credit form for the advisory"*).
Placeholder convention:
- `<security-list>` — the project's security list. The concrete
address is declared in
[`<project-config>/project.md → Mailing lists`](../../<project-config>/project.md#mailing-lists).
## Rules
- **Thread attachment** — attach the draft to the inbound relay
thread, per the [threading rule](threading.md). On the default
`claude_ai_mcp` backend that means resolving the thread's latest
message ID and passing it as `replyToMessageId`; on the opt-in
`oauth_curl` backend it means passing the `threadId` to
`oauth-draft-create --thread-id`. Never fabricate a new thread for
a credit-preference relay; it goes on the same thread as the
original inbound report.
- **Subject** — `Re: <root subject>`, i.e. the subject of the
inbound relay message. No fabricated new subject, no
relay-specific title like *"\<Project\>: credit-preference relay
for <GHSA-ID>"*.
- **`To:`** — the ASF forwarder (the `From:` address of the
inbound relay message). Typically this is a personal
`@apache.org` address; use that, not the `security@apache.org`
list alias, so the conversation stays with the individual who
already knows the report.
- **`Cc:`** — `<security-list>` as always.
- **Body** — short, per the *"Brevity: emails state facts, not
context"* rule in [`../../AGENTS.md`](../../AGENTS.md). The ASF
security team knows the handling process; do **not** restate the
vulnerability, the severity analysis, or the project's CVE
process. When the purpose of the draft is a credit-preference
relay, the ask is one sentence: *"Please forward the
credit-preference question below to the external reporter through
the original channel."*
- **Include the clickable external-reference URL in the body, not
just the ID.** The forwarder receives many relays; making them
re-look-up the ID to forward our reply is friction. Put the full
URL on its own line near the top of the body so it is one click
reachable:
- GHSA: `https://github.com/<org>/<repo>/security/advisories/GHSA-NNNN-NNNN-NNNN`
- HackerOne: the report URL the forwarder originally shared
- Any other channel: the canonical URL for the report
The CVE-record URL (`https://www.cve.org/CVERecord?id=<CVE-ID>`
or the adopting project's CVE-tool URL) goes on its own line too
when the message includes a CVE allocation.
- **Reporter-facing content goes as a ready-to-paste block, not as
a third-person ask.** Any text destined for the external reporter
via the forwarder MUST be drafted as the actual reporter-facing
message, addressed to the reporter and signed by the project,
inside a fenced block the forwarder can copy verbatim into their
reply to the reporter.
❌ Third-person framing forces the forwarder to compose the
reporter-facing text themselves:
```text
Could you please pass to Matteo that CVE was allocated for
GHSA-2vgv-x9xr-7gfj: CVE-2026-49296. Thanks.
```
✓ Paste-ready block in the reporter's voice:
```text
Hi <forwarder>,
GHSA: https://github.com/<org>/<repo>/security/advisories/<GHSA-ID>
CVE: https://www.cve.org/CVERecord?id=<CVE-ID>
Please forward the following to the external reporter:
---
Hello <reporter first-name>,
Thanks again for your report. We have allocated <CVE-ID> for
the issue and the fix is being prepared. Please keep this issue
private until it has been publicly disclosed.
Best,
<project> security team
---
Thanks,
<sender>
```
**Why both rules together.** The clickable URL gives the
forwarder one-click context on their side; the paste-ready block
gives them zero-edit-required content for their reply. Together
they reduce the relay round-trip to a single forward-and-paste
action on the forwarder's side and let the project control the
reporter-facing wording (credit framing, embargo wording,
disclosure-timeline language).
Apply this shape to every relay message that carries content
intended to reach the external reporter — receipt of
confirmation, credit-preference question, CVE-allocation
notification, status update, release-shipped notification,
advisory-published notification.
**Source:** Arnout Engelen (`@raboof`, `engelen@apache.org`,
ASF Security) feedback on a CVE-allocation relay sent for
`GHSA-2vgv-x9xr-7gfj` / `CVE-2026-49296`, 2026-05-30.
## How the skills detect relay cases
The `security-issue-import` skill classifies candidates into
`Report`, `ASF-security relay`, and several non-import classes; the
classification feeds this drafting path.
Relay-specific signals in the inbound message:
- `From:` is `security@apache.org` or a personal `@apache.org`
address of an ASF-security-team member;
- Body opens with the ASF forwarding preamble — *"Dear PMC, The
security vulnerability report has been received by the Apache
Security Team and is being passed to you for action …"* — with
the original report underneath (often after a `====GHSA-…`
separator when the report came in via GitHub Security Advisory);
- The body usually ends with a `Credit` line naming the discoverer
(e.g. *"This vulnerability was discovered and reported by
bugbunny.ai"*) — use that verbatim for the Reporter-credited-as
placeholder, not the `From:` header (which is always the
forwarder's address).
The import skill's Step 3 classification table documents the exact
subject / sender signals; this file describes what to do once the
classification says *"ASF-security relay"*.