You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@magpie.apache.org by "potiuk (via GitHub)" <gi...@apache.org> on 2026/10/19 14:44:15 UTC

[PR] perf(security-issue-sync): decide bulk mode, guardrails, drafting, GHSA routing and the push flow as code [magpie]

potiuk opened a new pull request, #1710:
URL: https://github.com/apache/magpie/pull/1710

   Layer 4b (part 1) of the security-family deep split (#1672), after #1705 (cve-allocate) and #1707 (deduplicate): the rule-shaped parts of `security-issue-sync` move into an `issue-sync` family of `tools/security-management`. Mining signals, the `signals-to-actions` table and the gather recipe stay with the model and follow in part 2.
   
   ## What moves to code
   
   | Where | Command | Decides / renders |
   |---|---|---|
   | Inputs / bulk 1 | `selector`, `resolve` | the selector as `gh` reads (a malformed `CVE-…` token stops it before any search); the resolved set (ledger dropped, closed `announced` cut to 90 days, a CVE matched only in its *CVE tool link* field, capped lists flagged) and the echo |
   | Bulk 1b | `preflight-query`, `preflight` | the batched state read; the no-op rule table, never skipping an explicitly named tracker |
   | Bulk 3–4 | `bucket`, `parse-bulk-reply` | CVE-affecting vs non-CVE-affecting (the `allocated → review-ready` push rides the latter), walk order; the merged confirmation syntax |
   | Step 3 | `parse-reply` | the single-tracker form (`shared.numbered`) |
   | Guardrails | `check` | reporter CVSS outside the observed state, other ASF projects, a bare CVE ID on markdown (or the CVE-tool URL in an email), bare `#NNN` |
   | Step 0 / drafts | `security-cc`, `draft-backend` | the CC through the configuration layers (`shared.recipients`); Gmail or Maildir, then the Gmail backend (`shared.drafting.choose`) |
   | GHSA | `ghsa-route` | the access tier and how each advisory change is delivered |
   | Step 5b | `push-decision` | skip, the seven gates (three checked on the JSON, four taken as the model's verdicts), session probe, push, state verification |
   | Step 6 | `render-recap` | the recap with every link |
   
   Nine eval suites become pytest cases named after each former case (`tests/test_issue_sync.py`, `tests/test_issue_sync_rules.py`): `step-bulk-selectors`, `step-bulk-orchestration`, `step-3-confirm`, `step-6-recap`, `step-guardrails`, `step-security-cc`, `step-draft-backend`, `step-ghsa-access-tier`, `step-5b-push-decision`. A new `step-5b-judged-gates` model suite covers the four gates the model still judges, and passes 2/2. The skill's model cases go from 86 to 38.
   
   `SKILL.md` grows slightly (7,006 → 7,282 tokens): this part adds the router lines but moves no large section out yet; `gather.md` and `signals-to-actions.md`, the bulk of the skill, are part 2.
   
   ## Behaviour changes
   
   - A malformed CVE token stops the whole selector before any search.
   - A CVE search keeps only trackers whose *CVE tool link* names the CVE, read through github-body-field rather than a body regex.
   - A bulk reply naming an unknown tracker or item, two dispositions for one tracker, or `force-sync` of a tracker that was not skipped applies nothing.
   - An explicit null or blank fallback address in the project layer disables the organization's, and the draft is blocked.
   - An admin-only advisory change after a `403` is never retried, and is always a draft relay, never a tracker comment.
   - A judged push gate with no verdict is asked for before the push, never assumed to pass.
   - The cve-allocate title cascade also strips a bracketed `[GHSA-…]` ID.
   - A CVE ID that is not `CVE-YYYY-NNNNN` never reaches a printed command: `push-decision` and the deduplicate apply plan (from #1707) refuse it, and quote it.
   
   Spec `security-issue-lifecycle` describes the new family.
   
   Part of #1672
   
   ## Generative AI disclosure
   
   Drafted with Claude Code (Claude Opus 5) and reviewed by the author.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@magpie.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] perf(security-issue-sync): decide bulk mode, guardrails, drafting, GHSA routing and the push flow as code [magpie]

Posted by "github-advanced-security[bot] (via GitHub)" <gi...@apache.org>.
github-advanced-security[bot] commented on code in PR #1710:
URL: https://github.com/apache/magpie/pull/1710#discussion_r4315294084


##########
tools/security-management/src/security_management/issue_sync/render.py:
##########
@@ -0,0 +1,154 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""The Guardrails check over everything the proposal would write, and the Step 6 recap.
+
+`check` reads each tracker- or reporter-bound passage the proposal carries
+(`surfaces`: `{kind, text}` with `kind` one of `body_patch`,
+`status_comment`, `rollup`, `issue_body`, `email`; `observed` is the one
+place a reporter score may appear) and reports, one per passage and
+guardrail, in passage order, content guardrails before formatting ones:
+
+- *Never propagate a reporter-supplied CVSS score* — a CVSS score, vector
+  or a score with a qualitative label outside `observed`;
+- *Never name or describe other ASF projects' vulnerabilities* — another
+  ASF project's name, or a cross-project phrase;
+- *Linking CVEs* — a bare CVE ID on a markdown surface; in a reporter
+  email the bare ID is right and the CVE-tool URL is the violation;
+- *Linking tracker issues* — a bare `#NNN`.
+
+The model still reads the surfaces for what a pattern cannot see; this is
+the floor, not the whole check.
+
+`recap` links the tracker, the rollup comment, the embedded CVE JSON (or
+says no CVE is allocated), the milestone, the draft and its thread, and
+repeats the next step.
+"""
+
+from __future__ import annotations
+
+import re
+from collections.abc import Mapping
+from typing import Any
+
+from security_management.cve_allocate.gate import record_url
+from security_management.shared import drafting, refs
+from security_management.shared.rollup import code, one_line
+
+CVSS = "Never propagate a reporter-supplied CVSS score"
+OTHER_ASF = "Never name or describe other ASF projects' vulnerabilities"
+LINK_CVE = "Linking CVEs"
+LINK_TRACKER = "Linking tracker issues"
+MARKDOWN = ("body_patch", "status_comment", "rollup", "issue_body")
+_CVSS = re.compile(
+    r"\bCVSS\b|\bAV:[NALP](?:/[A-Za-z]{1,3}:[A-Za-z])+|\b\d{1,2}\.\d[ \t]?\(?(?:low|medium|high|critical)\b",
+    re.IGNORECASE,
+)
+_CVE = re.compile(r"CVE-\d{4}-\d{4,7}")
+_CROSS = re.compile(
+    r"also reported against|cross-project|other apache projects|sister project|the same finder also",
+    re.IGNORECASE,
+)
+_BREAK = re.compile(r"(?<=[.!?])\s+")
+
+
+def _sentences(text: str) -> list[str]:
+    """`text` as sentences: a break is `.`, `!` or `?` then whitespace, so a URL stays whole."""
+    joined = re.sub(r"\s*\n\s*", " ", text.strip())
+    return [s.strip() for s in _BREAK.split(joined) if s.strip()]
+
+
+def _bare_cves(sentence: str) -> list[str]:
+    linked = {m.group(1) for m in re.finditer(r"\[`?(CVE-\d{4}-\d{4,7})`?\]\(", sentence)}
+    in_urls = {c for url in re.findall(r"https?://\S+", sentence) for c in _CVE.findall(url)}
+    return [c for c in _CVE.findall(sentence) if c not in linked and c not in in_urls]
+
+
+def check(data: Mapping[str, Any]) -> dict[str, Any]:
+    own = {str(n).lower() for n in data.get("own_names") or []}
+    names = [n for n in drafting.ASF_PROJECTS if n.lower() not in own]
+    other = re.compile(r"\b(?:Apache\s+)?(?:" + "|".join(names) + r")\b")
+    violations: list[dict[str, str]] = []
+    for surface in data.get("surfaces") or []:
+        kind = str(surface.get("kind") or "")
+        if kind == "observed":
+            continue
+        for sentence in _sentences(str(surface.get("text") or "")):
+            found: list[str] = []
+            if _CVSS.search(sentence):
+                found.append(CVSS)
+            if other.search(sentence) or _CROSS.search(sentence):
+                found.append(OTHER_ASF)
+            if kind == "email":
+                if "cveprocess.apache.org" in sentence:

Review Comment:
   ## CodeQL / Incomplete URL substring sanitization
   
   The string [cveprocess.apache.org](1) may be at an arbitrary position in the sanitized URL.
   
   [Show more details](https://github.com/apache/magpie/security/code-scanning/150)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@magpie.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] perf(security-issue-sync): decide bulk mode, guardrails, drafting, GHSA routing and the push flow as code [magpie]

Posted by "potiuk (via GitHub)" <gi...@apache.org>.
potiuk merged PR #1710:
URL: https://github.com/apache/magpie/pull/1710


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@magpie.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org