apache/airflow-steward
GitHub: apache/airflow-steward
面向Apache开源项目的可复用安全漏洞处理框架,通过AI Agent技能和标准化流程实现从漏洞报告到CVE发布的全生命周期管理。
Stars: 0 | Forks: 1
**目录** *由 [DocToc](https://github.com/thlorenz/doctoc) 生成*
- [概述](#overview)
- [本指南的适用人群](#who-this-guide-is-for)
- [运行 Agent 技能的前置条件](#prerequisites-for-running-the-agent-skills)
- [1. 遵循 `SKILL.md` 约定的 Agent](#1-an-agent-that-speaks-the-skillmd-convention)
- [2. 电子邮件连接(目前为 Gmail MCP)](#2-email-connection-gmail-mcp-today)
- [3. GitHub 连接(GitHub MCP / `gh` CLI)](#3-github-connection-github-mcp--gh-cli)
- [4. PMC 成员资格(仅用于 CVE 分配)](#4-pmc-membership-only-for-cve-allocation)
- [5. 浏览器(用于人工点击步骤)](#5-browser-for-the-human-click-steps)
- [6. 本地 `` 克隆(仅用于 `fix-security-issue`)](#6-local-upstream-clone-only-for-fix-security-issue)
- [7. `uv`(用于 `generate-cve-json`)](#7-uv-for-generate-cve-json)
- [共享约定](#shared-conventions)
- [让报告人随时了解进展](#keeping-the-reporter-informed)
- [在追踪器上记录状态转换](#recording-status-transitions-on-the-tracker)
- [机密性](#confidentiality)
- [给问题分类者 — 步骤 1–6](#for-issue-triagers--steps-16)
- [日常分类循环](#daily-triage-loop)
- [评估报告](#assessing-a-report)
- [分配 CVE](#allocating-the-cve)
- [最常用的工具](#tools-you-use-most)
- [给修复开发者 — 步骤 7–11](#for-remediation-developers--steps-711)
- [接手追踪器](#picking-up-a-tracker)
- [尝试自动修复](#attempting-an-automated-fix)
- [手动发起公开修复 PR](#opening-the-public-fix-pr-manually)
- [私有 PR 后备方案](#private-pr-fallback)
- [交接给发布管理员](#handoff-to-the-release-manager)
- [最常用的工具](#tools-you-use-most-1)
- [给发布管理员 — 步骤 12–15](#for-release-managers--steps-1215)
- [从修复开发者处交接](#handoff-from-the-remediation-developer)
- [发送安全公告](#sending-the-advisory)
- [捕获公共存档 URL](#capturing-the-public-archive-url)
- [发布 CVE 并关闭问题](#publishing-the-cve-and-closing-the-issue)
- [发布后的致谢信息更正](#post-release-credit-corrections)
- [最常用的工具](#tools-you-use-most-2)
- [流程参考:16 个步骤](#process-reference-the-16-steps)
- [步骤 1 — 报告到达 security@](#step-1--report-arrives-on-security)
- [步骤 2 — 导入报告](#step-2--import-the-report)
- [步骤 3 — 讨论是否值得申请 CVE](#step-3--discuss-cve-worthiness)
- [步骤 4 — 升级停滞的讨论](#step-4--escalate-stalled-discussions)
- [步骤 5 — 达成有效/无效共识](#step-5--land-the-validinvalid-consensus)
- [步骤 6 — 分配 CVE](#step-6--allocate-the-cve)
- [步骤 7 — 自行指派并实施修复](#step-7--self-assign-and-implement-the-fix)
- [步骤 8 — 发起公开 PR(简单情况)](#step-8--open-a-public-pr-straightforward-cases)
- [步骤 9 — 发起私有 PR(特殊情况)](#step-9--open-a-private-pr-exceptional-cases)
- [步骤 10 — 关联 PR 并应用 `pr created`](#step-10--link-the-pr-and-apply-pr-created)
- [步骤 11 — PR 合并](#step-11--pr-merged)
- [步骤 12 — 修复发布](#step-12--fix-released)
- [步骤 13 — 发送安全公告](#step-13--send-the-advisory)
- [步骤 14 — 捕获公共公告 URL](#step-14--capture-the-public-advisory-url)
- [步骤 15 — 发布 CVE 记录并关闭问题](#step-15--publish-the-cve-record-and-close-the-issue)
- [步骤 16 — 致谢更正](#step-16--credit-corrections)
- [标签生命周期](#label-lifecycle)
- [状态图](#state-diagram)
- [标签参考](#label-reference)
- [采用该框架](#adopting-the-framework)
## 概述
本仓库托管了一个可复用的、与具体项目无关的框架,用于
运行 ASF(Apache 软件基金会)项目的安全问题处理流程。(目前
由于历史原因托管在 `apache/airflow-steward`;未来将
重命名为 `apache/steward`。)
下面的生命周期和约定是框架层面的;所有
项目特定的配置(身份、仓库、邮件列表、 canned responses、
发布列车、安全模型、范围标签、里程碑格式、标题规范化规则、
修复工作流细节)都声明在**采用该框架的项目**的 `/`
目录中——即采用项目保存在其追踪器仓库根目录下的
`.apache-steward/` 目录。框架
本身作为 git submodule 被拉取到采用者的追踪器中,路径为
`.apache-steward/apache-steward/`。
新项目通过以下方式采用该框架:
1. 将本仓库克隆为追踪器仓库的 submodule,路径为
`.apache-steward/apache-steward/`。
2. 将 [`projects/_template/`](projects/_template/)
脚手架复制到追踪器的 `.apache-steward/` 目录,并
填入项目的身份信息、邮件列表、范围标签、
发布列车名单、安全模型和 canned responses。
3. 将追踪器仓库中的 `.claude/skills/` 符号链接到
submodule 的 `.claude/skills/`,以便 Claude Code(或其他
兼容 `SKILL.md` 的 Agent)根据采用者的项目配置加载框架技能。
私有的 `` 仓库是采用项目的安全团队共享的追踪器。只有安全团队的成员才有访问权限。
问题是从项目的安全邮件列表上提出的报告创建的(参见 `/project.md → Mailing lists`),并由安全团队成员复制到 `` 中——因此,追踪器的 GitHub 作者**并不总是报告人**,真正的报告人是发送原始邮件的人。
每个追踪器同时通过两个渠道流动:
- 原始的安全列表邮件线程,在每次状态转换时都会通知报告人;
- 追踪问题上的评论,以便安全团队的其他成员和发布管理员可以跟进,而无需从标签和时间戳重建状态。
本文档的其余部分按受众进行组织。选择与您将要执行的操作相匹配的角色,阅读其对应部分,并在需要查看步骤级细节时跳转到[流程参考](#process-reference-the-16-steps)。
## 本指南的适用人群
三个角色共同承担处理流程。任何安全团队成员都可以在特定问题上承担其中任何一个角色,实际上人们会轮换角色——但在任何时刻,一个特定的追踪问题都只有一个人负责下一步操作。
请选择当前适用于您的角色:
- **我是安全团队的新人,或者我主要只是想对问题发表评论。** 请阅读下面的[共享约定](#shared-conventions)。采用项目的安全问题看板——参见 `/project.md → GitHub project board`——是主视图。您不需要 Agent 即可发表评论。
- **我是轮值的分类人员** —— 每周运行几次 `import new reports` 和 `sync all`。请跳转至 [给问题分类者 — 步骤 1–6](#for-issue-triagers--steps-16)。
- **我接手了一个追踪器,正准备发起一个修复 PR。** 请跳转至 [给修复开发者 — 步骤 7–11](#for-remediation-developers--steps-711)。
- **我是包含安全修复的发布版本的发布管理员。** 请跳转至 [给发布管理员 — 步骤 12–15](#for-release-managers--steps-1215)。
- **我正在查找特定的步骤或标签。** 请直接前往 [流程参考](#process-reference-the-16-steps) 或 [标签生命周期](#label-lifecycle)。
## 运行 Agent 技能的前置条件
如果您只打算在看板上**对问题发表评论**,请跳过本节——一个浏览器和您的 `` 协作者访问权限就足够了。
如果您计划**运行任何 Agent 技能**(`import`、`sync`、`allocate-cve`、`fix`、`generate-cve-json`、`deduplicate`)——通常作为轮值分类人员、修复开发者或发布管理员——请在调用技能**之前**检查以下设置。每个技能在运行时也会针对同一列表执行简短的 Step 0 预检,如果缺少某些内容,它会停止并给出明确的信息,因此您不会在工作流进行到一半时才发现缺失了什么。
### 1. 遵循 `SKILL.md` 约定的 Agent
[Claude Code](https://www.anthropic.com/claude-code) 是编写这些技能时所依据的参考实现。任何能够读取 `.claude/skills/*/SKILL.md` 文件并遵循其分步说明的 Agent 都应该可以使用;这里对 Claude Code 本身并没有硬性依赖。
该 Agent 会在预披露的 CVE 内容(私人邮件线程、草稿公告、进行中的追踪器讨论)上运行。请使用 [`secure-agent-setup.md`](secure-agent-setup.md) 中记录的凭据隔离设置来运行它——这是一项分层防御措施,围绕 Claude Code 的文件系统沙箱、工具级权限规则以及一个会从 Agent 环境中剥离凭据形态变量的 clean-env 包装器构建而成。所需的系统工具(`bubblewrap`、`socat`、`claude-code` 本身)受 7 天上游发布冷却期的限制,这反映了框架在其 `[tool.uv] exclude-newer` 和 Dependabot 配置中使用的相同约定。
### 2. 电子邮件连接(目前为 Gmail MCP)
导入、同步和分配 CVE 技能会**读取与每个追踪器关联的安全列表邮件线程**并在该线程上起草回复。目前这是通过 [Claude Gmail MCP](https://docs.anthropic.com/en/docs/build-with-claude/mcp) 进行的,该 MCP 连接到已订阅采用项目安全列表的安全团队成员的个人 Gmail 帐户(参见 `/project.md → Mailing lists`)。这足以为技能提供查看入站报告和在正确线程上创建草稿的访问权限。
一个面向整个 ASF 的替代方案正在酝酿中:
[`rbowen/ponymail-mcp`](https://github.com/rbowen/ponymail-mcp)(由前 ASF 董事会董事兼 ComDev 负责人 Rich Bowen 开发)现已支持 OAuth 身份验证,并可以读取私有的 ASF 列表。一旦 ASF OAuth 接入,个人分类人员应该能够运行这些技能而无需连接他们的个人 Gmail——直接针对 ASF 凭据(并最终针对 ASF 的新 MFA)进行身份验证就足够了。在那之前,Gmail MCP 是唯一的途径。
**如果没有此连接:** `import-security-issue` 将无法找到新报告,`sync-security-issue` 将无法与邮件线程协调状态,并且没有任何技能可以起草给报告人的回复。技能将拒绝启动并告诉您首先配置 MCP。
### 3. GitHub 连接(GitHub MCP / `gh` CLI)
每个技能都会读取和写入 `` 问题。Claude Code 默认附带了 GitHub MCP,并且这些技能在某些调用中也会直接使用 `gh` CLI。这些技能需要:
- 运行 Agent 的 shell 上具有已认证的 `gh auth status`。
- 对 `` 具有协作者访问权限(任何权限级别)——安全团队名单按项目维护;对于当前活动项目,请参见 [`/release-trains.md`](/release-trains.md#security-team-roster)。
- 对于 `fix-security-issue`:您的 GitHub 帐户上需要有一个 `` 的分叉(技能在通过 `gh pr create --web` 发起 PR 之前会将分支推送到那里)。
### 4. PMC 成员资格(仅用于 CVE 分配)
采用项目的 CVE 工具分配表在服务器端是**受 PMC 限制**的——只有项目的 PMC 成员才能提交 CVE 分配。非 PMC 的分类人员仍然可以运行 `allocate-cve`;该技能会预先检测到这一点(它会询问*“您是 `` 的 PMC 成员吗?”*),并生成一条中继消息,供 PMC 成员点击完成。对于 Airflow,具体的工具是位于 的 ASF Vulnogram;参见 [`/project.md → CVE tooling`](/project.md#cve-tooling)。
同样的 PMC 限制也适用于私有 ASF 列表上的 ponymail URL 查找;直到 `ponymail-mcp` 接入 ASF OAuth 之前,只有 PMC 成员才能直接查看私有列表存档。
### 5. 浏览器(用于人工点击步骤)
流程的几个部分涉及人类必须填写并点击的表单——CVE 工具分配表、CVE 记录 `#source` 粘贴、`gh pr create --web` 编辑视图。这些技能会准备好 URL 和要粘贴的精确文本,并将其移交给浏览器;它们不会尝试自动执行这些点击。
### 6. 本地 `` 克隆(仅用于 `fix-security-issue`)
修复技能会在您的本地克隆中写入更改,运行本地检查和测试,分支推送到您的分叉,并通过 `gh pr create --web` 发起 PR。您需要:
- 一个可从 Agent 工作目录访问的 `` 干净克隆——路径来自 `config/user.md → environment.upstream_clone`,在您第一次运行该技能时交互式设置;
- 按照其贡献文档安装采用项目的开发工具链——对于 Airflow,请参见 [`/fix-workflow.md → Toolchain`](/fix-workflow.md#toolchain);
- 一个以您的 GitHub 分叉命名的 remote,`gh pr create` 可以推送到该 remote。
### 7. `uv`(用于 `generate-cve-json`)
`generate-cve-json` 脚本是一个由 `uv` 管理的小型 Python 项目。安装一次 `uv` 即可();该脚本会引导完成其余工作。
## 共享约定
这些约定约束着每个角色。如果您不确定某条规则是否适用于您,那么它就是适用的。
### 让报告人随时了解进展
安全团队承诺在**每次状态转换时**,在原始邮件线程(而不是在 GitHub 通知镜像线程)上向原始报告人通报其报告的状态。每当发生以下任何情况时,都应向报告人发送简短的状态更新:
* 报告已被确认或评估(有效 / 无效);
* 已分配 CVE;
* 已发起修复 PR;
* 修复 PR 已**合并**;
* 问题已安排在特定的发布版本中(已设置里程碑);
* 版本已发布并且公开公告已发送;
* CVE 记录已在 cve.org 上发布(完成披露);
* 最终公开公告中可见的任何致谢信息或字段已更改。
每次状态更新都应明确说明发生了什么变化,链接到相关的产物(PR URL、CVE ID、公告链接),并说明接下来会发生什么。如果报告人尚未回复他们偏好的致谢方式,请提出致谢偏好的问题——但是,**如果已经在同一线程上提出过该问题并且仍在等待回复,请勿再次询问**。就同一个未解决的问题两次催促报告人是不礼貌的,会导致我们被拉黑;如果在发布前他们没有回复,则默认使用原始电子邮件中报告人的全名。
常见情况的可复用措辞位于 [`/canned-responses.md`](/canned-responses.md)——在从头起草回复之前请先查阅它。
### 在追踪器上记录状态转换
**每次状态转换也必须作为评论记录在 `` 中的 GitHub 问题上**,而不仅仅是通过电子邮件发送。这两个渠道服务于不同的受众:电子邮件让报告人了解情况;问题评论让安全团队的其他成员和发布管理员了解情况,而无需强迫他们从标签和时间戳重建状态。评论应简要说明发生了什么变化,链接到相关产物(PR URL、CVE ID、公告链接),并指出是否已通知报告人。
### 机密性
私有追踪器(采用项目的 ``)的机密性既是一项**生命周期规则**,也是一项**写作规则**:
您在追踪器上记录的每次转换、每条状态评论、每份电子邮件草稿都必须尊重它。完整的规则集——禁止的表面、允许的表面、清理指南、针对私有 `security@` / `private@` 线程和仓库内 `gh issue comment` 调用的例外桶——位于 [`AGENTS.md` — Confidentiality of the tracker repository](AGENTS.md#confidentiality-of-the-tracker-repository)。
在编辑可能在团队外部可见的任何内容之前,请先阅读它。
## 给问题分类者 — 步骤 1–6
您拥有从 `` 上的入站报告到分配 CVE、应用范围标签、并为修复开发者准备好接手问题的整个追踪器。步骤 6(CVE 分配本身)受 PMC 限制:**只有采用项目的 PMC 成员才能提交 CVE 工具分配表**。如果您不是 PMC 成员,您需要将预先起草的请求中继给 PMC 成员——无论哪种方式,您都是将最终生成的 CVE ID 落实回追踪器的人。
### 日常分类循环
典型的分类扫荡按顺序运行三个技能:
1. **`import new reports`** — [`import-security-issue`](.claude/skills/import-security-issue/SKILL.md) 扫描 `` 以查找尚未导入的线程,对每个候选进行分类(真实报告 vs. 自动扫描/综合/媒体/垃圾邮件),并为每个有效报告提出一个追踪器以及一份确认收据的 Gmail 草稿。参见 [步骤 2](#step-2--import-the-report)。
2. **`sync all`** — [`sync-security-issue`](.claude/skills/sync-security-issue/SKILL.md) 将每个打开的追踪器与其邮件线程、修复 PR、发布列车和 users@ 存档进行协调。在一次运行中提出标签/里程碑/受让人/正文更改。
3. **`allocate CVE for issue #N`** — 当报告被评估为有效时的 [`allocate-cve`](.claude/skills/allocate-cve/SKILL.md)。参见 [步骤 6](#step-6--allocate-the-cve)。
没有明确的确认,不会应用任何内容——每个技能都是一个提案引擎,而不是自动驾驶仪。
### 评估报告
对于每个 `needs triage` 追踪器,在评论中推动有效性评估,至少邀请另一位安全团队成员参与讨论。使用 [`/canned-responses.md`](/canned-responses.md) 中的 canned response 模板进行负面评估,以便语气保持礼貌但坚定。
当报告被确认为有效时,从项目范围集合中精确应用一个范围标签(在 [`/scope-labels.md`](/scope-labels.md) 中声明)。
如果一份报告影响多个范围,请在分配前拆分为按范围分类的追踪器——`sync-security-issue` 技能会将此作为一个阻碍项呈现。参见 [步骤 5](#step-5--land-the-validinvalid-consensus)。
如果讨论停滞了大约 30 天,请根据 [步骤 4](#step-4--escalate-stalled-discussions) 升级给更广泛的受众。
### 分配 CVE
使用 [`allocate-cve`](.claude/skills/allocate-cve/SKILL.md)。该技能会预先询问您是否在 PMC 中;如果不在,它会将方案重塑为 ``@``-提及的中继消息,您将其转发给追踪器或 `` 线程上的 PMC 成员。一旦分配的 `CVE-YYYY-NNNNN` 被粘贴回来,该技能会一次性将其连接到追踪器中(*CVE tool link* 正文段、`cve allocated` 标签、状态更改评论、刷新的 CVE-JSON 附件),并交接给 `sync-security-issue` 以协调追踪器的其余部分。完整细节请参见 [步骤 6](#step-6--allocate-the-cve)。
### 最常用的工具
- [`import-security-issue`](.claude/skills/import-security-issue/SKILL.md) — 每次分类扫荡开始时的*“导入新报告”*。这是 `` 报告进入流程的入口点。
- [`import-security-issue-from-pr`](.claude/skills/import-security-issue-from-pr/SKILL.md) — 当与安全相关的修复在未经过 `` 的情况下公开落地,且团队已同意其值得申请 CVE 时的*“从 PR 导入追踪器”*。直接落在 `Assessed` 列中。
- [`sync-security-issue`](.claude/skills/sync-security-issue/SKILL.md) — *“同步 ”* 或 *“同步所有”*。在一个组合提案中呈现停滞的问题、缺失的字段、致谢回复和范围拆分要求。
- [`allocate-cve`](.claude/skills/allocate-cve/SKILL.md) — *“为 分配 CVE”*。
- [`generate-cve-json`](tools/vulnogram/generate-cve-json/SKILL.md) — 按需刷新嵌入在问题正文中的可直接粘贴的 JSON。
- [`deduplicate-security-issue`](.claude/skills/deduplicate-security-issue/SKILL.md) — 当两个追踪器描述独立发现的相同根本原因错误时。
- [`invalidate-security-issue`](.claude/skills/invalidate-security-issue/SKILL.md) — 一旦步骤 5 达成无效共识,执行*“关闭 NN 为无效”*。应用 `invalid` 标签,归档项目看板项,并(对于从 `` 导入的追踪器)起草一份向报告人解释理由的回复。
## 给修复开发者 — 步骤 7–11
您拥有从分配 CVE 到在 `` 中合并公开修复 PR(包括 `pr merged` 交接,此时追踪器等待发布列车发布)的整个追踪器。该角色名称与您在已发布的 CVE 记录中获得的 `remediation developer` 致谢相匹配(参见生成的 CVE JSON 中带有 `type: "remediation developer"` 的 `credits[]`)。
### 接手追踪器
选择一个带有范围标签、`cve allocated` 且对修复方案有明确共识的追踪器。在 GitHub 上自行指派自己,以便看板反映所有权。参见 [步骤 7](#step-7--self-assign-and-implement-the-fix)。
### 尝试自动修复
在手动编写修复之前,考虑让 [`fix-security-issue`](.claude/skills/fix-security-issue/SKILL.md) 技能先尝试一下。作为*“尝试修复问题 #N”*(或*“为 #N 起草 PR”*)调用时,该技能会:
- 首先运行 `sync-security-issue` 以确保追踪器的状态是最新的;
- 阅读完整的追踪器讨论和链接的 `security@` 邮件线程,并决定该问题是否*易于修复*——对修复方案有明确共识、范围小、在 `` 中位置已知。如果不是,该技能会停止并告诉您在尝试修复之前追踪器还需要什么;
- 如果是,则提出实施计划(要修改哪些文件、更改什么、添加哪些测试),并在进行任何编辑之前**等待您的明确确认**;
- 在您的本地 `` 克隆中写入更改,运行本地静态检查和测试,并在失败时进行迭代;
- 通过 `gh pr create --web` 从您的分叉发起公开 PR,并带有经过净化处理的标题和正文——在写入或推送之前,每个公开表面(提交消息、分支名称、PR 标题、PR 正文、newsfragment)都会经过 grep 检查,防止泄露 `CVE-`、`` 仓库 slug、`vulnerability`、*“security fix”* 及类似信息;
- 使用新的 PR 链接更新 `` 追踪问题,并应用 `pr created` 标签,然后交接回 `sync-security-issue`。
在仍然需要人工决策的情况下,该技能会拒绝继续:仍在评估中的报告、尚未归类为有效漏洞的报告,以及需要 [步骤 9](#step-9--open-a-private-pr-exceptional-cases) 中私有 PR 后备方案的更改。如果它拒绝,请退回到下面的手动流程。
即使该技能端到端成功,您仍然是公开 `` PR 的作者和面向审查者的联系人。请在审查和合并期间继续关注该 PR。
### 手动发起公开修复 PR
如果您正在手动编写修复,请在您的本地 `` 克隆中编写代码更改,运行本地检查和测试,并通过 `gh pr create --web` 发起 PR。PR 描述**绝不能**透露 CVE、更改的安全性质或链接回 ``——参见 [步骤 8](#step-8--open-a-public-pr-straightforward-cases) 和 [`AGENTS.md`](AGENTS.md#confidentiality-of-the-tracker-repository) 中的机密性规则。
当修复应在补丁列车上发布时,请在公开 PR 上请求 `backport-to-v3-2-test`(或等效的)标签。
### 私有 PR 后备方案
在特殊情况下——高度关键的修复,或需要私有审查的代码——请向 `` 的 `main` 分支而不是 `` 发起 PR。那里不会运行 CI,因此在请求审查之前请手动运行静态检查和测试。获得批准后,通过公开推送分支在 `` 中重新发起 PR。参见 [步骤 9](#step-9--open-a-private-pr-exceptional-cases)。
### 交接给发布管理员
一旦 `` PR 合并,`sync-security-issue` 会将追踪器从 `pr created` 移至 `pr merged`,并设置修复将随其发布的版本的里程碑。然后追踪器等待发布列车。当发布版本发布时,sync 会将 `pr merged` 交换为 `fix released`,追踪器便成为发布管理员的责任。参见 [步骤 11](#step-11--pr-merged) 和 [步骤 12](#step-12--fix-released)。
### 最常用的工具
- [`fix-security-issue`](.claude/skills/fix-security-issue/SKILL.md) — *“尝试修复问题 #N”*。提出计划、编写代码、运行本地测试,并使用净化后的标题/正文发起一个 `--web` PR。完整流程以及技能拒绝继续的情况,请参见上面的 [尝试自动修复](#attempting-an-automated-fix)。
- [`sync-security-issue`](.claude/skills/sync-security-issue/SKILL.md) — 在 PR 经历审查和合并的过程中,保持追踪器的标签、里程碑和受让人与 PR 状态对齐。
## 给发布管理员 — 步骤 12–15
您拥有从修复实际发布(`fix released`)到带有已发布 CVE 记录的关闭追踪问题的整个追踪器。从修复开发者的交接是自动的:`sync-security-issue` 检测 PyPI / Helm 注册表上的里程碑版本,将 `pr merged` 交换为 `fix released`,并将发送公告的任务分配给您。
### 从修复开发者处交接
在看板上关注您的 `fix released`队列。在 `pr merged` → `fix released` 交换触发之前,追踪器仍属于修复开发者(步骤 11 领域)。一旦触发,它就是您的了。参见 [步骤 12](#step-12--fix-released)。
### 发送安全公告
审查追踪器上附加的 CVE JSON,填写任何缺失的正文段(CWE、严重性、受影响版本),并通过 ASF CVE 工具将公告电子邮件发送到 `` / ``。
添加 `announced - emails sent` 并移除 `fix released`。**此时不要关闭问题**——参见 [步骤 13](#step-13--send-the-advisory)。
### 捕获公共存档 URL
这是一次由同步技能为您处理的交接:一旦公告在 users@ 列表上存档,下一次运行 `sync-security-issue` 会找到该 URL,填充 *Public advisory URL* 正文段,重新生成 CVE JSON 附件,并将标签移至 `announced`。参见 [步骤 14](#step-14--capture-the-public-advisory-url)。
### 发布 CVE 并关闭问题
对于每个 `announced` 问题:在 `https://cveprocess.apache.org/cve5/#source` 打开 Vulnogram,粘贴最新附加的 CVE JSON,保存,并将记录从 REVIEW 移至 PUBLIC。
然后关闭问题(不要更新任何标签)。这是生命周期的最后一步。参见 [步骤 15](#step-15--publish-the-cve-record-and-close-the-issue)。
停留在 `announced` 超过一两天的问题,就是提醒 RM(发布管理员)的信号。
### 发布后的致谢信息更正
如果在发布公告后需要更正致谢信息,请回复公告电子邮件并附上缺失的致谢信息,更新 ASF CVE 工具,并要求 ASF 安全团队将信息推送到 `cve.org`。参见 [步骤 16](#step-16--credit-corrections)。
### 最常用的工具
- [`sync-security-issue`](.claude/skills/sync-security-issue/SKILL.md) — 在每个发布窗口开始时的*“同步已公告项”*,以查看需要进行 Vulnogram 推送的 `announced` 积压。还有在发送公告之前深入查看特定 CVE 的*“同步 CVE-YYYY-NNNN”*。
- [`generate-cve-json`](tools/vulnogram/generate-cve-json/SKILL.md) — 在捕获 URL 后正文段发生更改时,按需重新生成附件。
## 流程参考:16 个步骤
这是生命周期的权威分步描述。上面每个角色部分都指向了特定的步骤。如果角色部分中的内容与此处的内容有冲突,请以此参考为准。
### 步骤 1 — 报告到达 security@
报告人向采用项目的 `` 或 `security@apache.org` 报告问题(在后一种情况下,Apache 软件基金会的安全团队会将该问题转发给项目的安全邮件列表)。
### 步骤 2 — 导入报告
**将报告作为追踪问题导入到 `` 中。** [`import-security-issue`](.claude/skills/import-security-issue/SKILL.md) 技能是流程的入口:它扫描 `` 以查找尚未导入的线程,对每个候选进行分类(真实报告 vs. 自动扫描/综合/媒体/垃圾邮件),从根消息中提取问题模板字段,并为每个有效报告提出一个追踪器以及一份确认收据的 Gmail 草稿。
没有用户的明确确认,不会应用任何内容。安全团队成员运行该技能(*“导入新报告”*)作为分类扫荡的第一个动作;新创建的问题会带有由问题模板自动设置的 `needs triage` 标签,草稿回复则在 Gmail 中准备好供分类者审查和发送。
如果报告“明显无效”(我们以前见过此类问题并已分类或回复)——例如自动扫描器转储或综合多问题报告——该技能会从 [`/canned-responses.md`](/canned-responses.md) 中提出匹配的 canned response 作为 Gmail 草稿,并且**不会**创建追踪器,因此无效类别永远不会进入看板。
此时追踪器还没有范围标签——它将在步骤 5 确认有效性时被应用。
**备用入口点——在公开 PR 中发现。** 有时,与安全相关的修复作为公开 PR 在 `` 上落地,而从未经过 ``(贡献者发起了一个看起来很常规的修复,安全团队后来意识到它值得申请 CVE)。对于这种情况,请使用 [`import-security-issue-from-pr`](.claude/skills/import-security-issue-from-pr/SKILL.md) 而不是 `import-security-issue`。该技能接受一个 PR URL/编号,从更改的文件路径检测范围,并直接在 **`Assessed`** 列中创建带有范围标签的追踪器——故意的导入意味着安全团队已经非正式地认定该报告是安全问题,因此步骤 5 的有效性讨论关卡被跳过,追踪器立即准备好进行 `allocate-cve`。此路径上没有需要确认的报告人,因此不会创建 Gmail 草稿。仅当安全相关性已达成一致时才使用此技能;对于真正不确定的报告,请先在安全团队聊天中讨论,然后如果有报告人参与则通过 `security@` 路由,或者手动发起一个 `Needs triage` 追踪器。
### 步骤 3 — 讨论是否值得申请 CVE
在问题中,我们讨论并就是否值得为其申请 CVE 达成一致。
### 步骤 4 — 升级停滞的讨论
如果讨论停滞并且我们在大约 30 天内无法做出决定,请将其升级给更广泛的受众。升级分为**两个阶段**进行——阶段 1 是简短的意见征集;阶段 2,如果阶段 1 在另外大约 7 天后仍然没有回应,将是一份 AI 生成的方案空间分析,旨在通过呈现具体的选项来推动讨论解开僵局。**这两个阶段都是提案,由推动升级的分类者在发布前进行审查**——Agent 不会在未经分类者明确“放行”的情况下向追踪器、`` 线程、`` 线程或报告人发布任何内容。
受众(两个阶段相同):
* ``
* `security@apache.org`
* 提出该问题的报告人,询问他们的意见和补充背景
#### 阶段 1 — 简短的意见征集(无 AI 分析)
第一封升级邮件**故意设计得很简短**。它说明了报告的存在、内部讨论已停滞约 30 天,向更广泛的受众征求输入,并链接追踪器 URL 作为稳定标识符——根据[三层机密性规则](AGENTS.md#confidentiality-of-the-tracker-repository),这在私有或公开受众面前都是安全的(URL 是公开安全的;追踪器内容和安全框架保持受限)。它**不**包括方案空间分析或建议的修复——那是阶段 2 的工作。阶段 1 的重点是让尚未看到报告的领域专家有机会用自己的想法发表意见,而不被预先准备好的解决方案所锚定。
阶段 1 消息格式(3-4 个简短段落):
1. 一句话:追踪器 `#NNN`,CVE `CVE-…`,一行描述。
2. 一句话:讨论已停滞 `` 天,最后一次实质性评论是在 `` 由 `` 发表。
3. 一句话:我们正在征求关于设计/修复方向的意见;欢迎任何想法。
4. 相关链接(仅在私有受众面前提供追踪器 URL;GHSA URL(如适用);报告人线程 ID)。
分类者在 Agent 的辅助下起草此内容,Agent 将草稿作为提案呈现以供审查(Gmail 草稿 + 状态汇总预览),并且只有在分类者确认后,Agent 才会发送/发布。
#### 阶段 2 — AI 生成的方案空间分析
当阶段 1 发布了**另外大约 7 天**仍然没有实质性回复时(沉默、“+1 看起来很糟”而没有修复建议、或已阅但无参与),Agent 会准备一份更深入的分析以解开设计问题。格式如下:
1. **以 AI 生成的免责声明开头**——分析由 AI Agent 起草,分类者在发布前对其进行了审查,可能存在错误。邀请审查者对任何感觉不对的地方提出质疑。
2. **标记方法**——解释被 ping 的人是如何被选中的。标准方法:交叉参照 讅 `` 以来受影响文件的前列提交者(通过 `git log` 统计提交频率)、`` 协作者列表(`gh api repos//collaborators`)以及线程上已参与的成员。
3. **TL;DR**——一段话,包含建议的短期+长期修复组合。
4. **为什么显而易见的修复是不够的**——如果讨论中已经出现了“只需做 X”的建议,而 Agent 认为这是不完整的,请具体解释差距(用代码示例展示绕过方法)。这是分析中最具承载力的部分——它将停滞的“我们应该做 X 吗?”转化为具体的“仅靠 X 无法解决案例 Y,这是替代方案”。
5. **方案空间选项**——标记为 A、B、C 等。每个选项包括:*它做什么*(有用的具体代码草图)、*它解决了什么*、*它没有解决什么*、*风险*(部署兼容性问题、迁移成本等)。
6. **开放设计问题**——在任何选项可以发布之前需要人工决策的 3-5 个阻碍。这些是 Agent 无法自行决定的事情(选择哪个选项、如何处理迁移、是否偏离项目约定)。
7. **内联 + 底部标记人员**,根据上述方法使用 `@`-提及。
Agent 将完整的草稿作为提案呈现——整个评论文本,以及它打算提及的 `@`-句柄列表和选择理由。**分类者在 Agent 将其发布到追踪器之前审查并批准草稿。** 这同样适用于将分析镜像给 PMC 受众的任何并行的 `` 邮件草稿。
如果分类者编辑了草稿,Agent 会应用编辑并重新提交以供确认。Agent 不会自行“迭代至高质量”——对分析的每一次可见更改都要经过分类者。
#### 在追踪器上记录升级
两个阶段都作为汇总条目落地到追踪器上(根据 [`tools/github/status-rollup.md`](tools/github/status-rollup.md)),使用操作标签 `Sync (Step 4 escalation)` 进行标记,以便审计跟踪显示每个阶段在时间线中的发送位置。阶段 1 条目记录发出的消息和沉默期时钟的启动;阶段 2 条目记录 AI 分析评论 + 被 ping 的人员列表 + 触发阶段 2 的阶段 1 之后的 7 天沉默。
#### 为什么要分阶段
将 AI 生成的分析作为*第一*个升级步骤发布,会缩短阶段 1 旨在产生的两个最佳结果:
- **领域专家提出了 Agent 没有想到的修复方案。** 阶段 1 为 Agent 文献中未涵盖的想法留出了空间——特别是对于具有深厚领域知识的人来说显而易见,但从文件差异中不可见的跨领域架构模式。AI 分析往往收敛于报告人建议的选项+标准强化模式;它*会*错过新颖的方法。
- **专家标记报告无效/超出范围。** 有时正确的答案是“这是已记录的行为”或“这重复了 2 年前的 `#XYZ`”;而已经提出修复方案的 AI 分析会将讨论锚定在*实施*该修复上,而不是评估是否需要修复。
阶段 2 用于阶段 1 显然未能产生上述任何结果的情况。直接跳到阶段 2 会将升级变成一个“批准这个设计”的请求,这与更广泛的受众步骤的目的恰恰相反。
### 步骤 5 — 达成有效/无效共识
最后,如果我们无法达成共识,我们将遵循 [投票](https://www.apache.org/foundation/voting.html#apache-voting-process)。
使用代码修改投票,这意味着提交者拥有约束性投票,而其他所有人都拥有建议性投票——并且鼓励所有人投票并表达意见。如果在讨论期间没有重大分歧,则无需通过邮件列表线程进行正式投票——投票在 PR 中进行。但是,如果存在不同意见,则在 `` 列表上进行投票。然后应移除 `needs triage` 标签。
### 步骤 6 — 分配 CVE
如果我们同意该问题无效,团队成员将关闭该问题并将该信息回复给报告人。[`invalidate-security-issue`](.claude/skills/invalidate-security-issue/SKILL.md) 技能是应用机制:它将追踪器标记为 `invalid`,发布简短的关闭评论,归档项目看板项,并且——当追踪器有入站 `` 线程时——在原始 Gmail 线程上起草一封礼貌但坚定的回复给报告人,理由提取自追踪器的讨论,并使用 [`/canned-responses.md`](/canned-responses.md) 中合适的 canned response 作为骨架。该草稿永远不会被自动发送——分类者会在 Gmail 中审查后再发送。如果已经分配了 CVE(需要先在 Vulnogram 中执行 REJECT)或者公告已经发布(公开撤回需要明确的团队升级),该技能会硬性停止。
如果问题有效,**采用项目的 PMC 成员**将通过项目的 CVE 工具分配一个 CVE(参见 [`/project.md → CVE tooling`](/project.md#cve-tooling))。
分配操作在服务器端受 PMC 限制,因此不在 PMC 中的分类者无法自行完成分配——他们准备请求(使用 [`allocate-cve`](.claude/skills/allocate-cve/SKILL.md) 技能,该技能根据 `/title-normalization.md` 离标题中任何冗余的项目前缀并构建中继消息)并通过在追踪器或 `` 线程上的 `@`-提及将其转发给 PMC 成员。一旦 PMC 成员分配并将 `CVE-YYYY-NNNNN` 报告回来,就可以使用该 ID 作为覆盖重新调用该技能,以将分配的 CVE 连接到追踪器中:*CVE tool link* 正文段、`cve allocated` 标签、状态更改评论和刷新的 CVE-JSON 正文嵌入。
然后,该技能交接给 `sync-security-issue`,以在同一流程中协调追踪器的其余部分(里程碑、受让人、修复 PR 状态、报告人线程草稿)。
团队成员(分类者或 PMC,无论是谁加载了报告人的线程)随后在电子邮件线程中回复,向报告人确认 CVE 的创建,包括 CVE ID,询问报告人希望如何被致谢,并在报告人回答时更新问题描述中的报告人姓名。
### 步骤 7 — 自行指派并实施修复
其中一名团队成员自行指派该问题(不一定是最初发起讨论的人)并实施修复。
注意:在某些情况下,可以将修复委托给可信的第三方个人。例如,如果被指派处理该问题的安全团队成员能够接触到愿意或专门从事采用项目开发的开发人员,他们可以委托给这样一个个人,前提是:
1. 该个人是可信的。
2. 该个人仅接收实施修复所需的信息(不共享安全团队电子邮件、GitHub 问题等的全部内容)。
3. 在与安全问题关联的电子邮件线程或 GitHub 问题中进行 LAZY CONSENSUS 投票(GitHub 通信同步到电子邮件组以供存档)。
### 步骤 8 — 发起公开 PR(简单情况)
如果问题比较简单,可以在 `` 仓库中直接发起 PR。PR 中的描述不应透露 CVE 或其安全性质。
### 步骤 9 — 发起私有 PR(特殊情况)
在特殊情况下——当问题极其关键,或者当代码需要讨论且 PR 在合并前需要输入和审查时——解决问题的人可以在 `` 仓库中创建一个带有“Closes: #issue”的 PR。该 PR 应针对 `` 仓库的 `main` 分支(而不是在 `/project.md → tracker_default_branch` 中声明的默认分支)提出。
这允许私下进行详细的代码更改讨论。目前,`` 仓库中的 PR 不会运行 CI,因此创建 PR 的人应手动运行静态检查和测试。我们将来可能会对此进行改进。一旦 PR 经过审查、批准并准备好合并,带有修复的分支应被推送到 `` 仓库,并且该 PR 应通过将分支推送到公开的 `` 并在那里重新发起以进行合并。
### 步骤 10 — 关联 PR 并应用 `pr created`
一旦在 `` 仓库中创建了 PR,创建它的团队成员应在问题描述中链接到该 PR,并在 `` 上为问题标记 `pr created` 标签。
### 步骤 11 — PR 合并
**PR 合并。** 当 `` PR 合并时,合并它的安全团队成员应将问题从 `pr created` 移至 `pr merged`。如果 `` 仓库中存在该 PR 的私有变体,则应将其关闭。问题的里程碑应设置为计划随其发布的版本的里程碑。
**里程碑命名约定**是项目特定的;对于当前采用的项目,请参见 [`/milestones.md`](/milestones.md),其中也记录了通过 `gh api` 创建缺失里程碑以及当分类需要时将修复推迟到下一个小版本而不是下一个补丁版本的策略。
**问题停留在 `pr merged` 状态,直到包含修复的发布版本实际发布。** 这可能是几小时(对于以快速节奏发布的核心补丁版本)或几周(对于按固定月度计划发布的 provider 波次)。在该窗口期间,问题在等待发布列车,而不是等待安全团队的任何操作——下一次转换会在发布到达 PyPI / Helm 注册表时自动触发(步骤 12)。
### 步骤 12 — 修复发布
**修复发布。** 当包含修复的版本实际向用户发布时——最终发布产物(根据采用项目的发布列车约定;对于 Airflow,请参见 [`/milestones.md`](/milestones.md)) 在项目的包索引上线——问题将从 `pr merged` 移至 `fix released`。`sync-security-issue` 技能检测到发布(通过在项目的包索引上检查里程碑版本),并在下次运行时提出标签交换建议,因此在实践中此过渡是自动的;安全团队成员只需确认同步提案即可。
**为什么这是一个独立的步骤。** `pr merged` → `fix released` 的交换是问题所有权已从修复作者/分类者转移到该版本的**发布管理员**的提示。在 `fix released` 之前,问题是一个代码更改产物;在 `fix released` 之后,它是一个公告协调产物,发布管理员负责下面的步骤 13–15。将两者合并为一个步骤会使这种所有权交接变得隐式;将它们分开使其显式化,并呈现一个发布管理员可以从看板驱动的 `fix released` 积压。
**交接评论。** 提议 `pr merged` → `fix released` 交换的同一 `sync-security-issue` 运行也会提议在追踪器上发布一条明确的**发布管理员交接评论**——一份独立的、带编号的清单(从 RM 的角度看的步骤 13–15),该清单 @`-提及发布管理员并链接到可直接粘贴的 CVE JSON、Vulnogram 的 `#source` 和 `#email` 选项卡以及 canned response 模板。该评论是一次性的,每个追踪器只发布一次;后续的同步运行会通过 HTML 标记检测到它并跳过发布。
这是一个独立的一级评论,而不是状态汇总条目——汇总是为了安全团队的审计跟踪,交接是 RM 的行动号召表面。
### 步骤 13 — 发送安全公告
在发布期间,发布管理员会查看 `` 上的 `fix released` 问题,更新项目的 CVE 工具(对于 Airflow,即 [the ASF CVE tool](https://cveprocess.apache.org);通常请参见 `/project.md → CVE tooling`),并从问题中提取信息更新以下字段:
* CWE(通用弱点枚举)——可能的 CWE 可在[此处](https://cwe.mitre.org/data/index.html)获取
* 产品名称——根据采用项目的 scope-label → 产品映射(对于 Airflow,请参见 [`/scope-labels.md`](/scope-labels.md))
* 受影响版本(`0, < Version released`)
* 简短公开摘要
* 严重性评分——基于 [Severity Rating 博客文章](https://security.apache.org/blog/severityrating)。
问题所有者应在问题讨论期间提出评分并更新工单。在没有异议的明显情况下,这应该以 lazy-consensus 模式进行。如果存在不同意见,推动讨论达成共识是首选结果。如有必要可进行投票。如果在早期讨论期间尚未决定严重性或达成共识,发布管理员对严重性评分拥有最终决定权(但应考虑安全团队的意见)。这是为了优先及时发布问题公告。
* 参考:
* `patch` —— `` 仓库中针对该修复的 PR
* 致谢:
* `reporter` —— 问题的报告人
* `remediation developer` —— PR 作者
发布管理员还会生成 CVE 描述,如果需要反馈则将 CVE 设置为 REVIEW 然后设置为 READY,并最终从 CVE 工具发送公告电子邮件。然后发布管理员添加 `announced - emails sent` 标签并移除 `fix released` 标签。
**此时问题保持打开状态**——它只在下面的步骤 15 中,在捕获了公共存档 URL(步骤 14)并在 Vulnogram 中将 CVE 记录移至 PUBLIC(步骤 15)之后才会关闭。这给了 `sync-security-issue` 技能另一个交接点,它可以注意到缺失的存档 URL 并在问题被遗忘之前发出提示。
### 步骤 14 — 捕获公共公告 URL
**捕获公共公告 URL 并将追踪器移至 `announced`。** 一旦公告电子邮件已发送并存档,这将由下一次 `sync-security-issue` 运行完成(或者由发布管理员手动驱动):
* 从 [users@ list archive](https://lists.apache.org/list.html?) 检索存档 URL——`sync-security-issue` 技能在每次运行时都会扫描存档以查找 CVE ID,并在找到匹配项时自动提出 URL;
* 将 URL 粘贴到追踪问题的 **Public advisory URL** 正文段中(该字段是专门为此交接添加到问题模板中的——切勿复用 *“Security mailing list thread”* 字段,该字段保存的是私有的 `security@` 线程);
* 重新生成 CVE JSON 附件——`generate-cve-json` 现在会自动从正文中提取 URL,并将其在 `references[]` 中标记为 `vendor-advisory`,因此附加的 CVE 记录带有一个可解析的 `vendor-advisory` 链接,准备好粘贴到 ASF CVE 工具中;
* **添加 `announced` 标签**到追踪问题。此时问题**保持打开状态**——关闭是发布管理员在下面的步骤 15 中的工作,在他们将 CVE 记录在 Vulnogram 中移至 PUBLIC 之后。
直到 *Public advisory URL* 字段被填充,`sync-security-issue` 技能才会提议将问题移至 `announced`——这是故意的:该字段是 CVE 记录的公共 `vendor-advisory` 引用将指向的位置,发布带有空引用的 CVE 会将损坏的记录泄露到 `cve.org`。
**可发布的通知评论。** 填充 *Public advisory URL* 正文段的同一次同步运行也会提议在追踪器上发布**可发布的通知评论**——一条独立的、一级的评论,它 `@`-提及发布管理员,总结刚刚落地确定的更新(URL 已捕获、JSON 已重新生成、`announced` 标签已添加),并给出最终粘贴 + `READY` → `PUBLIC` 移动以及追踪器关闭的明确许可。就像步骤 12 的交接评论一样,它是一次性的,每个追踪器只发布一次(在后续运行中通过 HTML 标记实现幂等)。
这两条评论共同构成了一个两部分叙事,发布管理员可以从追踪器页面驱动,而无需查阅汇总或外部文档。
### 步骤 15 — 发布 CVE 记录并关闭问题
**推送最终 CVE 记录并关闭问题。** 对于每个带有 `announced` 标签的问题,发布管理员(即在步骤 13 中发送公告的同一人):
* 在 `https://cveprocess.apache.org/cve5/#source` 打开 Vulnogram `#source` 选项卡;
* 从追踪问题中复制最新的 CVE JSON 附件(在步骤 14 中重新生成的,现在带有 `vendor-advisory` URL 的那份)并将其粘贴到 `#source` 表单中;
* 在 ASF CVE 工具中保存并将记录从 `READY` 移至 `PUBLIC`——**这是将记录传播到 [`cve.org`](https://cve.org) 的最终操作**;
* **关闭问题**——不要更新任何标签。这结束了生命周期。`sync-security-issue` 技能跟随关闭操作执行显式的 `archiveProjectV2Item` 突变,以便关闭的追踪器永久离开活动看板(参见 [`tools/github/project-board.md` — *Archive a board item*](tools/github/project-board.md#archive-a-board-item--terminal-state-cleanup))。
这种两步交接(同步捕获 URL → RM 发布记录)意味着没有人需要同时记住这两半:同步技能的责任在标签变为 `announced` 时结束,而 RM 的责任范围仅限于将 `announced` 问题带入关闭状态。停留在 `announced` 超过一两天的问题就是提醒 RM 的信号。
### 步骤 16 — 致谢更正
如果我们需要添加缺失的致谢(这种情况有时由于复制粘贴错误和流程的脆弱性而发生),发布管理员需要:
* 回复公告电子邮件并提及缺失的致谢
* 使用缺失的致谢更新 [ASF CVE 工具](https://cveprocess.apache.org)
* 要求 ASF 安全团队将信息推送到 [cve.org](https://cve.org)
## 标签生命周期
### 状态图
下图显示了典型的状态流。每个节点是一个标签(或共存的标签簇);每条边是推动问题前进的流程步骤。关闭处置(`invalid`、`not CVE worthy`、`duplicate`、`wontfix`)可以在 `needs triage` 之后的任何时候终止流程。
```
flowchart TD
A([report on project security list]) -->|step 2: import-security-issue| B[needs triage]
A2([security-relevant fix in public PR]) -->|step 2 alt: import-security-issue-from-pr| C
B -->|step 5: consensus invalid| X1([invalid / not CVE worthy / duplicate / wontfix])
B -->|step 5: consensus valid| C["scope label
(project-specific — see
projects/<PROJECT>/scope-labels.md)"] C -->|step 6: CVE reserved by PMC member| D[cve allocated] D -->|step 10: public PR opened| E[pr created] E -->|step 11: PR merges| F[pr merged] F -->|step 12: release ships| G[fix released] G -->|step 13: advisory sent| H[announced - emails sent] H -->|step 14: archive URL captured| J[announced] J -->|step 15: RM moves CVE to PUBLIC + close| Z([issue closed]) classDef closed fill:#f8d7da,stroke:#842029,color:#000; classDef done fill:#d1e7dd,stroke:#0f5132,color:#000; class X1,Z closed; class H,J done; ``` 从 `A2` 进入的虚线等价物代表了上面 [步骤 2](#step-2--import-the-report) 中描述的故意导入路径:从公开 PR 打开的追踪器跳过了 `needs triage` 列,直接落在 `scope label`(项目看板上的 `Assessed` 列),因为有效性评估在调用之前已经非正式地发生了。 ### 标签参考 下表以表格形式重复了相同的流程。问题通常从左到右经历这些标签。 **范围标签是项目特定的**——采用项目的具体范围标签位于 [`/scope-labels.md`](projects/)(对于采用的项目,即 [`/scope-labels.md`](/scope-labels.md))。
下表使用 `` 作为采用项目定义的任何范围标签的占位符。
| 标签 | 含义 | 在步骤添加 | 在步骤移除 |
| --- | --- | --- | --- |
| `needs triage` | 新提交;评估尚未开始。 | 1 | 5 |
| `` | 漏洞的范围。仅设置一个项目特定的范围标签。 | 5 | 从不(在问题的生命周期内一直保留) |
| `cve allocated` | 已为该问题预留了 CVE。分配本身受 PMC 限制(只有采用项目的 PMC 成员才能提交 CVE 工具分配表);非 PMC 的分类人员通过 [`allocate-cve`](.claude/skills/allocate-cve/SKILL.md) 技能将请求中继给 PMC 成员。 | 6 | 从不 |
| `pr created` | 已在 `` 上发起了公开修复 PR 但尚未合并。 | 10 | 11(被 `pr merged` 替换) |
| `pr merged` | 修复 PR 已合并到 `` 中;尚未发布包含该修复的版本。 | 11 | 12(在发布版本发布时被 `fix released` 替换) |
| `fix released` | 包含该修复的版本已向用户发布;公告尚未发送。 | 12 | 13(被 `announced - emails sent` 替换) |
| `announced - emails sent` | 公开公告已发送到项目的 announce 和 users 邮件列表(参见 `/project.md → Mailing lists`)。应用此标签后问题**保持打开**;关闭取决于 RM 完成步骤 15。 | 13 | 从不(在关闭后保留在问题上以供审计历史) |
| `announced` | 公开公告 URL 已被捕获到追踪问题的 *Public advisory URL* 正文段中,并且附加的 CVE JSON 已重新生成,因此其 `references[]` 现在带有 `vendor-advisory` URL。追踪问题正在等待发布管理员将 CVE JSON 复制到项目的 CVE 工具中,将记录移至 PUBLIC 并关闭问题(步骤 15)。关闭时没有标签更改——问题在仍设置 `announced` 的情况下关闭。 | 14 | 从不(在关闭后保留在问题上) |
| `wontfix` / `invalid` / `not CVE worthy` / `duplicate` | 用于无效或不值得申请 CVE 的报告的关闭处置。 | 5 / 6 | — |
[`sync-security-issue`](.claude/skills/sync-security-issue/SKILL.md) 技能保证这些标签的准确性:在每次运行时,它都会检测问题、修复 PR 和发布列车的当前状态,并提出流程要求的标签转换建议。
## 采用该框架
项目并不直接存放在本仓库中——采用者将框架作为 git submodule 拉取到他们自己的追踪器仓库中(参见 [`AGENTS.md`](AGENTS.md#repository-purpose) 中的 *Repository purpose*),并在 `/`(在采用者的追踪器根目录中解析为 `.apache-steward/`)下随附提供其按项目配置的内容。
要引导新的采用者,请将 [`projects/_template/`](projects/_template/) 复制到您追踪器仓库的 `/` 中,填写 TODO 占位符,并通过 [`AGENTS.md` — Placeholder convention](AGENTS.md#placeholder-convention-used-in-skill-files) 中记录的路径解析将框架的技能指向它。
(project-specific — see
projects/<PROJECT>/scope-labels.md)"] C -->|step 6: CVE reserved by PMC member| D[cve allocated] D -->|step 10: public PR opened| E[pr created] E -->|step 11: PR merges| F[pr merged] F -->|step 12: release ships| G[fix released] G -->|step 13: advisory sent| H[announced - emails sent] H -->|step 14: archive URL captured| J[announced] J -->|step 15: RM moves CVE to PUBLIC + close| Z([issue closed]) classDef closed fill:#f8d7da,stroke:#842029,color:#000; classDef done fill:#d1e7dd,stroke:#0f5132,color:#000; class X1,Z closed; class H,J done; ``` 从 `A2` 进入的虚线等价物代表了上面 [步骤 2](#step-2--import-the-report) 中描述的故意导入路径:从公开 PR 打开的追踪器跳过了 `needs triage` 列,直接落在 `scope label`(项目看板上的 `Assessed` 列),因为有效性评估在调用之前已经非正式地发生了。 ### 标签参考 下表以表格形式重复了相同的流程。问题通常从左到右经历这些标签。 **范围标签是项目特定的**——采用项目的具体范围标签位于 [`
标签:Agent, Apache, CVE, CVE分配, GPT, TLS抓取, 安全合规, 安全漏洞, 开发框架, 数字签名, 模块化设计, 漏洞管理, 网络代理, 自动化修复, 软件安全, 逆向工具, 问题分类