Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
e7e3d79
refactor VersionField into an annotation for use in other objects
ahouseholder Jul 15, 2025
de1a38b
add id property to decision points
ahouseholder Jul 15, 2025
0d7b1c2
add minimal selection object for data exchange
ahouseholder Jul 15, 2025
1a4bd12
add new version of decision point value selection schema
ahouseholder Jul 15, 2025
6813909
add new version of decision point value selection schema
ahouseholder Jul 15, 2025
cc9874a
make examples into lists
ahouseholder Jul 15, 2025
3842cf7
fix some formatting
ahouseholder Jul 15, 2025
0031210
remove default from VersionField annotation
ahouseholder Jul 15, 2025
be08398
we don't need a decision point id field separately, it's derivable fr…
ahouseholder Jul 15, 2025
4f4cde0
more clean up
ahouseholder Jul 15, 2025
b48d444
more clean up
ahouseholder Jul 15, 2025
bc81392
Merge branch '820-add-a-minimalist-selection-object' of https://githu…
ahouseholder Jul 15, 2025
82947e2
we don't need decision point id
ahouseholder Jul 15, 2025
4b64e6b
refactor schema version to variable
ahouseholder Jul 16, 2025
7c6c2a1
compute path relative to module location
ahouseholder Jul 16, 2025
3b73b3d
fix some redundancy based on copilot PR review
ahouseholder Jul 16, 2025
3624054
refactor namespace and version specifications for modularity
ahouseholder Jul 16, 2025
f690df4
add unit tests
ahouseholder Jul 16, 2025
405f9d2
add namespace pattern and update examples
ahouseholder Jul 16, 2025
3b5f191
Merge branch 'main' of https://github.com/CERTCC/SSVC into 820-add-a-…
ahouseholder Jul 16, 2025
3993da4
work in progress commit. Not quite working yet
ahouseholder Jul 17, 2025
494dbbd
updates namespace regex to fit test strings
ahouseholder Jul 17, 2025
2b8c5af
add namespaces docs
ahouseholder Jul 17, 2025
3fbb206
Update docs/reference/code/namespaces.md
ahouseholder Jul 18, 2025
2108157
fix typo
ahouseholder Jul 18, 2025
5b8c98f
Merge remote-tracking branch 'gh_pub/780-clarify-distinction-between-…
ahouseholder Jul 18, 2025
5c0b213
add reverse domain name recommendation for private / experimental nam…
ahouseholder Jul 18, 2025
8545878
add reverse domain name recommendation for private / experimental nam…
ahouseholder Jul 18, 2025
8c4077c
Merge remote-tracking branch 'gh_pub/780-clarify-distinction-between-…
ahouseholder Jul 18, 2025
c2a5e84
add warning about "no adds" in extensions.
ahouseholder Jul 18, 2025
3dae4a9
add one more test string
ahouseholder Jul 18, 2025
628709f
we're enforcing version patterns, so should -> must. Also bump defaul…
ahouseholder Jul 21, 2025
e853f33
fix default version implementation
ahouseholder Jul 21, 2025
89c1c0b
make timestamp required.
ahouseholder Jul 21, 2025
b213254
force schema order
ahouseholder Jul 21, 2025
8729d51
allow additional properties in selection object
ahouseholder Jul 21, 2025
925d661
fix how we set the schemaVersion
ahouseholder Jul 21, 2025
70fce8e
RFC 3339 is more specific than ISO 8601
ahouseholder Jul 21, 2025
ed4c9fb
Merge branch '820-add-a-minimalist-selection-object' into 780-clarify…
ahouseholder Jul 21, 2025
c2673cc
adjust example namespaces
ahouseholder Jul 21, 2025
337bcf1
pattern was blocking 2-letter TLDs in reverse-domain-name convention
ahouseholder Jul 21, 2025
b52b8ca
example.org -> example.organization (as in organization.example rever…
ahouseholder Jul 21, 2025
009b8a2
refactor defaults, patterns, and types into an ssvc.utils sub-package
ahouseholder Jul 21, 2025
cc4a679
cleanup defaults module
ahouseholder Jul 21, 2025
a1c0719
Bump jsonschema from 4.24.0 to 4.25.0
dependabot[bot] Jul 21, 2025
989a07a
fix double-copyright blocks
ahouseholder Jul 21, 2025
be4f036
rename types.py to field_specs.py
ahouseholder Jul 21, 2025
9816c5c
reinstate additionalProperties=false in JSON schema
ahouseholder Jul 21, 2025
5f17c5d
Merge branch '820-add-a-minimalist-selection-object' into 780-clarify…
ahouseholder Jul 21, 2025
4bdd8c6
Merge commit 'a1c071992c060a42c708626a92a8229bdf16ccbb' into 780-clar…
ahouseholder Jul 21, 2025
cb05a84
update schema to reflect recent changes
ahouseholder Jul 21, 2025
ea7420a
Merge branch 'main' of https://github.com/CERTCC/SSVC into 820-add-a-…
ahouseholder Jul 21, 2025
85dab99
change "vulnerability_id" to "target_ids" and make it a list of strin…
ahouseholder Jul 21, 2025
1876d68
make single selection sub-object forbid extras too
ahouseholder Jul 21, 2025
2e1aa6b
Merge branch '820-add-a-minimalist-selection-object' into 780-clarify…
ahouseholder Jul 21, 2025
8dd1569
fails on "ssvc//example.organization#model/com.example#foo"
ahouseholder Jul 21, 2025
0a2ee24
make tests pass
ahouseholder Jul 21, 2025
37c55e3
revise docstring, add abnf draft
ahouseholder Jul 21, 2025
f9904fc
update ns pattern documentation
ahouseholder Jul 21, 2025
13c364e
updated NS pattern
ahouseholder Jul 21, 2025
4aae5b0
add # to allowed chars
ahouseholder Jul 22, 2025
e26856b
replace "x_test" with "x_example.test" to bring into line with revers…
ahouseholder Jul 22, 2025
343542b
revise documentation
ahouseholder Jul 22, 2025
9210646
refine `target_ids` to avoid nullable values
ahouseholder Jul 22, 2025
8179b0f
update field descriptions
ahouseholder Jul 22, 2025
746ee88
Merge branch '820-add-a-minimalist-selection-object' into 780-clarify…
ahouseholder Jul 22, 2025
eba76b4
fix examples in namespace field_specs.py
ahouseholder Jul 22, 2025
0855875
refactor TargetIdList into ssvc.utils.field_specs
ahouseholder Jul 22, 2025
abc3bde
update schema
ahouseholder Jul 22, 2025
6702558
fix #753
ahouseholder Jul 22, 2025
5dcf367
change how we set default version so that "version" is required in ve…
ahouseholder Jul 23, 2025
afe9c61
clean up definitions with mixins
ahouseholder Jul 23, 2025
53d550d
enforce UTC and no milliseconds when serializing out to JSON
ahouseholder Jul 23, 2025
46c27a9
refactor timestamp into a mixin class
ahouseholder Jul 23, 2025
8dd88e1
fix tests
ahouseholder Jul 23, 2025
4746d8e
add keys in parentheses when we generate examples of decision points …
ahouseholder Jul 23, 2025
079d7b2
add full identity to dp title strings
ahouseholder Jul 23, 2025
65cef84
port over decision point identity method from another branch
ahouseholder Jul 23, 2025
a623e2c
fix tests
ahouseholder Jul 23, 2025
b955ef7
Improve namespace implementation (#824)
ahouseholder Jul 23, 2025
d41bfc3
add resources and reference lists to selection object
ahouseholder Jul 23, 2025
4d87f74
post-process schema to ensure that "name" and "description" fields ar…
ahouseholder Jul 23, 2025
1075c55
move post-processing into the data class itself
ahouseholder Jul 23, 2025
11793a2
rename Selection and SelectionList objects
ahouseholder Jul 23, 2025
3d60391
make selection_from_decision_point into a class method of Selection
ahouseholder Jul 23, 2025
0cceff7
take advantage of `exclude_none=True`
ahouseholder Jul 23, 2025
f6f068e
add newline at end of schema file
ahouseholder Jul 23, 2025
92274ee
add selection schema dumper to doctools.py for commit hook
ahouseholder Jul 24, 2025
54f2a14
add unit tests
ahouseholder Jul 24, 2025
b8e0911
fix test that was overly spec'ed to log sequence
ahouseholder Jul 24, 2025
bd55dd6
remove default version from selection object
ahouseholder Jul 24, 2025
cc57bb2
Add & refine docstrings
ahouseholder Jul 24, 2025
a89b250
revert uri->url back to uri
ahouseholder Jul 24, 2025
5eb833e
update schema description to reflect recent developments
ahouseholder Jul 24, 2025
9faaf9a
fix a bug in namespace validator that may have prevented extensions t…
ahouseholder Jul 24, 2025
afecc43
refine ns validator
ahouseholder Jul 24, 2025
ab2ed94
Update data/schema/v2/Decision_Point_Value_Selection-2-0-0.schema.json
ahouseholder Jul 28, 2025
1e77dcd
Update docs/adr/0012-ssvc-namespaces.md
ahouseholder Jul 28, 2025
c36eb64
Update src/test/test_namespaces_pattern.py
ahouseholder Jul 28, 2025
538020d
Update src/ssvc/selection.py
ahouseholder Jul 28, 2025
e84a406
Update docs/reference/code/namespaces.md
ahouseholder Jul 28, 2025
8c0f983
Update docs/reference/code/namespaces.md
ahouseholder Jul 28, 2025
9b2a83a
Update docs/reference/code/namespaces.md
ahouseholder Jul 28, 2025
9a48b01
Update docs/reference/code/namespaces.md
ahouseholder Jul 28, 2025
2508240
Update docs/reference/code/namespaces.md
ahouseholder Jul 28, 2025
0cedd65
Update docs/reference/code/namespaces.md
ahouseholder Jul 28, 2025
6949295
Update docs/reference/code/namespaces.md
ahouseholder Jul 28, 2025
eccf7ca
Update namespaces.md
ahouseholder Jul 28, 2025
74463f1
forbid extras
ahouseholder Jul 28, 2025
215da4e
Update docs/reference/code/namespaces.md
ahouseholder Jul 28, 2025
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
236 changes: 236 additions & 0 deletions data/schema/v2/Decision_Point_Value_Selection-2-0-0.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://certcc.github.io/SSVC/data/schema/v2/Decision_Point_Value_Selection-2-0-0.schema.json",
"title": "Decision Point Value Selection List",
"description": "This schema defines the structure for representing selected values from SSVC Decision Points. Each selection list can have multiple selection objects, each representing a decision point, and each selection object can have multiple selected values when full certainty (i.e., a singular value selection) is not available.",
"type": "object",
"properties": {
"timestamp": {
"description": "Timestamp of the selections, in RFC 3339 format.",
"examples": [
"2025-01-01T12:00:00Z",
"2025-01-02T15:30:45-04:00"
],
"format": "date-time",
"title": "Timestamp",
"type": "string"
},
"schemaVersion": {
"const": "2.0.0",
"description": "The schema version of this selection list.",
"title": "Schemaversion",
"type": "string"
},
"target_ids": {
"description": "Optional list of identifiers for the item or items (vulnerabilities, reports, advisories, systems, assets, etc.) being evaluated by these selections.",
"examples": [
[
"CVE-1900-0000"
],
[
"VU#999999",
"GHSA-0123-4567-89ab"
]
],
"items": {
"type": "string"
},
"minItems": 1,
"title": "Target Ids",
"type": "array"
},
"selections": {
"description": "List of selections made from decision points. Each selection item corresponds to value keys contained in a specific decision point identified by its namespace, key, and version. Note that selection objects are deliberately minimal objects and do not contain the full decision point details.",
"items": {
"$ref": "#/$defs/Selection"
},
"minItems": 1,
"title": "Selections",
"type": "array"
},
"resources": {
"description": "A list of references to resources that provide additional context about the decision points found in this selection.",
"examples": [
[
{
"description": "Documentation for a set of decision points",
"uri": "https://example.com/decision_points"
},
{
"description": "JSON representation of decision point 2",
"uri": "https://example.org/definitions/dp2.json"
},
{
"description": "A JSON file containing extension decision points in the x_com.example namespace",
"uri": "https://example.com/ssvc/x_com.example/decision_points.json"
}
]
],
"items": {
"$ref": "#/$defs/Reference"
},
"minItems": 1,
"title": "Resources",
"type": "array"
},
"references": {
"description": "A list of references to resources that provide additional context about the specific values selected.",
"examples": [
[
{
"description": "A report on which the selections were based",
"uri": "https://example.com/report"
}
],
[
{
"description": "A code section on which the selections were based",
"uri": "https://git.example.com/some-relevant-path/code#L21-42"
},
{
"description": "A code section on which calls the vulnerable function",
"uri": "https://git.example.com/some-relevant-path/callingcode#L91-16"
}
]
],
"items": {
"$ref": "#/$defs/Reference"
},
"minItems": 1,
"title": "References",
"type": "array"
}
},
"required": [
"timestamp",
"schemaVersion",
"selections"
],
"additionalProperties": false,
"$defs": {
"MinimalDecisionPointValue": {
"description": "A minimal representation of a decision point value.\nIntended to parallel the DecisionPointValue object, but with fewer required fields.\nA decision point value is uniquely identified within a decision point by its key.\nGlobally, the combination of Decision Point namespace, key, and version coupled with the value key\nuniquely identifies a value across all decision points and values.\nOther required fields in the DecisionPointValue object, such as name and description, are optional here.",
"properties": {
"key": {
"title": "Key",
"type": "string"
},
"name": {
"title": "Name",
"type": "string"
},
"description": {
"title": "Description",
"type": "string"
}
},
"required": [
"key"
],
"title": "MinimalDecisionPointValue",
"type": "object"
},
"Reference": {
"additionalProperties": false,
"description": "A reference to a resource that provides additional context about the decision points or selections.\nThis object is intentionally minimal and contains only the URL and an optional description.",
"properties": {
"uri": {
"format": "uri",
"minLength": 1,
"title": "Uri",
"type": "string"
},
"description": {
"title": "Description",
"type": "string"
}
},
"required": [
"uri"
],
"title": "Reference",
"type": "object"
},
"Selection": {
"additionalProperties": false,
"description": "A minimal selection object that contains the decision point ID and the selected values.\nWhile the Selection object parallels the DecisionPoint object, it is intentionally minimal, with\nfewer required fields and no additional metadata, as it is meant to represent a selection made from a\npreviously defined decision point. The expectation is that a Selection object will usually have\nfewer values than the original decision point, as it represents a specific evaluation\nat a specific time and may therefore rule out some values that were previously considered.\nOther fields like name and description may be copied from the decision point, but are not required.",
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"description": {
"title": "Description",
"type": "string"
},
"namespace": {
"description": "The namespace of the SSVC object.",
"examples": [
"ssvc",
"cisa",
"x_com.example//com.example#private",
"ssvc/de-DE/example.organization#reference-arch-1"
],
"maxLength": 1000,
"minLength": 3,
"pattern": "^(?=.{3,1000}$)(?:x_(?!.*[.-]{2,})[a-z][a-z0-9]+(?:[.-][a-z0-9]+)*|(?!.*[.-]{2,})[a-z][a-z0-9]+(?:[.-][a-z0-9]+)*)(?:(?:/(([A-Za-z]{2,3}(-[A-Za-z]{3}(-[A-Za-z]{3}){0,2})?|[A-Za-z]{4,8})(-[A-Za-z]{4})?(-([A-Za-z]{2}|[0-9]{3}))?(-([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-[A-WY-Za-wy-z0-9](-[A-Za-z0-9]{2,8})+)*(-[Xx](-[A-Za-z0-9]{1,8})+)?|[Xx](-[A-Za-z0-9]{1,8})+|[Ii]-[Dd][Ee][Ff][Aa][Uu][Ll][Tt]|[Ii]-[Mm][Ii][Nn][Gg][Oo])/|//)(?!.*[.-]{2,})[a-zA-Z][a-zA-Z0-9]*(?:[.-][a-zA-Z0-9]+)*(?:#[a-zA-Z0-9]+(?:[.-][a-zA-Z0-9]+)*)?(?:/(?!.*[.-]{2,})[a-zA-Z][a-zA-Z0-9]*(?:[.-][a-zA-Z0-9]+)*(?:#[a-zA-Z0-9]+(?:[.-][a-zA-Z0-9]+)*)?)*)?$",
"title": "Namespace",
"type": "string"
},
"key": {
"title": "Key",
"type": "string"
},
"version": {
"description": "The version of the SSVC object. This must be a valid semantic version string.",
"examples": [
"1.0.0",
"2.1.3"
],
"minLength": 5,
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$",
"title": "Version",
"type": "string"
},
"values": {
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer these to match to "Name" of the value as seen in Decision Point Schema here https://certcc.github.io/SSVC/data/schema/v1/Decision_Point-1-0-1.schema.json#/$defs/decision_point_value/properties/name - No matter what we say about these being machine readable some one will see this Selection and wonder what does "N" mean for example. It is likely these selection schemas will be used without a local reference of all the Decision Points. In the earliest version, I had an option to embed all the Decision Points in the Selection if needed so a single Selection Document is complete in giving all information needed and consistent with itself and did not need a lookup.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with @sei-vsarvepalli that it is for humans nice to have a name value.

"description": "A list of selected value keys from the decision point values.",
"examples": [
[
{
"key": "N"
},
{
"key": "Y"
}
],
[
{
"key": "A"
},
{
"key": "B"
},
{
"key": "C"
}
]
],
"items": {
"$ref": "#/$defs/MinimalDecisionPointValue"
},
"minItems": 1,
"title": "Values",
"type": "array"
}
},
"required": [
"namespace",
"key",
"version",
"values"
],
"title": "Selection",
"type": "object"
}
}
}
121 changes: 121 additions & 0 deletions docs/adr/0012-ssvc-namespaces.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
status: "accepted"
date: 2025-07-22
deciders: @ahouseholer @sei-vsarvepalli
consulted: @tschmidtb51
---
# Use of Namespaces in SSVC objects

## Context and Problem Statement

We need to include decision points and other objects that are not directly
defined by the SSVC project team. For example, CVSS vector elements are a
rich source of structured data that can be used to inform SSVC decisions and
modeled as SSVC decision point objects. However, the
[FIRST CVSS SIG](https://www.first.org/cvss) owns the definition of CVSS vector
elements. So we need a way to describe these objects in SSVC format
without making them part of the SSVC specification.


## Decision Drivers

- Need to include decision points based on data, objects, standards, and other
definitions that are not part of the SSVC specification.
- Need to clearly distinguish between objects managed by the SSVC project and
objects provided for convenience by the SSVC project, but whose semantics are
defined by other projects or standards.

## Considered Options

- One big pile of objects (effectively no namespaces)
- Use namespaces to distinguish between SSVC project objects and other objects

## Decision Outcome

Chosen option: "Use namespaces", because

- Clearly distinguishes between SSVC project objects and objects derived from other sources
- Allows for extension of SSVC objects with additional data from other sources
- Allows for extensions for langauages, translation, localization, etc.

Specifically, we intend to use:

**Registered namespaces** for objects that we create and maintain (even if they are
based on other sources).

!!! example

We use the `ssvc` namespace for all SSVC objects that are part of the
main project. We use the `cvss` namespace to contain CVSS vector elements.

**Unregistered namespaces** for objects that we do not create or maintain, but
that others may want for their own use. Unregistered namespaces must start with
an `x_` prefix followed by a reverse domain name, such as `x_org.example`.
Unregistered namespaces are intended for experimental or private use.

!!! example

A government agency might create a set of decision points for internal use
using the `x_example.agency` namespace. This allows them to use SSVC objects
of their own design alongside existig SSVC objects without needing to
register their namespace with the SSVC project.

**Namespace extensions** for objects that are derived from other objects in an
registered or unregistered namespace. Extensions are not intended to be used to
introduce new objects, but rather to refine existing objects with additional data
or semantics.
Namespace extensions can be used for refining the meaning of decision point
values for a specific constituency, or adding additional nuance to
interpretation of a decision point in a specific context.

!!! example

An ISAO (Information Sharing and Analyzing Organization) might want to refine the meaning of decision point values for their
constituency, and could use `ssvc//example.isao` as the namespace for their
collection of extensions.

### Consequences

#### Positive Consequences

- SSVC users can customize SSVC objects with additional refinements using extensions
- SSVC users can create their own SSVC objects in an unregistered namespace for
their own use, and share them with others
- Facilitates language translation and localization of SSVC objects to specific
constituencies


#### Negative Consequences

- Registered namespaces must be managed and maintained
- Potential for confusion if unregistered namespaces are used without care or
violating the naming conventions

<!-- This is an optional element. Feel free to remove. -->
### Confirmation

- Regular expressions are used in the SSVC specification in both python objects
and JSON schema to validate the namespace format.
- Object validators can be used to ensure that namespaces are correctly formatted
and that registered namespaces are used for objects that are part of the SSVC
specification.

<!-- This is an optional element. Feel free to remove. -->
## Pros and Cons of the Options

### One big pile of objects

We started out with all objects having no namespaces, which meant that
all objects were effectively part of the SSVC specification. This was problematic
because it made it difficult to distinguish between objects that were part of the
SSVC specification under our control and objects that were derived from other sources.

- Good, because it was simple and easy to understand
- Bad, because it made it difficult to distinguish between SSVC project objects and
objects based on specifications we neither created nor maintained


<!-- This is an optional element. Feel free to remove. -->
## More Information

- [SSVC Namespace Documentation](../reference/code/namespaces.md)
1 change: 1 addition & 0 deletions docs/adr/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ the decision records that have been made.
- [0009 - Outcomes are Ordered Sets](0009-outcomes-are-ordered-sets.md)
- [0010 - Outcome Sets are separate from Decision Point Groups](0010-outcome-sets-are-separate-from-decision-point-groups.md)
- [0011 - Correspondence between Automatable v2.0.0, Value Density v1.0.0, and CVSS v4](0011-automatable-and-value-density-and-CVSSv4.md)
- [0012 - SSVC Namespaces](0012-ssvc-namespaces.md)

## Rejected Records

Expand Down
Loading