From 918fba4572103a65e539d95f7824cf885d938f7a Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Wed, 27 May 2026 10:46:59 +0200 Subject: [PATCH 1/5] feat: Satisfy some security gd_reqs --- docs/internals/requirements/requirements.rst | 85 ++++++++++++-- src/extensions/score_metamodel/metamodel.yaml | 101 +++++++++++++++++ .../rst/options/test_options_options.rst | 104 ++++++++++++++++++ 3 files changed, 282 insertions(+), 8 deletions(-) diff --git a/docs/internals/requirements/requirements.rst b/docs/internals/requirements/requirements.rst index 382cb8f03..67f620f98 100644 --- a/docs/internals/requirements/requirements.rst +++ b/docs/internals/requirements/requirements.rst @@ -1156,15 +1156,84 @@ Testing Docs-As-Code shall enforce that every Safety Analysis has a short description of the failure effect (e.g. failure lead to an unintended actuation of the analysed element) ----------------------------------------------------------------- -Safety Analysis (DFA + FMEA) Process to Tool Requirement Mapping ----------------------------------------------------------------- -.. needtable:: - :style: table - :types: gd_req - :columns: id;satisfies_back as "tool_req" - :filter: "gd_req__saf" in id +πŸ”’ Security Analysis +##################### + + +.. tool_req:: Security Analysis Need Types + :id: tool_req__docs_sec_types + :implemented: YES + :tags: Security Analysis + :version: 1 + :satisfies: + gd_req__sec_attr_uid, + gd_req__sec_attr_title, + :parent_covered: YES + + Docs-As-Code shall support the following need types: + + * Feature Security Analysis Threat (STRIDE) -> ``feat_sec_threat`` + * Component Security Analysis Threat (STRIDE) -> ``comp_sec_threat`` + * Platform Security Analysis Threat (STRIDE) -> ``plat_sec_threat`` + * Feature Security Analysis (Threat Scenario) -> ``feat_sec_ana`` + * Component Security Analysis (Threat Scenario) -> ``comp_sec_ana`` + * Platform Security Analysis (Threat Scenario) -> ``plat_sec_ana`` + + All need types have a mandatory ``title`` and unique ``id``. + + +.. tool_req:: Security Analysis: STRIDE Threat ID Attribute + :id: tool_req__docs_sec_attr_stride_threat_id + :implemented: YES + :tags: Security Analysis + :version: 1 + :satisfies: gd_req__sec_attr_stride_threat_id + :parent_covered: YES + + Docs-As-Code shall enforce that STRIDE threat needs + (``feat_sec_threat``, ``comp_sec_threat``, ``plat_sec_threat``) + have a mandatory ``threat_id`` attribute. + + +.. tool_req:: Security Analysis Threat Scenario Mandatory Attributes + :id: tool_req__docs_sec_attrs_mandatory + :implemented: YES + :tags: Security Analysis + :version: 1 + :satisfies: + gd_req__sec_attr_threat_scenario_id, + gd_req__sec_attr_status, + gd_req__sec_attr_sufficient, + gd_req__sec_attr_teffect, + :parent_covered: YES + + Docs-As-Code shall enforce that threat scenario needs + (``feat_sec_ana``, ``comp_sec_ana``, ``plat_sec_ana``) + have the following mandatory attributes: + + * ``threat_scenario_id`` + * ``status``: ``valid`` or ``invalid`` + * ``sufficient``: ``yes`` or ``no`` + * ``teffect``: short description of the threat impact + + +.. tool_req:: Security Analysis Optional Attributes + :id: tool_req__docs_sec_attrs_optional + :implemented: YES + :tags: Security Analysis + :version: 1 + :satisfies: + gd_req__sec_attr_mitigation_issue, + gd_req__sec_attr_aou, + :parent_covered: YES + + Docs-As-Code shall allow threat scenario needs + (``feat_sec_ana``, ``comp_sec_ana``, ``plat_sec_ana``) + to have the following optional attributes and links: + + * ``mitigation_issue``: link to a GitHub issue + * ``mitigated_by``: link to ``aou_req`` πŸ—ΊοΈ Full Mapping diff --git a/src/extensions/score_metamodel/metamodel.yaml b/src/extensions/score_metamodel/metamodel.yaml index 7d82bde3b..fffc91cfd 100644 --- a/src/extensions/score_metamodel/metamodel.yaml +++ b/src/extensions/score_metamodel/metamodel.yaml @@ -854,6 +854,107 @@ needs_types: - safety_analysis parts: 3 + # Security Analysis + # req-Id: tool_req__docs_sec_types + feat_sec_threat: + title: Feature Security Analysis Threat (STRIDE) + mandatory_options: + # req-Id: tool_req__docs_sec_attr_stride_threat_id + threat_id: ^.*$ + status: ^(valid|invalid)$ + content: ^[\s\S]+$ + tags: + - stride_threat + - security_analysis + parts: 3 + + # req-Id: tool_req__docs_sec_types + comp_sec_threat: + title: Component Security Analysis Threat (STRIDE) + mandatory_options: + # req-Id: tool_req__docs_sec_attr_stride_threat_id + threat_id: ^.*$ + status: ^(valid|invalid)$ + content: ^[\s\S]+$ + tags: + - stride_threat + - security_analysis + parts: 3 + + # req-Id: tool_req__docs_sec_types + plat_sec_threat: + title: Platform Security Analysis Threat (STRIDE) + mandatory_options: + # req-Id: tool_req__docs_sec_attr_stride_threat_id + threat_id: ^.*$ + status: ^(valid|invalid)$ + content: ^[\s\S]+$ + tags: + - stride_threat + - security_analysis + parts: 3 + + # req-Id: tool_req__docs_sec_types + feat_sec_ana: + title: Feature Security Analysis (Threat Scenario) + mandatory_options: + # req-Id: tool_req__docs_sec_attrs_mandatory + threat_scenario_id: ^.*$ + # req-Id: tool_req__docs_sec_attrs_mandatory + status: ^(valid|invalid)$ + # req-Id: tool_req__docs_sec_attrs_mandatory + sufficient: ^(yes|no)$ + # req-Id: tool_req__docs_sec_attrs_mandatory + teffect: ^.+$ + # req-Id: tool_req__docs_sec_argument + content: ^[\s\S]+$ + optional_options: + # req-Id: tool_req__docs_sec_attrs_optional + mitigation_issue: ^https://github.com/.*$ + optional_links: + # req-Id: tool_req__docs_sec_attrs_optional + mitigated_by: feat_req, aou_req + tags: + - threat_scenario + - security_analysis + parts: 3 + + # req-Id: tool_req__docs_sec_types + comp_sec_ana: + title: Component Security Analysis (Threat Scenario) + mandatory_options: + threat_scenario_id: ^.*$ + status: ^(valid|invalid)$ + sufficient: ^(yes|no)$ + teffect: ^.+$ + content: ^[\s\S]+$ + optional_options: + mitigation_issue: ^https://github.com/.*$ + optional_links: + mitigated_by: comp_req, aou_req + tags: + - threat_scenario + - security_analysis + parts: 3 + + # req-Id: tool_req__docs_sec_types + plat_sec_ana: + title: Platform Security Analysis (Threat Scenario) + mandatory_options: + threat_scenario_id: ^.*$ + status: ^(valid|invalid)$ + sufficient: ^(yes|no)$ + teffect: ^.+$ + content: ^[\s\S]+$ + optional_options: + mitigation_issue: ^https://github.com/.*$ + optional_links: + mitigated_by: feat_req, aou_req + tags: + - threat_scenario + - security_analysis + parts: 3 + testcase: title: Testcase Needs parsed from test.xml files optional_options: diff --git a/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst b/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst index 014e1e25d..36e5aa58f 100644 --- a/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst +++ b/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst @@ -535,3 +535,107 @@ Expect no errors related to "violates" field. We need to be generic for expect-n .. feat_req:: milestone must be a version :id: feat_req__random_id4 :valid_until: 2035-03 + + +.. Security Analysis: feat_sec_threat + +#EXPECT: feat_sec_threat__test__bad_1: is missing required attribute: `threat_id`. + +.. feat_sec_threat:: Missing threat_id + :id: feat_sec_threat__test__bad_1 + :status: valid + + Some content. + + +#EXPECT: feat_sec_threat__test__bad_2.status (done): does not follow pattern `^(valid|invalid)$`. + +.. feat_sec_threat:: Invalid status + :id: feat_sec_threat__test__bad_2 + :threat_id: S.01 + :status: done + + Some content. + + +#EXPECT-NOT: feat_sec_threat__test__ok_3 + +.. feat_sec_threat:: Valid threat + :id: feat_sec_threat__test__ok_3 + :threat_id: S.01 + :status: valid + + Some content. + + +.. Security Analysis: feat_sec_ana + +#EXPECT: feat_sec_ana__test__bad_4: is missing required attribute: `threat_scenario_id`. + +.. feat_sec_ana:: Missing threat_scenario_id + :id: feat_sec_ana__test__bad_4 + :status: invalid + :sufficient: no + :teffect: Unauthorized access to stored data. + + Argument why mitigation is insufficient. + + +#EXPECT: feat_sec_ana__test__bad_5.sufficient (maybe): does not follow pattern `^(yes|no)$`. + +.. feat_sec_ana:: Invalid sufficient value + :id: feat_sec_ana__test__bad_5 + :threat_scenario_id: TS.01 + :status: valid + :sufficient: maybe + :teffect: Unauthorized access to stored data. + + Argument why mitigation is insufficient. + + +#EXPECT: feat_sec_ana__test__bad_6.status (done): does not follow pattern `^(valid|invalid)$`. + +.. feat_sec_ana:: Invalid status value + :id: feat_sec_ana__test__bad_6 + :threat_scenario_id: TS.01 + :status: done + :sufficient: no + :teffect: Unauthorized access to stored data. + + Argument why mitigation is insufficient. + + +#EXPECT: feat_sec_ana__test__bad_7: is missing required attribute: `teffect`. + +.. feat_sec_ana:: Missing teffect + :id: feat_sec_ana__test__bad_7 + :threat_scenario_id: TS.01 + :status: invalid + :sufficient: no + + Argument why mitigation is insufficient. + + +#EXPECT-NOT: feat_sec_ana__test__ok_8 + +.. feat_sec_ana:: Valid threat scenario + :id: feat_sec_ana__test__ok_8 + :threat_scenario_id: TS.01 + :status: valid + :sufficient: yes + :teffect: Unauthorized access to stored data. + + Mitigation is sufficient because access controls are in place. + + +#EXPECT-NOT: feat_sec_ana__test__ok_9 + +.. feat_sec_ana:: Valid threat scenario with optional mitigation_issue + :id: feat_sec_ana__test__ok_9 + :threat_scenario_id: TS.02 + :status: invalid + :sufficient: no + :teffect: Data integrity violation via tampering. + :mitigation_issue: https://github.com/eclipse-score/score/issues/1 + + Mitigation not yet implemented. From 18138ecc4c21f5aeb97c473256a09d7f0662bb1c Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Wed, 27 May 2026 13:28:26 +0200 Subject: [PATCH 2/5] feat: Add tool_req__docs_sec_argument --- docs/internals/requirements/requirements.rst | 18 ++++++++++++++++-- .../tests/rst/options/test_options_options.rst | 10 ++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/internals/requirements/requirements.rst b/docs/internals/requirements/requirements.rst index 67f620f98..f25f77610 100644 --- a/docs/internals/requirements/requirements.rst +++ b/docs/internals/requirements/requirements.rst @@ -1208,7 +1208,7 @@ Testing gd_req__sec_attr_teffect, :parent_covered: YES - Docs-As-Code shall enforce that threat scenario needs + Enforce that threat scenario needs (``feat_sec_ana``, ``comp_sec_ana``, ``plat_sec_ana``) have the following mandatory attributes: @@ -1218,6 +1218,20 @@ Testing * ``teffect``: short description of the threat impact +.. tool_req:: Security Analysis Argument Content + :id: tool_req__docs_sec_argument + :implemented: YES + :tags: Security Analysis + :version: 1 + :satisfies: gd_req__sec_argument + :parent_covered: YES + + Enforce that threat scenario needs + (``feat_sec_ana``, ``comp_sec_ana``, ``plat_sec_ana``) + have a non-empty content body describing the argument + for why the mitigation is sufficient or not. + + .. tool_req:: Security Analysis Optional Attributes :id: tool_req__docs_sec_attrs_optional :implemented: YES @@ -1228,7 +1242,7 @@ Testing gd_req__sec_attr_aou, :parent_covered: YES - Docs-As-Code shall allow threat scenario needs + Allow threat scenario needs (``feat_sec_ana``, ``comp_sec_ana``, ``plat_sec_ana``) to have the following optional attributes and links: diff --git a/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst b/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst index 36e5aa58f..cd6560e54 100644 --- a/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst +++ b/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst @@ -639,3 +639,13 @@ Expect no errors related to "violates" field. We need to be generic for expect-n :mitigation_issue: https://github.com/eclipse-score/score/issues/1 Mitigation not yet implemented. + + +#EXPECT: feat_sec_ana__test__bad_10: is missing required attribute: `content`. + +.. feat_sec_ana:: Missing argument content + :id: feat_sec_ana__test__bad_10 + :threat_scenario_id: TS.03 + :status: invalid + :sufficient: no + :teffect: Unauthorized data access. From fe5a8d5b770ca9a8849dc9decf42df0c4a6201dd Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Thu, 28 May 2026 08:47:45 +0200 Subject: [PATCH 3/5] fix: review feedback --- docs/internals/requirements/requirements.rst | 2 +- src/extensions/score_metamodel/metamodel.yaml | 6 ++--- .../rst/options/test_options_options.rst | 22 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/internals/requirements/requirements.rst b/docs/internals/requirements/requirements.rst index f25f77610..c23add9a4 100644 --- a/docs/internals/requirements/requirements.rst +++ b/docs/internals/requirements/requirements.rst @@ -1215,7 +1215,7 @@ Testing * ``threat_scenario_id`` * ``status``: ``valid`` or ``invalid`` * ``sufficient``: ``yes`` or ``no`` - * ``teffect``: short description of the threat impact + * ``threat_effect``: short description of the threat impact .. tool_req:: Security Analysis Argument Content diff --git a/src/extensions/score_metamodel/metamodel.yaml b/src/extensions/score_metamodel/metamodel.yaml index fffc91cfd..ebae71fca 100644 --- a/src/extensions/score_metamodel/metamodel.yaml +++ b/src/extensions/score_metamodel/metamodel.yaml @@ -905,7 +905,7 @@ needs_types: # req-Id: tool_req__docs_sec_attrs_mandatory sufficient: ^(yes|no)$ # req-Id: tool_req__docs_sec_attrs_mandatory - teffect: ^.+$ + threat_effect: ^.+$ # req-Id: tool_req__docs_sec_argument content: ^[\s\S]+$ optional_options: @@ -926,7 +926,7 @@ needs_types: threat_scenario_id: ^.*$ status: ^(valid|invalid)$ sufficient: ^(yes|no)$ - teffect: ^.+$ + threat_effect: ^.+$ content: ^[\s\S]+$ optional_options: mitigation_issue: ^https://github.com/.*$ @@ -944,7 +944,7 @@ needs_types: threat_scenario_id: ^.*$ status: ^(valid|invalid)$ sufficient: ^(yes|no)$ - teffect: ^.+$ + threat_effect: ^.+$ content: ^[\s\S]+$ optional_options: mitigation_issue: ^https://github.com/.*$ diff --git a/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst b/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst index cd6560e54..7de48e171 100644 --- a/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst +++ b/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst @@ -552,7 +552,7 @@ Expect no errors related to "violates" field. We need to be generic for expect-n .. feat_sec_threat:: Invalid status :id: feat_sec_threat__test__bad_2 - :threat_id: S.01 + :threat_id: MT_01_03 :status: done Some content. @@ -562,10 +562,10 @@ Expect no errors related to "violates" field. We need to be generic for expect-n .. feat_sec_threat:: Valid threat :id: feat_sec_threat__test__ok_3 - :threat_id: S.01 + :threat_id: MT_01_03 :status: valid - Some content. + message timing is manipulated (Tampering) .. Security Analysis: feat_sec_ana @@ -576,7 +576,7 @@ Expect no errors related to "violates" field. We need to be generic for expect-n :id: feat_sec_ana__test__bad_4 :status: invalid :sufficient: no - :teffect: Unauthorized access to stored data. + :threat_effect: Unauthorized access to stored data. Argument why mitigation is insufficient. @@ -588,7 +588,7 @@ Expect no errors related to "violates" field. We need to be generic for expect-n :threat_scenario_id: TS.01 :status: valid :sufficient: maybe - :teffect: Unauthorized access to stored data. + :threat_effect: Unauthorized access to stored data. Argument why mitigation is insufficient. @@ -600,14 +600,14 @@ Expect no errors related to "violates" field. We need to be generic for expect-n :threat_scenario_id: TS.01 :status: done :sufficient: no - :teffect: Unauthorized access to stored data. + :threat_effect: Unauthorized access to stored data. Argument why mitigation is insufficient. -#EXPECT: feat_sec_ana__test__bad_7: is missing required attribute: `teffect`. +#EXPECT: feat_sec_ana__test__bad_7: is missing required attribute: `threat_effect`. -.. feat_sec_ana:: Missing teffect +.. feat_sec_ana:: Missing threat_effect :id: feat_sec_ana__test__bad_7 :threat_scenario_id: TS.01 :status: invalid @@ -623,7 +623,7 @@ Expect no errors related to "violates" field. We need to be generic for expect-n :threat_scenario_id: TS.01 :status: valid :sufficient: yes - :teffect: Unauthorized access to stored data. + :threat_effect: Unauthorized access to stored data. Mitigation is sufficient because access controls are in place. @@ -635,7 +635,7 @@ Expect no errors related to "violates" field. We need to be generic for expect-n :threat_scenario_id: TS.02 :status: invalid :sufficient: no - :teffect: Data integrity violation via tampering. + :threat_effect: Data integrity violation via tampering. :mitigation_issue: https://github.com/eclipse-score/score/issues/1 Mitigation not yet implemented. @@ -648,4 +648,4 @@ Expect no errors related to "violates" field. We need to be generic for expect-n :threat_scenario_id: TS.03 :status: invalid :sufficient: no - :teffect: Unauthorized data access. + :threat_effect: Unauthorized data access. From 9715b35143849ecfe3fbda1691d01ef1b8e0f4c7 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Thu, 28 May 2026 11:28:25 +0200 Subject: [PATCH 4/5] fix: review feedback --- docs/internals/requirements/requirements.rst | 18 +-------- src/extensions/score_metamodel/metamodel.yaml | 39 ++++++++++++------- .../rst/options/test_options_options.rst | 29 ++++++++++---- .../score_source_code_linker/__init__.py | 9 +++++ 4 files changed, 56 insertions(+), 39 deletions(-) diff --git a/docs/internals/requirements/requirements.rst b/docs/internals/requirements/requirements.rst index c23add9a4..504ede378 100644 --- a/docs/internals/requirements/requirements.rst +++ b/docs/internals/requirements/requirements.rst @@ -136,9 +136,9 @@ This section provides an overview of current process requirements and their clar :parent_covered: NO: Can not cover 'ISO/IEC/IEEE/29148' :version: 1 :implemented: YES - :satisfies: gd_req__req_attr_description, gd_req__req_check_mandatory, + :satisfies: gd_req__req_attr_description, gd_req__req_check_mandatory, gd_req__sec_argument - Docs-as-Code shall enforce that each need of type :need:`tool_req__docs_req_types` has a description (content) + Enforce that each need of type :need:`tool_req__docs_req_types` has a description (content) .. tool_req:: Enforces description wording rules @@ -1218,20 +1218,6 @@ Testing * ``threat_effect``: short description of the threat impact -.. tool_req:: Security Analysis Argument Content - :id: tool_req__docs_sec_argument - :implemented: YES - :tags: Security Analysis - :version: 1 - :satisfies: gd_req__sec_argument - :parent_covered: YES - - Enforce that threat scenario needs - (``feat_sec_ana``, ``comp_sec_ana``, ``plat_sec_ana``) - have a non-empty content body describing the argument - for why the mitigation is sufficient or not. - - .. tool_req:: Security Analysis Optional Attributes :id: tool_req__docs_sec_attrs_optional :implemented: YES diff --git a/src/extensions/score_metamodel/metamodel.yaml b/src/extensions/score_metamodel/metamodel.yaml index ebae71fca..21785ab92 100644 --- a/src/extensions/score_metamodel/metamodel.yaml +++ b/src/extensions/score_metamodel/metamodel.yaml @@ -127,6 +127,7 @@ needs_types: gd_req: title: Process Requirements mandatory_options: + # req-Id: tool_req__docs_common_attr_description content: ^[\s\S]+$ optional_links: # req-Id: tool_req__docs_req_link_satisfies_allowed @@ -289,6 +290,7 @@ needs_types: safety: ^(QM|ASIL_B)$ # req-Id: tool_req__docs_common_attr_status status: ^(valid|invalid)$ + # req-Id: tool_req__docs_common_attr_description content: ^[\s\S]+$ mandatory_links: # req-Id: tool_req__docs_req_link_satisfies_allowed @@ -325,6 +327,7 @@ needs_types: safety: ^(QM|ASIL_B)$ # req-Id: tool_req__docs_common_attr_status status: ^(valid|invalid)$ + # req-Id: tool_req__docs_common_attr_description content: ^[\s\S]+$ mandatory_links: # req-Id: tool_req__docs_req_link_satisfies_allowed @@ -350,6 +353,7 @@ needs_types: tool_req: title: Tool Requirement mandatory_options: + # req-Id: tool_req__docs_common_attr_description content: ^[\s\S]+$ optional_links: # req-Id: tool_req__docs_req_link_satisfies_allowed @@ -385,6 +389,7 @@ needs_types: safety: ^(QM|ASIL_B)$ # req-Id: tool_req__docs_common_attr_status status: ^(valid|invalid)$ + # req-Id: tool_req__docs_common_attr_description content: ^[\s\S]+$ optional_options: codelink: ^.*$ @@ -738,11 +743,12 @@ needs_types: failure_effect: ^.*$ sufficient: ^(yes|no)$ status: ^(valid|invalid)$ + # req-Id: tool_req__docs_common_attr_description content: ^[\s\S]+$ mandatory_links: violates: feat_arc_sta optional_options: - mitigation_issue: ^https://github.com/.*$ + mitigation_issue: ^https://github\.com/[^/]+/[^/]+/issues/\d+$ optional_links: mitigated_by: stkh_req, aou_req parts: 3 @@ -758,13 +764,14 @@ needs_types: sufficient: ^(yes|no)$ status: ^(valid|invalid)$ # req-Id: tool_req__docs_saf_attrs_content + # req-Id: tool_req__docs_common_attr_description content: ^[\s\S]+$ mandatory_links: # req-Id: tool_req__docs_saf_attrs_violates violates: feat_arc_sta optional_options: # req-Id: tool_req__docs_saf_attrs_mitigation_issue - mitigation_issue: ^https://github.com/.*$ + mitigation_issue: ^https://github\.com/[^/]+/[^/]+/issues/\d+$ optional_links: # req-Id: tool_req__docs_saf_attrs_mitigated_by # (only mandatory once valid status == valid) @@ -788,7 +795,7 @@ needs_types: content: ^[\s\S]+$ optional_options: # req-Id: tool_req__docs_saf_attrs_mitigation_issue - mitigation_issue: ^https://github.com/.*$ + mitigation_issue: ^https://github\.com/[^/]+/[^/]+/issues/\d+$ mandatory_links: # req-Id: tool_req__docs_saf_attrs_violates violates: comp_arc_sta @@ -816,7 +823,7 @@ needs_types: content: ^[\s\S]+$ optional_options: # req-Id: tool_req__docs_saf_attrs_mitigation_issue - mitigation_issue: ^https://github.com/.*$ + mitigation_issue: ^https://github\.com/[^/]+/[^/]+/issues/\d+$ mandatory_links: # req-Id: tool_req__docs_saf_attrs_violates violates: feat_arc_dyn, feat_arc_sta @@ -843,7 +850,7 @@ needs_types: content: ^[\s\S]+$ optional_options: # req-Id: tool_req__docs_saf_attrs_mitigation_issue - mitigation_issue: ^https://github.com/.*$ + mitigation_issue: ^https://github\.com/[^/]+/[^/]+/issues/\d+$ mandatory_links: # req-Id: tool_req__docs_saf_attrs_violates violates: comp_arc_dyn, comp_arc_sta @@ -860,7 +867,7 @@ needs_types: title: Feature Security Analysis Threat (STRIDE) mandatory_options: # req-Id: tool_req__docs_sec_attr_stride_threat_id - threat_id: ^.*$ + threat_id: ^(AU_01_0[1-3]|AZ_01_0[1-3]|CT_01_0[1-2]|DS_01_0[1-3]|EX_01_0[1-6]|LA_01_0[1-3]|MT_01_0[1-7])$ status: ^(valid|invalid)$ content: ^[\s\S]+$ tags: @@ -873,7 +880,7 @@ needs_types: title: Component Security Analysis Threat (STRIDE) mandatory_options: # req-Id: tool_req__docs_sec_attr_stride_threat_id - threat_id: ^.*$ + threat_id: ^(AU_01_0[1-3]|AZ_01_0[1-3]|CT_01_0[1-2]|DS_01_0[1-3]|EX_01_0[1-6]|LA_01_0[1-3]|MT_01_0[1-7])$ status: ^(valid|invalid)$ content: ^[\s\S]+$ tags: @@ -886,7 +893,7 @@ needs_types: title: Platform Security Analysis Threat (STRIDE) mandatory_options: # req-Id: tool_req__docs_sec_attr_stride_threat_id - threat_id: ^.*$ + threat_id: ^(AU_01_0[1-3]|AZ_01_0[1-3]|CT_01_0[1-2]|DS_01_0[1-3]|EX_01_0[1-6]|LA_01_0[1-3]|MT_01_0[1-7])$ status: ^(valid|invalid)$ content: ^[\s\S]+$ tags: @@ -899,18 +906,18 @@ needs_types: title: Feature Security Analysis (Threat Scenario) mandatory_options: # req-Id: tool_req__docs_sec_attrs_mandatory - threat_scenario_id: ^.*$ + threat_scenario_id: ^(AS_01_(01|02|04|05|06|07|09|10)|CO_01_0[1-7]|SC_01_0[2-5]|SI_01_0[2-5]|UI_01_(0[1-9]|1[0-2]))$ # req-Id: tool_req__docs_sec_attrs_mandatory status: ^(valid|invalid)$ # req-Id: tool_req__docs_sec_attrs_mandatory sufficient: ^(yes|no)$ # req-Id: tool_req__docs_sec_attrs_mandatory threat_effect: ^.+$ - # req-Id: tool_req__docs_sec_argument + # req-Id: tool_req__docs_common_attr_description content: ^[\s\S]+$ optional_options: # req-Id: tool_req__docs_sec_attrs_optional - mitigation_issue: ^https://github.com/.*$ + mitigation_issue: ^https://github\.com/[^/]+/[^/]+/issues/\d+$ optional_links: # req-Id: tool_req__docs_sec_attrs_optional mitigated_by: feat_req, aou_req @@ -923,13 +930,14 @@ needs_types: comp_sec_ana: title: Component Security Analysis (Threat Scenario) mandatory_options: - threat_scenario_id: ^.*$ + threat_scenario_id: ^(AS_01_(01|02|04|05|06|07|09|10)|CO_01_0[1-7]|SC_01_0[2-5]|SI_01_0[2-5]|UI_01_(0[1-9]|1[0-2]))$ status: ^(valid|invalid)$ sufficient: ^(yes|no)$ threat_effect: ^.+$ + # req-Id: tool_req__docs_common_attr_description content: ^[\s\S]+$ optional_options: - mitigation_issue: ^https://github.com/.*$ + mitigation_issue: ^https://github\.com/[^/]+/[^/]+/issues/\d+$ optional_links: mitigated_by: comp_req, aou_req tags: @@ -941,13 +949,14 @@ needs_types: plat_sec_ana: title: Platform Security Analysis (Threat Scenario) mandatory_options: - threat_scenario_id: ^.*$ + threat_scenario_id: ^(AS_01_(01|02|04|05|06|07|09|10)|CO_01_0[1-7]|SC_01_0[2-5]|SI_01_0[2-5]|UI_01_(0[1-9]|1[0-2]))$ status: ^(valid|invalid)$ sufficient: ^(yes|no)$ threat_effect: ^.+$ + # req-Id: tool_req__docs_common_attr_description content: ^[\s\S]+$ optional_options: - mitigation_issue: ^https://github.com/.*$ + mitigation_issue: ^https://github\.com/[^/]+/[^/]+/issues/\d+$ optional_links: mitigated_by: feat_req, aou_req tags: diff --git a/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst b/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst index 7de48e171..ca1357192 100644 --- a/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst +++ b/src/extensions/score_metamodel/tests/rst/options/test_options_options.rst @@ -585,7 +585,7 @@ Expect no errors related to "violates" field. We need to be generic for expect-n .. feat_sec_ana:: Invalid sufficient value :id: feat_sec_ana__test__bad_5 - :threat_scenario_id: TS.01 + :threat_scenario_id: SC_01_02 :status: valid :sufficient: maybe :threat_effect: Unauthorized access to stored data. @@ -597,7 +597,7 @@ Expect no errors related to "violates" field. We need to be generic for expect-n .. feat_sec_ana:: Invalid status value :id: feat_sec_ana__test__bad_6 - :threat_scenario_id: TS.01 + :threat_scenario_id: SC_01_02 :status: done :sufficient: no :threat_effect: Unauthorized access to stored data. @@ -609,7 +609,7 @@ Expect no errors related to "violates" field. We need to be generic for expect-n .. feat_sec_ana:: Missing threat_effect :id: feat_sec_ana__test__bad_7 - :threat_scenario_id: TS.01 + :threat_scenario_id: SC_01_02 :status: invalid :sufficient: no @@ -620,7 +620,7 @@ Expect no errors related to "violates" field. We need to be generic for expect-n .. feat_sec_ana:: Valid threat scenario :id: feat_sec_ana__test__ok_8 - :threat_scenario_id: TS.01 + :threat_scenario_id: SC_01_02 :status: valid :sufficient: yes :threat_effect: Unauthorized access to stored data. @@ -632,7 +632,7 @@ Expect no errors related to "violates" field. We need to be generic for expect-n .. feat_sec_ana:: Valid threat scenario with optional mitigation_issue :id: feat_sec_ana__test__ok_9 - :threat_scenario_id: TS.02 + :threat_scenario_id: SC_01_03 :status: invalid :sufficient: no :threat_effect: Data integrity violation via tampering. @@ -641,11 +641,24 @@ Expect no errors related to "violates" field. We need to be generic for expect-n Mitigation not yet implemented. -#EXPECT: feat_sec_ana__test__bad_10: is missing required attribute: `content`. +#EXPECT: feat_sec_ana__test__bad_10.mitigation_issue (https://github.com/eclipse-score/docs-as-code/pull/508): does not follow pattern -.. feat_sec_ana:: Missing argument content +.. feat_sec_ana:: Invalid mitigation_issue (pull request, not issue) :id: feat_sec_ana__test__bad_10 - :threat_scenario_id: TS.03 + :threat_scenario_id: SC_01_04 + :status: invalid + :sufficient: no + :threat_effect: Unauthorized data access. + :mitigation_issue: https://github.com/eclipse-score/docs-as-code/pull/508 + + Mitigation not yet implemented. + + +#EXPECT: feat_sec_ana__test__bad_11: is missing required attribute: `content`. + +.. feat_sec_ana:: Missing argument content + :id: feat_sec_ana__test__bad_11 + :threat_scenario_id: SC_01_04 :status: invalid :sufficient: no :threat_effect: Unauthorized data access. diff --git a/src/extensions/score_source_code_linker/__init__.py b/src/extensions/score_source_code_linker/__init__.py index df86705a8..b0ebe7e4b 100644 --- a/src/extensions/score_source_code_linker/__init__.py +++ b/src/extensions/score_source_code_linker/__init__.py @@ -151,6 +151,15 @@ def setup_source_code_linker(app: Sphinx, ws_root: Path | None): "options": ["source_code_link", "testlink"], }, ) + app.config.needs_string_links.setdefault( + "mitigation_issue_linker", + { + "regex": r"(?Phttps://github\.com/[^/]+/(?P[^/]+)/issues/(?P\d+))", + "link_url": "{{url}}", + "link_name": "{{repo}}#{{number}}", + "options": ["mitigation_issue"], + }, + ) score_sourcelinks_json = os.environ.get("SCORE_SOURCELINKS") if not score_sourcelinks_json: From 1625b134f8cd53019a31fd029ae0e78b149c4b81 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Fri, 29 May 2026 13:53:56 +0200 Subject: [PATCH 5/5] fix: review feedback --- docs/internals/requirements/requirements.rst | 2 -- src/extensions/score_metamodel/__init__.py | 9 +++++++++ src/extensions/score_source_code_linker/__init__.py | 9 --------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/internals/requirements/requirements.rst b/docs/internals/requirements/requirements.rst index 504ede378..bc35248df 100644 --- a/docs/internals/requirements/requirements.rst +++ b/docs/internals/requirements/requirements.rst @@ -1180,8 +1180,6 @@ Testing * Component Security Analysis (Threat Scenario) -> ``comp_sec_ana`` * Platform Security Analysis (Threat Scenario) -> ``plat_sec_ana`` - All need types have a mandatory ``title`` and unique ``id``. - .. tool_req:: Security Analysis: STRIDE Threat ID Attribute :id: tool_req__docs_sec_attr_stride_threat_id diff --git a/src/extensions/score_metamodel/__init__.py b/src/extensions/score_metamodel/__init__.py index 7f26c9b83..594fdcf04 100644 --- a/src/extensions/score_metamodel/__init__.py +++ b/src/extensions/score_metamodel/__init__.py @@ -327,6 +327,15 @@ def setup(app: Sphinx) -> dict[str, str | bool]: app.config.needs_types += metamodel.needs_types app.config.needs_links.update(metamodel.needs_links) app.config.needs_fields.update(metamodel.needs_fields) + app.config.needs_string_links.setdefault( + "mitigation_issue_linker", + { + "regex": r"(?Phttps://github\.com/[^/]+/(?P[^/]+)/issues/(?P\d+))", + "link_url": "{{url}}", + "link_name": "{{repo}}#{{number}}", + "options": ["mitigation_issue"], + }, + ) app.config.graph_checks = metamodel.needs_graph_check app.config.prohibited_words_checks = metamodel.prohibited_words_checks diff --git a/src/extensions/score_source_code_linker/__init__.py b/src/extensions/score_source_code_linker/__init__.py index b0ebe7e4b..df86705a8 100644 --- a/src/extensions/score_source_code_linker/__init__.py +++ b/src/extensions/score_source_code_linker/__init__.py @@ -151,15 +151,6 @@ def setup_source_code_linker(app: Sphinx, ws_root: Path | None): "options": ["source_code_link", "testlink"], }, ) - app.config.needs_string_links.setdefault( - "mitigation_issue_linker", - { - "regex": r"(?Phttps://github\.com/[^/]+/(?P[^/]+)/issues/(?P\d+))", - "link_url": "{{url}}", - "link_name": "{{repo}}#{{number}}", - "options": ["mitigation_issue"], - }, - ) score_sourcelinks_json = os.environ.get("SCORE_SOURCELINKS") if not score_sourcelinks_json: