FR-135 · 第三期歸檔 · 2026-10-13

通報、提醒、支援期到期通知的設計草案,交給週期任務 FR

CRA 第三期不做的三件事(通報案件頁籤、提醒排程與寄信紀錄、相關決策),其設計草案與 ENISA 欄位對照集中在此

CRA 第三期只做三份法定文件匯出(X1)與支援期剩餘天數徽章(S1)。通報案件、通報提醒、支援期提醒都不在 CRA 第三期,併入平台級 FR「週期任務與條件通知」(FR-137)。本檔把已寫好的設計草案、決策者已裁的相關決策、探脈發現的落地問題、ENISA SRP 三階段欄位對照集中保存,給 FR-137 討論時當輸入。這裡的內容不是定案:決策者方向一節是 2026-10-13 的裁示,其餘草案要在 FR-137 重新對照該 FR 的架構再定。

CRA 第三期不做 給 FR-137 當輸入 弱點處理狀態另轉 FR-134

狀態:歸檔(新 FR 輸入) | 日期:2026-10-13 | 去向:FR-137「週期任務與條件通知」(母卡 CM-2714、探脈 CM-2715)

§1

決策者方向(2026-10-13)

新 FR 的方向(只定方向,不展開設計)

  • 週期設定放任務,不放 AO(一個 AO 底下會有多筆任務)。資源庫 module_frames.frequency 閒置欄日後當建專案時的預設帶入。
  • 自動執行只限掃描類任務。
  • 通知預設=任務執行人員;掃描類多一個特例:「風險門檻+額外通知對象」(例如 CRA 專案設 high 以上通知通報聯絡人)。
  • 通報在系統裡只剩一件事:掃描掃到 high 以上時通知通報人員,且要留紀錄(哪次掃描、什麼等級、何時通知誰);客戶之後怎麼到 ENISA 平台通報,系統不管。
  • 通報提醒、支援期提醒都併入這個 FR。
  • CRA.ART.14.RP 三個 AO 的證據=客戶自行上傳 ENISA 平台送件截圖,不加證據來源第七型 reporting。

本檔其餘各節是為 CRA 專案內「通報案件頁籤」與「提醒排程」寫的草案。方向改成平台級週期任務後,資料模型、收件人、排程精度都要在 FR-137 重新判斷;ENISA 欄位對照與時區語系的現況盤點仍可直接用。

弱點「處理狀態/揭露狀態」不在本檔:那是掃描結果本身要不要多欄的問題,屬 FR-134,已列在 docs/features/FR-134-2610-source-code-sbom-scan/handoff/FR-134-STATE.md §3 第 14 列。草案內提到「W1」「衝突處 ①」處,指的就是那一項。


§2

通報案件頁籤草案

做什麼

CRA 專案 SSP 多一個「通報案件」頁籤:列出本專案的通報案件,每筆顯示軌道、狀態、三個到期倒數;點進去可填案件內容、回填三階段送件時間與回執編號。一案一筆,三階段在同一筆補填,最終報告送出後唯讀——與 ENISA 平台同形狀。

資料模型草案:oscal.ssp_incident_reports

照 oscal.ssp_risks 的骨架(tenant_id/org_unit_id 取自專案、RLS ENABLE+FORCE、一條 FOR ALL policy、GRANT cm_app 含 sequence、FK ssp_id ON DELETE CASCADE)。業務欄如下:

欄 型別 說明
track varchar exploited-vulnerability/severe-incident,程式列舉(決定期限算法)
title text ENISA 必填(255 字)
summary text ENISA 早期警示必填(4000 字);雛形「摘要」
severity varchar 嚴重度;值域建議進 system_menus(N1 開工時定 group 名)
member_states jsonb 受影響會員國(多選,ISO 國碼陣列);ENISA 必填
manufacturer_name text 預設帶 Party「製造商」名,可改
product_name/product_version text 預設帶受評標的 ext:cra-product-name/ext:cra-product-identifier,可改;ENISA 必填
aware_at timestamptz 知悉時間,使用者填,UTC 存(D1)
fix_available_at timestamptz 修補可用時間,只漏洞軌(D1)
due_early_warning_at/due_notification_at timestamptz 建案時算好存(知悉+24h/+72h)
due_final_at timestamptz 依軌道重算,可空(D1)
submitted_early_warning_at/submitted_notification_at/submitted_final_at timestamptz 三階段送件時間(=時間軸)
receipt_early_warning/receipt_notification/receipt_final varchar 三段回執編號(ENISA 案件編號形如 SRP-GR-I-2026-00001289,一案一號,三段通常相同)
status varchar 草稿/已早期警示/已通知/已結案,程式列舉(狀態機)
vulnerability_disposition_id bigint 可空 關聯弱點(W1 上線後才有值),見衝突處 ①
stage_content jsonb 三階段的長文欄(見「ENISA 欄位對照」),一階段一個 key
remarks text 備註
regulation varchar 固定 CRA,唯一預留

stage_content 用 JSONB 而非逐欄展開:ENISA 三階段的文字欄有十餘個且兩軌不同,逐欄展開會讓表寬翻倍、且平台改版就要改 schema;這些欄只給 X1 套範本與畫面顯示,不做查詢條件。

端點(照 R1-a 四端點)

GET/POST /ssp/<ssp_uid>/incident-reports、PUT/DELETE /ssp/<ssp_uid>/incident-report/<uid>。讀 require_participant+oscal.ssp.read、寫 require_manager+oscal.ssp.update(同 R1-a);uid 以 (ssp_id, uid) 一起查,擋拿自己 SSP 權限動別人的案件。最終報告已送出(submitted_final_at 有值)的案件,PUT 回 409。回應補 created_user_name/updated_user_name。

畫面改動

  • SspTabPanel.vue 加 TabPanel,條件 formSettings?.sections?.incident_report,深連結 key incident_report。
  • 清單欄:案件編號、標題、軌道、狀態、三個到期(倒數徽章)、關聯弱點。倒數顏色照雛形提案:已送出綠、剩超過 24h 灰、24h 內橘、2h 內或逾期紅、未開始算虛線框。
  • 案件頁:照雛形「時間軸/回填送件紀錄/案件資料/摘要」四區。
  • 雛形要拿掉的:「適用法規下拉/規則展開」(雛形本身已無此下拉,phase3-incidents.html grep「法規」0 處;確認不加回)、「通報對象與聯絡資訊」區塊中「協調 CSIRT:待設定」改顯示「受影響會員國」欄的值;「寄信紀錄」區塊等 N2 上線才有資料,N1 先隱藏。

證據來源第七型 reporting

ao_evidence_source.py 加 T_REPORTING = "reporting" 與 _reporting:查本 SSP 的案件,status 有案件即 filled,count=案件數,summary=最近一筆的更新時間,link={tab:'ssp', section:'incident_report'}。沒有案件時顯示 empty——「沒有發生需通報的事件」也是正常狀態,FE 文案要寫「尚無通報案件」而非「缺漏」。哪幾個 AO 掛這一型由套件 seed 決定(II.8 協調揭露、Art.14 相關控制項),N1 開工時對 seed 006 現有掛點補。


§3

提醒排程與寄信紀錄草案

做什麼

每天跑一次:找出今天該寄的通報期限提醒與支援期提醒,寄給對的人,並記一筆紀錄;同一件事同一階段只寄一次。

排程

core/scheduler.py init_scheduler 加一支每日 cron(照 :236-267 的 system_context+session_scope 寫法,跨租戶掃描)。例外:D2 的「到期前 4 小時」與「逾期」精度是小時級,每日一次跑不到——見衝突處 ③ 的處理建議(改每小時 tick、寄送仍靠紀錄表去重)。

寄信紀錄表:compliance.notification_logs

欄 說明
tenant_id/org_unit_id
object_type incident_report/information_system_version
object_uid 物件 uid
stage 通報:created、ew-before-4h、ew-overdue、n72-before-4h、n72-overdue、final-before-4h、final-overdue;支援期:d90、d30、d7
recipient 收件信箱(一人一列)
sent_at 寄出時間

UNIQUE (object_type, object_uid, stage, recipient) 即去重鍵;排程先 INSERT 搶到列才寄,搶不到跳過。

收件人

  • 通報:該案件所屬專案的參與者 manager(D2)。
  • 支援期:反查「哪些 CRA 專案的 SSP 盤點掛了這個資訊系統」,寄給那些專案的 manager;沒掛任何專案的版本只顯示徽章不寄(D5)。反查要新寫:oscal.ssp_inventory_items.props 內 ref-id=資訊系統 uid → system_implementation_id → SSP → compliance.projects.living_ssp_id,再濾框架為 CRA。

信件文字

排程沒有 request,flask_babel.gettext 不能用(project_service.py:10 那條只能在 request 內)。定案寫「改讀租戶預設語系」,但系統目前沒有租戶語系設定,見衝突處 ③。


§4

相關決策(決策者 2026-10-13 拍板時的原文)

D3(弱點兩組狀態)隨弱點處理狀態轉 FR-134;D4(只出 docx)留在 CRA 第三期。以下四項是通報與提醒相關的原文。

✅ D1 — 通報期限怎麼算

定案:知悉時間由使用者填(UTC 存、顯示換時區);到期一(24h)與到期二(72h)建案時算好存欄位;到期三依軌道重算:漏洞軌=回填「修補可用時間」後加 14 天,空著顯示「待修補」;事件軌=回填 72 小時通知送件時間後加 1 個月。

理由:CRA Art.14 兩軌第三段起算點不同(docs/reference/CRA/cra-reference.md Step 7 表);ENISA SRP 的做法也一致——漏洞最終報告平台不計時(要等修補)、事件最終報告從通知送出起算。

被排除:「三個到期都在建案時算死」——事件軌第三段的起算點不是知悉,算死會在使用者還沒送 72 小時通知時就顯示錯的倒數。

✅ D2 — 提醒寄幾封、寄給誰

定案:建案當下一封、每階段到期前 4 小時一封、逾期一封;收件人=專案參與者 manager;「提前幾小時」進 system_menus(group incident_reminder_offset),不寫死。

理由:24 小時期限太短,按天提醒無意義;4 小時是「還來得及到平台送件」的緩衝。manager 是專案層唯一確定有權處理的角色。

被排除:按天多次提醒(24h 期限內沒有意義);寄給所有參與者(auditor/viewer 無權回填,只是噪音)。

✅ D5 — 支援期提醒

定案:到期前 90/30/7 天各一封;收件人=有掛該資訊系統的 CRA 專案 manager(SSP 盤點 ref-type 資訊系統 → 專案);沒掛任何專案的版本只顯示徽章不寄信。

理由:資訊系統是租戶層主檔,沒有「負責人」欄;能確定有人負責的只有「把它納入 CRA 評估的專案」。

被排除:寄給租戶管理員(不一定懂產品);本期做「通知設定」畫面(雛形提案,延後)。

✅ D6 — 弱點反向連結通報案件

定案:弱點列顯示「已建通報案件」連結(vulnerability_dispositions.incident_report_id)。

理由:顧問在掃描結果頁看到高風險弱點時,要一眼知道「這個已經通報了沒」。

被排除:只做通報 → 弱點單向(掃描結果頁看不到通報狀態)。


§5

落地問題(探脈發現)

⚠️ ② D5 收件人要新寫「資訊系統反查專案」,不是現成能力

  • 盤點掛資訊系統存在 oscal.ssp_inventory_items.props JSONB(ref-id=資訊系統 uid),要經 system_implementation_id → SSP → compliance.projects.living_ssp_id 才到專案,再判框架是否 CRA;CM-2707 探脈已記「資訊系統反查專案沒有現成查詢」。
  • 這不改定案,但讓 N2 的規模比卡上 S~M 偏向 M;也是 CM-2707 改裁「不做反查專案」與 D5 之間的張力——CM-2707 不做的是「通報頁反查」,D5 需要的是「排程反查」,兩者不同,本稿照 D5 寫。

建議:反查寫成 infra 層一支查詢(JSONB 條件),放 N2;不擴大成通用 API。

⚠️ ③ 時區、語系與提醒精度:系統沒有「租戶時區」「租戶預設語系」,每日 tick 也追不到 4 小時

  • 時區:D1 寫「租戶時區顯示」,但全庫沒有租戶時區欄;後端營運時區寫死 Asia/Taipei(common/util/common_util.py:36、config/config.py:178),FE 顯示時區寫死(src/utils/dateTime.js:9,註解寫明「個人 profile 時區設定接這裡」)。
  • 語系:N2 寫「改讀租戶預設語系」,但沒有租戶語系設定,只有環境變數 DEFAULT_LOCALE(.env.sample:124,jedi-iam 透過 common/iam_ports.py:31-50 讀)與 BABEL_DEFAULT_LOCALE(config/config.py:176)。
  • 精度:D2「到期前 4 小時」「逾期」是小時級;卡上 N2 寫「每日 tick」,每日一次會晚最多 24 小時,對 24h 期限等於沒提醒。

建議:時區照現況走既有顯示時區(getDisplayTimeZone()/BUSINESS_TZ),不在本期加租戶時區;語系讀 DEFAULT_LOCALE 環境變數,信件文字放與 gettext 無關的字典檔;通報提醒的 tick 改每小時(支援期提醒仍可每日,同一支 tick 內判斷)。三點都不改 D1/D2 的內容,只改落地方式,請首腦確認。


§6

ENISA SRP 三階段欄位對照

來源:ENISA《CRA SRP — AR User Manual》v1.1 §4.7(2026-09 版,55 頁;本稿只抄欄位,未轉貼全文)。手冊截圖只示範「嚴重事件」軌,被利用漏洞軌的欄位未截圖;手冊寫明「Fields differ depending on whether you select Actively Exploited Vulnerability or Severe Incident」,並說「部分欄位若資訊已有即為必填」。

欄位(手冊原文) 中文 早期警示 72 小時通知 最終報告 我們的落點
Notification type 軌道 必填 帶入 帶入 track
Title(255) 標題 必填 帶入 帶入 title
Summary(4000) 摘要 必填 帶入 帶入 summary
Manufacturer name 製造商 必填(下拉,可新增) 帶入 帶入 manufacturer_name ← Party
Member States where product available 受影響會員國(決定協調 CSIRT) 必填(多選) 帶入 帶入 member_states
Product Name/Product version(各 255) 產品名/版本 必填(可多個產品) 帶入 帶入 product_name/product_version
Product type 預設/重要/關鍵產品 選填 — — ← ext:cra-product-class
End of support indicator 是否已過支援期 選填 — — ← 版本 support_end_date
Component name 元件名 選填 — — stage_content(漏洞軌可帶 W1 套件名)
Mitigating measure expected shortly 近期會有緩解措施 選填 — — stage_content
Incident is suspected by unlawful or malicious acts(255) 是否疑為惡意行為 必填(事件軌) — — stage_content
User action able to reduce impact(4000) 使用者可採取的降低影響措施 選填 — — stage_content
Considered sensitivity of information(255) 資訊敏感度 選填 選填 — stage_content
General information about the nature of the incident(4000) 事件性質概述 選填 必填 — stage_content
Initial assessment of the incident(4000) 初步評估 選填 必填 — stage_content
Date and time when the incident was detected 偵測時間 選填 必填 — aware_at 預設帶入,可改
Date and time when the incident occurred 發生時間 選填 必填 — stage_content
Corrective or mitigating measures taken(可多筆,4000) 已採取的矯正措施 選填 選填 必填 stage_content
Corrective or mitigating measures that users can take(可多筆) 使用者可採取的措施 選填 選填 必填 stage_content
Applied and ongoing mitigation measures(可多筆) 已實施與進行中的緩解 選填 選填 必填 stage_content
Attack vector(255) 攻擊向量 — 選填 — stage_content
Detailed description of the Severity of the incident(4000) 嚴重度詳述 選填 選填 必填 stage_content;severity 是我們的分級欄
Detailed description of the Impact of the incident(4000) 影響詳述 選填 選填 必填 stage_content
Type of threat or root cause(255) 威脅類型或根因 選填 選填 必填 stage_content
Particular Exceptional Circumstances(PEC)+理由三選+補充(800) 特殊例外情況(延後轉發) — 選填(僅漏洞軌) — stage_content
Additional Notes 補充說明 任何階段可更新 同左 同左 remarks

平台行為(給 N1 狀態機參考):草稿只存在送件人帳號、不送 CSIRT;早期警示與 72 小時通知送出後仍可更新;最終報告送出後唯讀;狀態依序為 EW Submitted → 72h Submitted(或 72h Submitted under PEC)→ FR Submitted,CSIRT 審後另有 Valid/Invalid/Closed。我們的 status 四值(草稿/已早期警示/已通知/已結案)對應前三段,CSIRT 審查結果不追。

被利用漏洞軌的欄位:未取得,X1 開工前補

手冊只截嚴重事件軌的畫面。漏洞軌至少有 PEC(上表)、元件名;其他差異(例如 CVE 編號、修補可用時間)要在 X1 開工前以 SRP 測試帳號或 ENISA 後續文件補齊,補到後更新本表與 stage_content 的 key 清單。


§7

日後拔成獨立模組的預留

本期不做多法規、多對象,但寫法要讓日後拔得出來:

  • 通報的四層檔案自成一組(ssp_incident_report_*),不把通報邏輯寫進 SSP 既有 service 或規劃頁 service。
  • ssp_id 本期必填。
  • 日後獨立=搬成套件(照 jedi-asset 切法、套件自帶 migration,見 CM-2707 探脈結論)、ssp_id 改可空、regulation 欄變成規則軸、頁籤改側選單入口。

沿革見 handoff/FR-135-LOG.md 與 git log。