github.com/gemaraproj/gemara@v1.3.0

riskcatalog.cue raw

  1// SPDX-License-Identifier: Apache-2.0
  2
  3// Schema lifecycle: experimental | stable | deprecated
  4@status("experimental")
  5package gemara
  6
  7import "list"
  8
  9@go(gemara)
 10
 11// A RiskCatalog is a structured collection of documented risks that may affect an organization,
 12// system, or service. It provides a centralized reference for risks that can be mapped to threats
 13// and referenced by policies when documenting how those risks are mitigated or accepted.
 14#RiskCatalog: {
 15	#Catalog
 16	metadata: type: "RiskCatalog"
 17
 18	// groups narrows the base groups to risk categories with appetite and severity boundaries
 19	groups?: [#RiskCategory, ...#RiskCategory]
 20
 21	// risks is a list of risks defined by this catalog
 22	risks?: [#Risk, ...#Risk] @go(Risks)
 23
 24	if risks != _|_ {
 25		_uniqueRiskIds: {for i, r in risks {(r.id): i}}
 26		// Each distinct rank value may appear at most once among risks that set rank (partial ranking allowed).
 27		// Keys are stringified ranks because CUE struct labels cannot be raw integers.
 28		_uniqueRiskRanks: {for i, r in risks if r.rank != _|_ {"\(r.rank)": i}}
 29		groups: [#RiskCategory, ...#RiskCategory]
 30		let _validGroupIds = [for g in groups {g.id}]
 31
 32		// Unify the valid ID list with a list.Contains constraint to require each entry's value exists
 33		for i, r in risks {
 34			_groupValidation: "\(i)": _validGroupIds & list.Contains(r.group)
 35		}
 36	}
 37}
 38
 39// RiskCategory describes a grouping of risks and defines appetite boundaries
 40#RiskCategory: {
 41	#Group
 42
 43	// appetite defines the acceptable level of risk for this category
 44	appetite: #RiskAppetite @go(Appetite)
 45
 46	// max-severity defines the risk tolerance boundary: the highest severity
 47	// the organization will accept within this category
 48	"max-severity"?: #Severity @go(MaxSeverity) @yaml("max-severity,omitempty")
 49}
 50
 51// Severity defines the assessed level of a risk based on its potential impact and likelihood
 52#Severity:
 53	// minor consequence if realized; manageable within normal operations
 54	"Low" |
 55	// moderate consequence if realized; may impair specific functions or objectives
 56	"Medium" |
 57	// severe consequence if realized; likely to disrupt core operations or objectives
 58	"High" |
 59	// extreme consequence if realized; threatens organizational viability or mission
 60	"Critical" @go(-)
 61
 62// RiskAppetite defines the acceptable level of exposure for a risk category
 63#RiskAppetite:
 64	// organization is willing to accept higher cost to minimize risk
 65	"Minimal" |
 66	// organization favors caution but permits limited risk
 67	"Low" |
 68	// organization tolerates residual risk when justified by value
 69	"Moderate" |
 70	// organization is willing to operate with less restrictive controls
 71	"High" @go(-)
 72
 73// A Risk represents the potential for negative impact resulting from one or more threats.
 74#Risk: {
 75	// id allows this risk to be referenced by other elements
 76	id: string
 77
 78	// title describes the risk
 79	title: string
 80
 81	// description explains the risk scenario
 82	description: string
 83
 84	// group references by id a catalog group that this risk belongs to
 85	group: string @go(Group)
 86
 87	// severity describes the assessed level of this risk
 88	severity: #Severity @go(Severity)
 89
 90	// rank optionally orders risks for the same catalog (e.g. when several share the same severity).
 91	// Lower values mean higher relative importance. Omitted when the four severity levels are enough.
 92	// When set, each value must be unique among all risks in the catalog that specify rank.
 93	rank?: int @go(Rank) @yaml("rank,omitempty")
 94
 95	// owner defines the RACI roles responsible for managing this risk
 96	owner?: #RACI @go(Owner)
 97
 98	// impact describes the business or operational impact
 99	impact?: string
100
101	// threats link this risk to Layer 2 threats
102	"threats"?: [#MultiEntryMapping, ...#MultiEntryMapping] @go(Threats)
103}