Documentation for the security issue dashboard.
schemas/case.schema.json: JSON Schema for the case files that back the dashboard.The dashboard is read-only: it renders a directory tree of JSON files and never writes to it. data_dir in config.yaml points at that tree.
One file is one case: a single reported security issue. It lists every email linked to that issue — the original report, any duplicate reports of the same issue, and follow-ups that are not part of the same mail thread. The file contents are header metadata only (no message bodies) and are described by schemas/case.schema.json. The file path and name carry the classification, as described below.
Every project has a directory named after its PMC:
<data_dir>/ <project>/*.json
A case leaves the project directory once it is resolved, or once it turns out not to be an issue. It then disappears from the project page, and stops adding to the project's debt in the statistics from the date of its last email onwards — or, if its CVE is listed in old_cve_close_dates, from the date given there.
ASF Security moves closed cases into one of two trees that mirror the per-project layout:
<data_dir>/ zzz-resolved/<project>/*.json accepted cases, once resolved zzz-non-issue/<project>/*.json rejected cases archive/ older closed cases, in the same two trees
Only the statistics read these trees to find out when each case was closed: the date of its last email, not counting follow-ups sent after its CVE was published.
To reopen a case, ASF Security moves its file back into the project directory, and the dashboard shows it as open again.
The name of a case file records how the case was classified. Free-form text describing the issue is wrapped in optional tokens:
[CVE-<id> [CVE-<id> …] | YYYY-MM-DD] [<subproject>] [<issue number>] <free text> [wf <state>].json
All of this follows the default process for handling a possible vulnerability, documented for committers.
A file named aaa-<topic>.json or zzz-<topic>.json is not a case but a standing label of the project, collecting every email on one recurring topic. The aaa- labels gather reports that are not handled as cases: for example aaa-dependencies for questions about dependencies, aaa-support for support requests, aaa-glasswing for the reports of the Glasswing scans and aaa-non-fwd for emails that were not forwarded to the project. The zzz- labels hold discussions with the project team that concern no open case, such as zzz-admin. The set of topics is not fixed; the prefixes merely sort these labels before and after the cases.
The dashboard does not treat them specially. While such a file sits in the project directory, the project page shows it as an untriaged case named after its first email, and the statistics count it as open; once it is moved to a closed tree, the statistics ignore it.
Once the case has CVE IDs (allocated by the security team), the name starts with them — repeated, when a single case covers more than one. That also marks the case as confirmed on the project page: it has been accepted and is being resolved.
Every other case is named after YYYY-MM-DD, the day its first report came in. The date is informational: the dashboard takes the dates it displays from the emails, not from the name.
For the PMCs listed in pmcs_with_subprojects, the token after the prefix names the subproject the issue belongs to.
The next token, when it is a number, is the identifier of the issue tracking the case: a Jira issue for the PMCs listed in pmcs_using_jira, a GitHub issue for those listed in pmcs_using_github. Such an issue must not reveal that the case is security-related: either it is private, or it is public and describes the problem as an ordinary bug — see Work in private.
A wf <state> suffix says what the case is waiting for:
| State | Meaning |
|---|---|
wf cve-allocation | The report has been accepted, but no CVE ID has been allocated yet. |
wf non-issue-feedback | The report has been rejected, and the reporter still has to be told why. |
wf non-issue-docs | Rejected as a vulnerability, but the documentation should be improved. |
wf non-issue-upstream | Rejected: the flaw is in an upstream component and has to be fixed, or avoided, there. |
wf disclosure | The fix has been released and the announcement still has to go out. |
| anything else | Shown as “waiting for …”. |
A case with neither CVE IDs nor a wf suffix is untriaged: it is waiting for the project team to investigate the report and accept or reject it.
Beyond what the schema can express:
subj, from, to, cc and reply_to hold raw header values, exactly as they appeared in the message. They may be RFC 2047 encoded words and are decoded, and in the case of the title sanitized, before being rendered.mailtime, subj, from, to and message_id are required. cc and reply_to are read when a producer supplies them: cc helps identify the mailing list an email belongs to, and reply_to recovers the reporter behind a sender rewritten by a list.With check-jsonschema:
find "$DATA_DIR" -name '*.json' -print0 | xargs -0 uvx check-jsonschema --schemafile docs/schemas/case.schema.json