diff --git a/docs/reference/decision_points/cvss/index.md b/docs/reference/decision_points/cvss/index.md
index 74c9fa53..f9309c0f 100644
--- a/docs/reference/decision_points/cvss/index.md
+++ b/docs/reference/decision_points/cvss/index.md
@@ -23,6 +23,12 @@ We have organized them into groups according to where they belong in the
been refined over different versions of the CVSS specification. These versions
do _not_ correspond the CVSS specification versions (2.0, 3.0, 3.1, 4.0 etc.).
+### Qualitative Severity
+
+
+- [CVSS Qualitative Severity Rating Scale](qualitative_severity.md)
+
+
### Base Metrics
diff --git a/docs/reference/decision_points/cvss/qualitative_severity.md b/docs/reference/decision_points/cvss/qualitative_severity.md
new file mode 100644
index 00000000..81be133d
--- /dev/null
+++ b/docs/reference/decision_points/cvss/qualitative_severity.md
@@ -0,0 +1,12 @@
+# CVSS Qualitative Severity Rating Scale
+
+```python exec="true" idprefix=""
+from ssvc.decision_points.cvss.qualitative_severity import LATEST
+from ssvc.doc_helpers import example_block
+
+print(example_block(LATEST))
+```
+
+The [CVSS Qualitative Severity Rating Scale](https://www.first.org/cvss/v4.0/specification-document#Qualitative-Severity-Rating-Scale)
+is a set of labels that describe the severity of a vulnerability based on the
+CVSS Score.
diff --git a/mkdocs.yml b/mkdocs.yml
index 1b896cf1..2e47540c 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -73,6 +73,7 @@ nav:
- Utility: 'reference/decision_points/utility.md'
- CVSS-based decision points:
- 'reference/decision_points/cvss/index.md'
+ - Qualitative Severity: 'reference/decision_points/cvss/qualitative_severity.md'
- Base Metrics:
- Attack Vector: 'reference/decision_points/cvss/attack_vector.md'
- Attack Complexity: 'reference/decision_points/cvss/attack_complexity.md'
diff --git a/src/ssvc/decision_points/cvss/qualitative_severity.py b/src/ssvc/decision_points/cvss/qualitative_severity.py
new file mode 100644
index 00000000..23358fe7
--- /dev/null
+++ b/src/ssvc/decision_points/cvss/qualitative_severity.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+"""
+Provides a decision point for the [CVSS Qualitative Severity Rating Scale](https://www.first.org/cvss/v4.0/specification-document#Qualitative-Severity-Rating-Scale).
+"""
+# Copyright (c) 2025 Carnegie Mellon University and Contributors.
+# - see Contributors.md for a full list of Contributors
+# - see ContributionInstructions.md for information on how you can Contribute to this project
+# Stakeholder Specific Vulnerability Categorization (SSVC) is
+# licensed under a MIT (SEI)-style license, please see LICENSE.md distributed
+# with this Software or contact permission@sei.cmu.edu for full terms.
+# Created, in part, with funding and support from the United States Government
+# (see Acknowledgments file). This program may include and/or can make use of
+# certain third party source code, object code, documentation and other files
+# (“Third Party Software”). See LICENSE.md for more details.
+# Carnegie Mellon®, CERT® and CERT Coordination Center® are registered in the
+# U.S. Patent and Trademark Office by Carnegie Mellon University
+
+from ssvc.decision_points import SsvcDecisionPointValue
+from ssvc.decision_points.cvss.base import CvssDecisionPoint
+from ssvc.decision_points.helpers import print_versions_and_diffs
+
+QS_NONE = SsvcDecisionPointValue(
+ name="None",
+ key="N",
+ description="No severity rating (0.0)",
+)
+
+LOW = SsvcDecisionPointValue(
+ name="Low",
+ key="L",
+ description="Low (0.1 - 3.9)",
+)
+MEDIUM = SsvcDecisionPointValue(
+ name="Medium",
+ key="M",
+ description="Medium (4.0 - 6.9)",
+)
+HIGH = SsvcDecisionPointValue(
+ name="High",
+ key="H",
+ description="High (7.0 - 8.9)",
+)
+CRITICAL = SsvcDecisionPointValue(
+ name="Critical",
+ key="C",
+ description="Critical (9.0 - 10.0)",
+)
+
+QUALITATIVE_SEVERITY = CvssDecisionPoint(
+ name="CVSS Qualitative Severity Rating Scale",
+ key="QS",
+ description="The CVSS Qualitative Severity Rating Scale provides "
+ "a categorical representation of a CVSS Score.",
+ version="1.0.0",
+ values=(
+ QS_NONE,
+ LOW,
+ MEDIUM,
+ HIGH,
+ CRITICAL,
+ ),
+)
+
+VERSIONS = (QUALITATIVE_SEVERITY,)
+LATEST = VERSIONS[-1]
+
+
+def main():
+ print_versions_and_diffs(VERSIONS)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/ssvc/doc_helpers.py b/src/ssvc/doc_helpers.py
index 6304044f..16a48bc8 100644
--- a/src/ssvc/doc_helpers.py
+++ b/src/ssvc/doc_helpers.py
@@ -69,10 +69,12 @@ def example_block_tabbed(dp: SsvcDecisionPoint, indent=4) -> str:
return "\n".join(rows)
-def example_block(dp: SsvcDecisionPoint, indent=4) -> str:
+def example_block(
+ dp: SsvcDecisionPoint, indent: int = 4, include_json: bool = True
+) -> str:
"""Given a decision point, return a markdown block that contains an example of the decision point."""
- indent_ = " " * 4
+ indent_ = " " * indent
rows = []
rows.append(f'!!! note "{dp.name} v{dp.version}"')
rows.append("")
@@ -81,12 +83,11 @@ def example_block(dp: SsvcDecisionPoint, indent=4) -> str:
rows.append(indent_ + row)
rows.append("")
- rows.append(
- indent_ + f'??? example "{dp.name} v{dp.version} JSON Example"'
- )
- rows.append("")
- for row in json_example(dp, indent=4).splitlines():
- rows.append(indent_ + row)
+ if include_json:
+ rows.append(indent_ + f'??? example "{dp.name} v{dp.version} JSON Example"')
+ rows.append("")
+ for row in json_example(dp, indent=4).splitlines():
+ rows.append(indent_ + row)
return "\n".join(rows)