github.com/gemaraproj/gemara@v1.3.0

controlcatalog.cue raw

 1// SPDX-License-Identifier: Apache-2.0
 2
 3// Schema lifecycle: experimental | stable | deprecated
 4@status("stable")
 5package gemara
 6
 7import "list"
 8
 9@go(gemara)
10
11// ControlCatalog describes a set of related controls and relevant metadata
12#ControlCatalog: {
13	#Catalog
14	metadata: type: "ControlCatalog"
15
16	// controls is a list of unique controls defined by this catalog
17	controls?: [#Control, ...#Control] @go(Controls)
18
19	if controls != _|_ {
20		_uniqueControlIds: {for i, c in controls {(c.id): i}}
21		groups: [#Group, ...#Group]
22		metadata: "applicability-groups": [#Group, ...#Group]
23		let _validGroupIds = [for g in groups {g.id}]
24		let _validApplicabilityIds = [for ag in metadata."applicability-groups" {ag.id}]
25
26		// Unify the valid ID list with a list.Contains constraint to require each entry's value exists
27		for i, c in controls {
28			_groupValidation: "\(i)": _validGroupIds & list.Contains(c.group)
29			for j, ar in c."assessment-requirements" {
30				for k, a in ar.applicability {
31					_applicabilityValidation: "\(i)-\(j)-\(k)": _validApplicabilityIds & list.Contains(a)
32				}
33			}
34		}
35	}
36}
37
38// Control describes a safeguard or countermeasure with a clear objective and assessment requirements
39#Control: {
40	// id allows this entry to be referenced by other elements
41	id: string
42
43	// title describes the purpose of this control at a glance
44	title: string
45
46	// objective is a unified statement of intent, which may encompass multiple situationally applicable requirements
47	objective: string
48
49	// group references by id a catalog group that this control belongs to
50	group: string @go(Group)
51
52	// assessment-requirements is a list of requirements that must be verified to confirm the control objective has been met
53	"assessment-requirements": [#AssessmentRequirement, ...#AssessmentRequirement] @go(AssessmentRequirements)
54
55	// guidelines documents relationships between this control and Layer 1 guideline artifacts
56	guidelines?: [#MultiEntryMapping, ...#MultiEntryMapping] @go(Guidelines)
57
58	// threats documents relationships between this control and Layer 2 threat artifacts
59	threats?: [#MultiEntryMapping, ...#MultiEntryMapping] @go(Threats)
60
61	// state is the lifecycle state of this control
62	state: #Lifecycle @go(State) @yaml("state,omitempty")
63
64	// replaced-by references the control that supersedes this one when deprecated or retired
65	"replaced-by"?: #EntryMapping @go(ReplacedBy,optional=nillable) @yaml("replaced-by,omitempty")
66}
67
68// AssessmentRequirement describes a tightly scoped, verifiable condition that must be satisfied and confirmed by an evaluator
69#AssessmentRequirement: {
70	// id allows this entry to be referenced by other elements
71	id: string
72
73	// text is the body of the requirement, typically written as a MUST condition
74	text: string
75
76	// applicability is a list of strings describing the situations where this text functions as a requirement for its parent control
77	applicability: [string, ...string]
78
79	// recommendation provides readers with non-binding suggestions to aid in evaluation or enforcement of the requirement
80	recommendation?: string
81
82	// state is the lifecycle state of this assessment requirement
83	state: #Lifecycle @go(State) @yaml("state,omitempty")
84
85	// replaced-by references the assessment requirement that supersedes this one when deprecated or retired
86	"replaced-by"?: #EntryMapping @go(ReplacedBy,optional=nillable) @yaml("replaced-by,omitempty")
87
88	// retired assessment requirements must not have a recommendation
89	if state == "Retired" {
90		recommendation?: _|_
91	}
92}