Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions organizations/ASF/organization.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ governance:
security_inbox:
kind: mailing-list
foundation_security_address: security@apache.org # ASF security team forwards reports here
cve_tool_senders: [security@apache.org] # organization-wide CVE bookkeeping sender
has_forwarder_relay: true
list_filter_query: "list:<security-list-domain>"
reporter_response_timeout_days: 14 # ASF policy: a silent reporter must not block the team
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ This is a pre-flight no-op classifier in the sense of `security-issue-sync`'s [b
Never read a body to decide.

**Run it.** Write `<scratch>/threads.json` with the Write tool —
`upstream`, `security_list`, `cve_tool_senders` (security-team members who post CVE-tool notifications, if any), `named_thread_id` under `import thread:<id>`,
`upstream`, `security_list`, `cve_tool_senders` (resolved from `security_inbox.cve_tool_senders`; security-team members who post CVE-tool notifications, if any), `named_thread_id` under `import thread:<id>`,
and `threads[]`, each `{thread_id, messages: [{subject, from}]}` — then:

```bash
Expand Down
2 changes: 2 additions & 0 deletions plugins/magpie-setup/skills/setup/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,7 @@ available). These pre-populate `<project-config>/project.md` in Step 9:
- `dev_list` is the target of the `dev` or `issues` or `pullrequests` notification containing `dev@`. If not found, default to `dev@<project>.apache.org`.
- `users_list` is the target of the `users` notification, or defaults to `users@<project>.apache.org`.
- `security_list` has no default: not every ASF project has a dedicated `security@<project>.apache.org` list. Detect it and ask, as [`adopt.md` Step 4b](adopt.md#4b--scaffold-whatever-is-still-missing) does; when no dedicated list is found, recommend requesting one from ASF Infra and offer `private@<project>.apache.org` only as a flagged fallback.
- `security_inbox.cve_tool_senders` inherits `security@apache.org` from the ASF organization profile. Ask which ASF CNA reviewers currently send CVE-tool notifications to the project. If the answer is non-empty, write one project-level list containing `security@apache.org` and the confirmed reviewer addresses because project values replace, rather than merge with, organization defaults. An empty answer leaves the key absent and keeps the inherited address; never guess reviewer addresses.
- `private_list` defaults to `private@<project>.apache.org`.
- `announce_list` defaults to `announce@apache.org`.
- `github.homepage` in `.asf.yaml` may refine `product_family_url` if the GitHub repo homepage was empty.
Expand Down Expand Up @@ -1329,6 +1330,7 @@ to this repo.
- Replace the placeholder `TODO` lines with the values auto-sourced in Step 4b:
- Always (organization-agnostic): `upstream_repo`, `upstream_default_branch`, `product_family_url`, `labels`.
- **Only when `organization: ASF`** (the ASF-specific block of Step 4b): `dev_list`, `commits_list`, `users_list`, `private_list`, `announce_list`. `security_list` is not auto-sourced: settle it with the detect-and-recommend rule in `adopt.md` Step 4b ("Ask where security reports go explicitly"). For a non-ASF `organization`, leave these as `TODO` — do not write `apache.org` addresses.
- For ASF adopters with confirmed reviewer addresses, write `security_inbox.cve_tool_senders` with both `security@apache.org` and those addresses. If none were confirmed, leave the key absent so the organization default remains effective. Do not write guessed personal addresses.
- Prompt the user to confirm the auto-sourced values, and only ask them to input values for stable fields that were absent or couldn't be derived.
- Stage the written files in `.apache-magpie-overrides/` to git (`git add`).

Expand Down
5 changes: 5 additions & 0 deletions plugins/magpie-setup/templates/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ security_inbox:
# The concrete inbound address / channel ID / form URL for this project.
# Consumed by: security-issue-import, security-issue-sync, canned-responses.
address: <security-list>
# Optional override: addresses that send CVE-tool bookkeeping mail.
# ASF projects inherit security@apache.org; if overriding this list, repeat
# that address and add the active CNA reviewers.
# Consumed by: security-issue-import's Step 1 pre-filter.
# cve_tool_senders: [security@apache.org, reviewer@apache.org]
```

**Optional override — `reporter_response_timeout_days`.** Days of
Expand Down
31 changes: 31 additions & 0 deletions tools/security-management/tests/test_issue_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,37 @@ def test_prefilter_rules(capsys, tmp_path) -> None:
assert [t["thread_id"] for t in out["dropped"]] == ["t-bookkeeping"]


def test_prefilter_drops_asf_cna_bookkeeping_from_configured_senders(capsys, tmp_path) -> None:
threads = {
"upstream": "apache/foo",
"security_list": "security@foo.apache.org",
"cve_tool_senders": ["security@apache.org", "reviewer@apache.org"],
"threads": [
{
"thread_id": "reservation",
"messages": [
{"subject": "CVE-2026-12345 reserved for foo", "from": "security@apache.org"},
],
},
{
"thread_id": "review-comment",
"messages": [
{
"subject": "Comment added on CVE-2026-12345",
"from": "ASF Reviewer <reviewer@apache.org>",
},
],
},
],
}

code, out = run(capsys, "prefilter", "--threads", write(tmp_path, "threads.json", threads))

assert code == 0
assert out["keep"] == []
assert [thread["thread_id"] for thread in out["dropped"]] == ["reservation", "review-comment"]


def test_dedup_queries_batch_by_six(capsys, tmp_path) -> None:
ids = [f"19d2f40286{i:06x}" for i in range(8)]
code, out = run(
Expand Down