Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,12 @@ http_file(

bazel_dep(name = "score_process_description", version = "2.1.2")

# Security process checks (#796) are not yet released
git_override(
module_name = "score_process_description",
commit = "5f80e45c89e99e1c964e556c93ff8acfb19c6718",
remote = "https://github.com/eclipse-score/process_description.git",
)

# Provide the tools from the devcontainer to Bazel
bazel_dep(name = "score_devcontainer", version = "1.11.1")
2 changes: 0 additions & 2 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 44 additions & 1 deletion docs/internals/requirements/requirements.rst
Original file line number Diff line number Diff line change
Expand Up @@ -647,14 +647,57 @@ Architecture Attributes
.. tool_req:: Security: Restrict linkage
:id: tool_req__docs_arch_link_security
:tags: Architecture
:implemented: YES
:implemented: PARTIAL
:version: 1
:parent_covered: YES
:satisfies: gd_req__arch_linkage_security_trace[version==1]

Docs-as-Code shall enforce that security relevant :need:`tool_req__docs_arch_types` (Security ==
YES) can only be linked against security relevant :need:`tool_req__docs_arch_types`.

.. note::
Currently only the ``implements`` link is checked.

.. tool_req:: Security: Requirement satisfied by security architecture
:id: tool_req__docs_req_link_security_to_arch
:tags: Architecture
:implemented: YES
:version: 1
:parent_covered: YES
:satisfies: gd_req__arch_linkage_requirement_security[version==1]

Docs-as-Code shall enforce that security relevant requirements (Security == YES) are only
satisfied (``satisfied_by``) by security relevant :need:`tool_req__docs_arch_types`
(Security == YES).

.. tool_req:: Security: Non-security architecture fulfils no security requirement
:id: tool_req__docs_arch_link_nonsec_to_sec_req
:tags: Architecture
:implemented: YES
:version: 1
:parent_covered: YES

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YES: Together with tool_req__docs_req_link_security_to_arch``

:satisfies: gd_req__arch_linkage_requirement_security[version==1]

Docs-as-Code shall enforce that :need:`tool_req__docs_arch_types` which are not security
relevant (Security == NO) do not fulfil (``fulfils``) security relevant requirements or AoUs
(Security == YES).

.. tool_req:: Security: Security requirement keeps a security child
:id: tool_req__docs_req_link_security_child
:tags: Architecture
:implemented: YES
:version: 1
:parent_covered: YES
:satisfies: gd_req__req_linkage_security[version==1]

Docs-as-Code shall enforce that every security relevant requirement (Security == YES) which
has child requirements (``derived_from``) has at least one security relevant child requirement
(Security == YES).

.. note::
Parent-child pairs across repository boundaries are not checked, because either the
children are missing in the build or the parent is external.
Comment on lines +685 to +699

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The process seems not complete here, as I don't see this in the process.
Is this something that will be coming in after or where the wording will change?
Cause the linked requirement doesn't specify this part.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually we check all links, regardless of cross repo or not. Not checking when cross repo would actually require some effort.


----------------------
πŸ–ΌοΈ Diagram Related
----------------------
Expand Down
39 changes: 38 additions & 1 deletion src/extensions/score_metamodel/checks/graph_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************
import operator
from collections import defaultdict
from collections.abc import Callable
from functools import reduce
from itertools import chain
Expand Down Expand Up @@ -183,6 +184,8 @@ def check_metamodel_graph(
f"Explanation for graph check {check_name} is missing. "
"Explanations are mandatory for graph checks."
)
# New checks only report infos until existing data has been cleaned up.
is_new_check = bool(check_config.get("new_check", False))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good feature. I think we can add this in this PR as an introduction even if it should be a seperate one.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure... our current info messages are ignored by everyone. And we will not see these in our downstream tests?

# Get all needs matching the selection criteria
try:
selected_needs = filter_needs_by_criteria(
Expand Down Expand Up @@ -224,7 +227,7 @@ def check_metamodel_graph(
f"condition `{check_to_perform[parent_relation]}`."
f" Explanation: {explanation}"
)
log.warning_for_need(need, msg)
log.warning_for_need(need, msg, is_new_check=is_new_check)


@graph_check
Expand Down Expand Up @@ -254,3 +257,37 @@ def check_valid_only_links_to_valid(
if invalid_needs:
msg = f"is valid but links to invalid need(s): {invalid_needs}"
log.warning_for_need(need, msg, is_new_check=True)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to add a new item to the graph checks.
Similar to the new_check we should add a thing that tells it if ALL have to fulfilled or if just one has to be.
Then we can adapt the logic of the current code a bit and don't have to add a single new check that does it for this circumstance?

@AlexanderLanin @a-zw thoughts on this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding that mechanism to the metamodel.yaml is good.

I'm not convinced about the name "new_check" because "new" is vague and relative. Maybe "info_only"?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's consitent with internal naming there we also have it called new_check but yes it probably should be like info_only or similar.


# req-Id: tool_req__docs_req_link_security_child
@graph_check
def check_security_parent_keeps_security_child(
app: Sphinx,
all_needs: NeedsView,
log: CheckLogger,
):
"""
A security relevant requirement with child requirements (derived_from)
must keep at least one security relevant child. Unlike safety, children
which are not security relevant are allowed, the security aspect must just
not get lost during refinement.
"""
req_types = {"stkh_req", "feat_req", "comp_req"}
children: defaultdict[str, list[NeedItem]] = defaultdict(list)
for need in all_needs.values():
if need["type"] in req_types:
parents = cast(list[str], need.get("derived_from") or [])
for parent in parents:
# Strip version conditions like `[version==1]`
children[parent.split("[")[0]].append(need)

for need in all_needs.filter_is_external(False).values():
if need["type"] not in req_types or need.get("security") != "YES":
continue
kids = children.get(need["id"], [])
if kids and not any(k.get("security") == "YES" for k in kids):
msg = (
"is security relevant, but none of its child requirements is: "
+ ", ".join(k["id"] for k in kids)
)
log.warning_for_need(need, msg, is_new_check=True)
26 changes: 24 additions & 2 deletions src/extensions/score_metamodel/metamodel.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1253,10 +1253,10 @@ graph_checks:
# req-Id: tool_req__docs_arch_link_security
tool_req__docs_arch_link_security:
needs:
include: feat_arc_sta, logic_arc_int, logic_arc_int_op, comp_arc_sta, real_arc_int, real_arc_int_op
include: feat_arc_sta, logic_arc_int, logic_arc_int_op, comp, comp_arc_sta, real_arc_int, real_arc_int_op
condition: security == YES
check:
implements: security == YES # Which attribute???
implements: security == YES
explanation: An security architecture element can only link other security architecture elements.

# Workproducts may only link to ASPICE 40 IIC stakeholder requirements
Expand All @@ -1270,3 +1270,25 @@ graph_checks:
- id contains aspice_40__iic
- id contains std_wp
explanation: Workproducts may only link to ASPICE 40 IIC stakeholder requirements. Please ensure that the linked requirement is an ASPICE 40 IIC stakeholder requirement.

# req-Id: tool_req__docs_req_link_security_to_arch
tool_req__docs_req_link_security_to_arch:
needs:
include: feat_req, comp_req
condition: security == YES
check:
satisfied_by: security == YES
# Reported as info until existing data has been cleaned up.
new_check: true
explanation: A security relevant requirement can only be satisfied by security relevant architecture elements.

# req-Id: tool_req__docs_arch_link_nonsec_to_sec_req
tool_req__docs_arch_link_nonsec_to_sec_req:
needs:
include: feat_arc_sta, feat_arc_dyn, logic_arc_int, comp, comp_arc_sta, comp_arc_dyn, real_arc_int
condition: security == NO
check:
fulfils: security == NO
# Reported as info until existing data has been cleaned up.
new_check: true
explanation: An architecture element which is not security relevant cannot fulfil security relevant requirements or AoUs.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
:derivation_technique: requirements_based

Checks if valid reqs only link to valid reqs
Note: DISABLED ATM, due to check not being a 'full' warning yet
Note: The check is a new check, so its finding is reported as info.



Expand All @@ -31,13 +31,9 @@



.. We can not yet enable this test. As the check is only an 'info' and not yet a true warning
.. Therefore the test is the inverse of what we will test once it is enabled.


.. comp_saf_fmea:: Child requirement
:id: comp_saf_fmea__child__1
:safety: QM
:status: valid
:mitigated_by: feat_req__parent__QM_invalid
:expect_not: invalid need(s)
:expect: is valid but links to invalid need(s): {'feat_req__parent__QM_invalid'}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test will not be green.
The warning is active but only as a new_check meaning it's an info.
The test only chekcs for warnings.

That's why it was testing the inverse earlier, which is the only thing we can do until we have the valid check fully active.

Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
..
# *******************************************************************************
# Copyright (c) 2026 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

.. test_metadata::
:id: test_metadata__security_linkage
:partially_verifies_list: tool_req__docs_arch_link_security, tool_req__docs_req_link_security_to_arch, tool_req__docs_arch_link_nonsec_to_sec_req, tool_req__docs_req_link_security_child
:test_type: requirements_based
:derivation_technique: requirements_based

Tests the security linkage checks between requirements and architecture.
The checks tool_req__docs_req_link_security_to_arch,
tool_req__docs_arch_link_nonsec_to_sec_req and
tool_req__docs_req_link_security_child are new checks, so their findings
are reported as infos instead of warnings.


.. Setup: link targets used by the tests below.

.. logic_arc_int:: Security interface
:id: logic_arc_int__test_sec__yes
:security: YES
:safety: QM
:status: valid

.. logic_arc_int:: Non-security interface
:id: logic_arc_int__test_sec__no
:security: NO
:safety: QM
:status: valid

.. comp:: Security component
:id: comp__test_sec_yes
:security: YES
:safety: QM
:status: valid

.. comp:: Non-security component
:id: comp__test_sec_no
:security: NO
:safety: QM
:status: valid


.. tool_req__docs_arch_link_security: a security component may only implement security interfaces.

.. Positive Test: security component implements a security interface.

.. comp:: Security component implements security interface
:id: comp__test_sec_impl_ok
:security: YES
:safety: QM
:status: valid
:implements: logic_arc_int__test_sec__yes
:expect_not: does not fulfill condition `security == YES`

.. Negative Test: security component implements a non-security interface.

.. comp:: Security component implements non-security interface
:id: comp__test_sec_impl_bad
:security: YES
:safety: QM
:status: valid
:implements: logic_arc_int__test_sec__no
:expect: Parent need `logic_arc_int__test_sec__no` does not fulfill condition `security == YES`.


.. tool_req__docs_req_link_security_to_arch: new check, reported as info only.

.. Positive Test: security requirement satisfied by a security component.

.. comp_req:: Security requirement
:id: comp_req__test_sec_yes
:security: YES
:safety: QM
:status: valid
:satisfied_by: comp__test_sec_yes
:expect_not: does not fulfill condition `security == YES`

.. Negative Test: security requirement satisfied by a non-security component.

.. comp_req:: Security requirement satisfied by non-security component
:id: comp_req__test_sec_satisfied_by_nonsec
:security: YES
:safety: QM
:status: valid
:satisfied_by: comp__test_sec_no
:expect: Parent need `comp__test_sec_no` does not fulfill condition `security == YES`


.. tool_req__docs_arch_link_nonsec_to_sec_req: new check, reported as info only.

.. comp_req:: Non-security requirement
:id: comp_req__test_sec_no
:security: NO
:safety: QM
:status: valid
:satisfied_by: comp__test_sec_no

.. Positive Test: non-security interface fulfils a non-security requirement.

.. real_arc_int:: Non-security interface fulfils non-security requirement
:id: real_arc_int__test_sec__fulfils_ok
:security: NO
:safety: ASIL_B
:status: valid
:fulfils: comp_req__test_sec_no
:expect_not: does not fulfill condition `security == NO`

.. Negative Test: non-security interface fulfils a security requirement.

.. real_arc_int:: Non-security interface fulfils security requirement
:id: real_arc_int__test_sec__fulfils_bad
:security: NO
:safety: ASIL_B
:status: valid
:fulfils: comp_req__test_sec_yes
:expect: Parent need `comp_req__test_sec_yes` does not fulfill condition `security == NO`


.. tool_req__docs_req_link_security_child: new check, reported as info only.

.. Positive Test: one security child is enough, non-security children are allowed.

.. feat_req:: Security parent with a security child
:id: feat_req__test_sec_parent_ok
:security: YES
:safety: QM
:status: valid
:expect_not: none of its child requirements

.. comp_req:: Security child
:id: comp_req__test_sec_child_ok_yes
:security: YES
:safety: QM
:status: valid
:derived_from: feat_req__test_sec_parent_ok
:satisfied_by: comp__test_sec_yes

.. comp_req:: Non-security child next to a security child
:id: comp_req__test_sec_child_ok_no
:security: NO
:safety: QM
:status: valid
:derived_from: feat_req__test_sec_parent_ok
:satisfied_by: comp__test_sec_no

.. Negative Test: security parent with only non-security children.

.. feat_req:: Security parent with only non-security children
:id: feat_req__test_sec_parent
:security: YES
:safety: QM
:status: valid
:expect: is security relevant, but none of its child requirements is: comp_req__test_sec_child_no

.. comp_req:: Non-security child
:id: comp_req__test_sec_child_no
:security: NO
:safety: QM
:status: valid
:derived_from: feat_req__test_sec_parent
:satisfied_by: comp__test_sec_no
Loading
Loading