@mitre/hdf-schema 3.0.0 → 3.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/LICENSE.md +55 -0
  2. package/README.md +96 -41
  3. package/dist/go/hdf.go +148 -104
  4. package/dist/helpers.js +4 -44
  5. package/dist/index.d.ts +26 -1
  6. package/dist/index.js +26 -1
  7. package/dist/schemas/hdf-amendments.schema.json +178 -53
  8. package/dist/schemas/hdf-baseline.schema.json +181 -56
  9. package/dist/schemas/hdf-comparison.schema.json +523 -108
  10. package/dist/schemas/hdf-evidence-package.schema.json +175 -50
  11. package/dist/schemas/hdf-plan.schema.json +181 -56
  12. package/dist/schemas/hdf-results.schema.json +502 -87
  13. package/dist/schemas/hdf-system.schema.json +190 -65
  14. package/dist/ts/hdf-amendments.d.ts +43 -15
  15. package/dist/ts/hdf-amendments.js +18 -7
  16. package/dist/ts/hdf-amendments.ts +44 -15
  17. package/dist/ts/hdf-results.d.ts +91 -37
  18. package/dist/ts/hdf-results.js +40 -20
  19. package/dist/ts/hdf-results.ts +91 -36
  20. package/package.json +44 -44
  21. package/dist/python/hdf_amendments.py +0 -695
  22. package/dist/python/hdf_baseline.py +0 -782
  23. package/dist/python/hdf_comparison.py +0 -1771
  24. package/dist/python/hdf_evidence_package.py +0 -593
  25. package/dist/python/hdf_plan.py +0 -363
  26. package/dist/python/hdf_results.py +0 -2163
  27. package/dist/python/hdf_system.py +0 -904
  28. package/src/schemas/hdf-amendments.schema.json +0 -97
  29. package/src/schemas/hdf-baseline.schema.json +0 -190
  30. package/src/schemas/hdf-comparison.schema.json +0 -107
  31. package/src/schemas/hdf-evidence-package.schema.json +0 -227
  32. package/src/schemas/hdf-plan.schema.json +0 -92
  33. package/src/schemas/hdf-results.schema.json +0 -304
  34. package/src/schemas/hdf-system.schema.json +0 -136
  35. package/src/schemas/primitives/amendments.schema.json +0 -155
  36. package/src/schemas/primitives/common.schema.json +0 -814
  37. package/src/schemas/primitives/comparison.schema.json +0 -809
  38. package/src/schemas/primitives/component.schema.json +0 -518
  39. package/src/schemas/primitives/data-flow.schema.json +0 -158
  40. package/src/schemas/primitives/extensions.schema.json +0 -342
  41. package/src/schemas/primitives/parameter.schema.json +0 -128
  42. package/src/schemas/primitives/plan.schema.json +0 -128
  43. package/src/schemas/primitives/platform.schema.json +0 -32
  44. package/src/schemas/primitives/result.schema.json +0 -133
  45. package/src/schemas/primitives/runner.schema.json +0 -83
  46. package/src/schemas/primitives/statistics.schema.json +0 -71
  47. package/src/schemas/primitives/system.schema.json +0 -132
  48. package/src/schemas/primitives/target.schema.json +0 -523
@@ -1,782 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Optional, Any, List, Dict, Union, TypeVar, Callable, Type, cast
3
- from enum import Enum
4
-
5
-
6
- T = TypeVar("T")
7
- EnumT = TypeVar("EnumT", bound=Enum)
8
-
9
-
10
- def from_str(x: Any) -> str:
11
- assert isinstance(x, str)
12
- return x
13
-
14
-
15
- def from_none(x: Any) -> Any:
16
- assert x is None
17
- return x
18
-
19
-
20
- def from_union(fs, x):
21
- for f in fs:
22
- try:
23
- return f(x)
24
- except:
25
- pass
26
- assert False
27
-
28
-
29
- def from_list(f: Callable[[Any], T], x: Any) -> List[T]:
30
- assert isinstance(x, list)
31
- return [f(y) for y in x]
32
-
33
-
34
- def from_float(x: Any) -> float:
35
- assert isinstance(x, (float, int)) and not isinstance(x, bool)
36
- return float(x)
37
-
38
-
39
- def to_float(x: Any) -> float:
40
- assert isinstance(x, (int, float))
41
- return x
42
-
43
-
44
- def from_bool(x: Any) -> bool:
45
- assert isinstance(x, bool)
46
- return x
47
-
48
-
49
- def to_class(c: Type[T], x: Any) -> dict:
50
- assert isinstance(x, c)
51
- return cast(Any, x).to_dict()
52
-
53
-
54
- def to_enum(c: Type[EnumT], x: Any) -> EnumT:
55
- assert isinstance(x, c)
56
- return x.value
57
-
58
-
59
- def from_dict(f: Callable[[Any], T], x: Any) -> Dict[str, T]:
60
- assert isinstance(x, dict)
61
- return { k: f(v) for (k, v) in x.items() }
62
-
63
-
64
- @dataclass
65
- class Dependency:
66
- """A dependency for a baseline. Can include relative paths or URLs for where to find the
67
- dependency.
68
- """
69
- branch: Optional[str] = None
70
- """The branch name for a git repo."""
71
-
72
- compliance: Optional[str] = None
73
- """The 'user/profilename' attribute for an Automate server."""
74
-
75
- git: Optional[str] = None
76
- """The location of the git repo. Example:
77
- 'https://github.com/my-org/ubuntu-22.04-stig-baseline.git'.
78
- """
79
- name: Optional[str] = None
80
- """The name or assigned alias."""
81
-
82
- path: Optional[str] = None
83
- """The relative path if the dependency is locally available."""
84
-
85
- status: Optional[str] = None
86
- """The status. Should be: 'loaded', 'failed', or 'skipped'."""
87
-
88
- status_message: Optional[str] = None
89
- """The reason for the status if it is 'failed' or 'skipped'."""
90
-
91
- supermarket: Optional[str] = None
92
- """The 'user/profilename' attribute for a Supermarket server."""
93
-
94
- url: Optional[str] = None
95
- """The address of the dependency."""
96
-
97
- @staticmethod
98
- def from_dict(obj: Any) -> 'Dependency':
99
- assert isinstance(obj, dict)
100
- branch = from_union([from_str, from_none], obj.get("branch"))
101
- compliance = from_union([from_str, from_none], obj.get("compliance"))
102
- git = from_union([from_str, from_none], obj.get("git"))
103
- name = from_union([from_str, from_none], obj.get("name"))
104
- path = from_union([from_str, from_none], obj.get("path"))
105
- status = from_union([from_str, from_none], obj.get("status"))
106
- status_message = from_union([from_str, from_none], obj.get("statusMessage"))
107
- supermarket = from_union([from_str, from_none], obj.get("supermarket"))
108
- url = from_union([from_str, from_none], obj.get("url"))
109
- return Dependency(branch, compliance, git, name, path, status, status_message, supermarket, url)
110
-
111
- def to_dict(self) -> dict:
112
- result: dict = {}
113
- if self.branch is not None:
114
- result["branch"] = from_union([from_str, from_none], self.branch)
115
- if self.compliance is not None:
116
- result["compliance"] = from_union([from_str, from_none], self.compliance)
117
- if self.git is not None:
118
- result["git"] = from_union([from_str, from_none], self.git)
119
- if self.name is not None:
120
- result["name"] = from_union([from_str, from_none], self.name)
121
- if self.path is not None:
122
- result["path"] = from_union([from_str, from_none], self.path)
123
- if self.status is not None:
124
- result["status"] = from_union([from_str, from_none], self.status)
125
- if self.status_message is not None:
126
- result["statusMessage"] = from_union([from_str, from_none], self.status_message)
127
- if self.supermarket is not None:
128
- result["supermarket"] = from_union([from_str, from_none], self.supermarket)
129
- if self.url is not None:
130
- result["url"] = from_union([from_str, from_none], self.url)
131
- return result
132
-
133
-
134
- @dataclass
135
- class Generator:
136
- """The tool that generated this file.
137
-
138
- Information about the tool that generated this HDF file.
139
- """
140
- name: str
141
- """The name of the software that produced this HDF file. Example: 'gosec-to-hdf'."""
142
-
143
- version: str
144
- """The version of the tool. Example: '5.22.3'."""
145
-
146
- @staticmethod
147
- def from_dict(obj: Any) -> 'Generator':
148
- assert isinstance(obj, dict)
149
- name = from_str(obj.get("name"))
150
- version = from_str(obj.get("version"))
151
- return Generator(name, version)
152
-
153
- def to_dict(self) -> dict:
154
- result: dict = {}
155
- result["name"] = from_str(self.name)
156
- result["version"] = from_str(self.version)
157
- return result
158
-
159
-
160
- @dataclass
161
- class RequirementGroup:
162
- """Describes a group of requirements, such as those defined in a single file."""
163
-
164
- id: str
165
- """The unique identifier for the group. Example: the relative path to the file specifying
166
- the requirements.
167
- """
168
- requirements: List[str]
169
- """The set of requirements as specified by their ids in this group. Example: 'SV-238196'."""
170
-
171
- title: Optional[str] = None
172
- """The title of the group - should be human readable."""
173
-
174
- @staticmethod
175
- def from_dict(obj: Any) -> 'RequirementGroup':
176
- assert isinstance(obj, dict)
177
- id = from_str(obj.get("id"))
178
- requirements = from_list(from_str, obj.get("requirements"))
179
- title = from_union([from_str, from_none], obj.get("title"))
180
- return RequirementGroup(id, requirements, title)
181
-
182
- def to_dict(self) -> dict:
183
- result: dict = {}
184
- result["id"] = from_str(self.id)
185
- result["requirements"] = from_list(from_str, self.requirements)
186
- if self.title is not None:
187
- result["title"] = from_union([from_str, from_none], self.title)
188
- return result
189
-
190
-
191
- @dataclass
192
- class InputConstraints:
193
- """Validation constraints for the input value.
194
-
195
- Validation constraints for an input value.
196
- """
197
- allowed_values: Optional[List[Any]] = None
198
- """Enumeration of permitted values."""
199
-
200
- max: Optional[float] = None
201
- """Maximum allowed value (for Numeric inputs)."""
202
-
203
- min: Optional[float] = None
204
- """Minimum allowed value (for Numeric inputs)."""
205
-
206
- pattern: Optional[str] = None
207
- """Regular expression pattern the value must match (for String inputs)."""
208
-
209
- @staticmethod
210
- def from_dict(obj: Any) -> 'InputConstraints':
211
- assert isinstance(obj, dict)
212
- allowed_values = from_union([lambda x: from_list(lambda x: x, x), from_none], obj.get("allowedValues"))
213
- max = from_union([from_float, from_none], obj.get("max"))
214
- min = from_union([from_float, from_none], obj.get("min"))
215
- pattern = from_union([from_str, from_none], obj.get("pattern"))
216
- return InputConstraints(allowed_values, max, min, pattern)
217
-
218
- def to_dict(self) -> dict:
219
- result: dict = {}
220
- if self.allowed_values is not None:
221
- result["allowedValues"] = from_union([lambda x: from_list(lambda x: x, x), from_none], self.allowed_values)
222
- if self.max is not None:
223
- result["max"] = from_union([to_float, from_none], self.max)
224
- if self.min is not None:
225
- result["min"] = from_union([to_float, from_none], self.min)
226
- if self.pattern is not None:
227
- result["pattern"] = from_union([from_str, from_none], self.pattern)
228
- return result
229
-
230
-
231
- class ComparisonOperator(Enum):
232
- """The comparison operator used when evaluating this input against observed values.
233
-
234
- Comparison operator for evaluating the input value against observed values. Numeric:
235
- eq/ne/lt/le/gt/ge. String: eq/ne/contains/matches. Collection: in/notIn.
236
- """
237
- CONTAINS = "contains"
238
- EQ = "eq"
239
- GE = "ge"
240
- GT = "gt"
241
- IN = "in"
242
- LE = "le"
243
- LT = "lt"
244
- MATCHES = "matches"
245
- NE = "ne"
246
- NOT_IN = "notIn"
247
-
248
-
249
- class InputType(Enum):
250
- """The data type of this input.
251
-
252
- The data type of the input value. Aligns with InSpec input types.
253
- """
254
- ARRAY = "Array"
255
- BOOLEAN = "Boolean"
256
- HASH = "Hash"
257
- NUMERIC = "Numeric"
258
- REGEXP = "Regexp"
259
- STRING = "String"
260
-
261
-
262
- @dataclass
263
- class Input:
264
- """A typed input parameter that bridges governance requirements and scanner automation.
265
- Inputs carry expected configuration values with type information, comparison operators,
266
- and validation constraints, enabling traceability from policy through to scan results.
267
- """
268
- name: str
269
- """The input name. Must be unique within a baseline or results document. Example:
270
- 'max_concurrent_sessions'.
271
- """
272
- constraints: Optional[InputConstraints] = None
273
- """Validation constraints for the input value."""
274
-
275
- description: Optional[str] = None
276
- """Human-readable description of what this input controls."""
277
-
278
- operator: Optional[ComparisonOperator] = None
279
- """The comparison operator used when evaluating this input against observed values."""
280
-
281
- required: Optional[bool] = None
282
- """Whether this input must be provided. Defaults to false if omitted."""
283
-
284
- sensitive: Optional[bool] = None
285
- """Whether this input contains sensitive data (passwords, keys). Sensitive values should be
286
- redacted in output. Defaults to false if omitted.
287
- """
288
- type: Optional[InputType] = None
289
- """The data type of this input."""
290
-
291
- value: Any
292
- """The input value. Type should match the declared type field. Accepts any JSON value."""
293
-
294
- @staticmethod
295
- def from_dict(obj: Any) -> 'Input':
296
- assert isinstance(obj, dict)
297
- name = from_str(obj.get("name"))
298
- constraints = from_union([InputConstraints.from_dict, from_none], obj.get("constraints"))
299
- description = from_union([from_str, from_none], obj.get("description"))
300
- operator = from_union([ComparisonOperator, from_none], obj.get("operator"))
301
- required = from_union([from_bool, from_none], obj.get("required"))
302
- sensitive = from_union([from_bool, from_none], obj.get("sensitive"))
303
- type = from_union([InputType, from_none], obj.get("type"))
304
- value = obj.get("value")
305
- return Input(name, constraints, description, operator, required, sensitive, type, value)
306
-
307
- def to_dict(self) -> dict:
308
- result: dict = {}
309
- result["name"] = from_str(self.name)
310
- if self.constraints is not None:
311
- result["constraints"] = from_union([lambda x: to_class(InputConstraints, x), from_none], self.constraints)
312
- if self.description is not None:
313
- result["description"] = from_union([from_str, from_none], self.description)
314
- if self.operator is not None:
315
- result["operator"] = from_union([lambda x: to_enum(ComparisonOperator, x), from_none], self.operator)
316
- if self.required is not None:
317
- result["required"] = from_union([from_bool, from_none], self.required)
318
- if self.sensitive is not None:
319
- result["sensitive"] = from_union([from_bool, from_none], self.sensitive)
320
- if self.type is not None:
321
- result["type"] = from_union([lambda x: to_enum(InputType, x), from_none], self.type)
322
- if self.value is not None:
323
- result["value"] = self.value
324
- return result
325
-
326
-
327
- class HashAlgorithm(Enum):
328
- """The hash algorithm used for the checksum.
329
-
330
- Supported cryptographic hash algorithms for checksums and integrity verification.
331
- """
332
- SHA256 = "sha256"
333
- SHA384 = "sha384"
334
- SHA512 = "sha512"
335
-
336
-
337
- @dataclass
338
- class Integrity:
339
- """Cryptographic integrity information for verifying this baseline has not been tampered
340
- with.
341
-
342
- Cryptographic integrity information for verifying the HDF file has not been tampered
343
- with. If algorithm is provided, checksum must also be provided, and vice versa.
344
- """
345
- algorithm: Optional[HashAlgorithm] = None
346
- """The hash algorithm used for the checksum."""
347
-
348
- checksum: Optional[str] = None
349
- """The checksum value."""
350
-
351
- signature: Optional[str] = None
352
- """Optional cryptographic signature."""
353
-
354
- signed_by: Optional[str] = None
355
- """Identifier of who signed this file."""
356
-
357
- @staticmethod
358
- def from_dict(obj: Any) -> 'Integrity':
359
- assert isinstance(obj, dict)
360
- algorithm = from_union([HashAlgorithm, from_none], obj.get("algorithm"))
361
- checksum = from_union([from_str, from_none], obj.get("checksum"))
362
- signature = from_union([from_str, from_none], obj.get("signature"))
363
- signed_by = from_union([from_str, from_none], obj.get("signedBy"))
364
- return Integrity(algorithm, checksum, signature, signed_by)
365
-
366
- def to_dict(self) -> dict:
367
- result: dict = {}
368
- if self.algorithm is not None:
369
- result["algorithm"] = from_union([lambda x: to_enum(HashAlgorithm, x), from_none], self.algorithm)
370
- if self.checksum is not None:
371
- result["checksum"] = from_union([from_str, from_none], self.checksum)
372
- if self.signature is not None:
373
- result["signature"] = from_union([from_str, from_none], self.signature)
374
- if self.signed_by is not None:
375
- result["signedBy"] = from_union([from_str, from_none], self.signed_by)
376
- return result
377
-
378
-
379
- @dataclass
380
- class Checksum:
381
- """Optional cryptographic checksum for verifying the integrity of remediation resources
382
- fetched from the URI. Recommended for security when referencing external automation
383
- scripts.
384
-
385
- Cryptographic checksum for baseline integrity verification.
386
- """
387
- algorithm: HashAlgorithm
388
- """The hash algorithm used for the checksum."""
389
-
390
- value: str
391
- """The checksum value."""
392
-
393
- @staticmethod
394
- def from_dict(obj: Any) -> 'Checksum':
395
- assert isinstance(obj, dict)
396
- algorithm = HashAlgorithm(obj.get("algorithm"))
397
- value = from_str(obj.get("value"))
398
- return Checksum(algorithm, value)
399
-
400
- def to_dict(self) -> dict:
401
- result: dict = {}
402
- result["algorithm"] = to_enum(HashAlgorithm, self.algorithm)
403
- result["value"] = from_str(self.value)
404
- return result
405
-
406
-
407
- @dataclass
408
- class Remediation:
409
- """Optional reference to automated remediation resources (Ansible playbooks, Terraform
410
- scripts, etc.) for implementing the security controls defined in this baseline.
411
-
412
- Reference to automated remediation resources for implementing security controls. Points
413
- to external automation content like Ansible playbooks, Terraform scripts, or
414
- vendor-provided remediation tools.
415
- """
416
- uri: str
417
- """URI pointing to automated remediation resources (Ansible playbooks, Terraform scripts,
418
- etc.). Examples: GitHub repository, DISA STIG Supplemental Automation Content,
419
- vendor-provided scripts.
420
- """
421
- checksum: Optional[Checksum] = None
422
- """Optional cryptographic checksum for verifying the integrity of remediation resources
423
- fetched from the URI. Recommended for security when referencing external automation
424
- scripts.
425
- """
426
-
427
- @staticmethod
428
- def from_dict(obj: Any) -> 'Remediation':
429
- assert isinstance(obj, dict)
430
- uri = from_str(obj.get("uri"))
431
- checksum = from_union([Checksum.from_dict, from_none], obj.get("checksum"))
432
- return Remediation(uri, checksum)
433
-
434
- def to_dict(self) -> dict:
435
- result: dict = {}
436
- result["uri"] = from_str(self.uri)
437
- if self.checksum is not None:
438
- result["checksum"] = from_union([lambda x: to_class(Checksum, x), from_none], self.checksum)
439
- return result
440
-
441
-
442
- @dataclass
443
- class Description:
444
- data: str
445
- """The description text content."""
446
-
447
- label: str
448
- """Description category. The 'default' label is required for the primary description. Common
449
- labels: 'default', 'check', 'fix', 'rationale'. Tools may use custom labels.
450
- """
451
-
452
- @staticmethod
453
- def from_dict(obj: Any) -> 'Description':
454
- assert isinstance(obj, dict)
455
- data = from_str(obj.get("data"))
456
- label = from_str(obj.get("label"))
457
- return Description(data, label)
458
-
459
- def to_dict(self) -> dict:
460
- result: dict = {}
461
- result["data"] = from_str(self.data)
462
- result["label"] = from_str(self.label)
463
- return result
464
-
465
-
466
- @dataclass
467
- class Reference:
468
- """A reference to an external document.
469
-
470
- A reference using the 'ref' field.
471
-
472
- A URL pointing at the reference.
473
-
474
- A URI pointing at the reference.
475
- """
476
- ref: Optional[Union[List[Dict[str, Any]], str]] = None
477
- url: Optional[str] = None
478
- uri: Optional[str] = None
479
-
480
- @staticmethod
481
- def from_dict(obj: Any) -> 'Reference':
482
- assert isinstance(obj, dict)
483
- ref = from_union([lambda x: from_list(lambda x: from_dict(lambda x: x, x), x), from_str, from_none], obj.get("ref"))
484
- url = from_union([from_str, from_none], obj.get("url"))
485
- uri = from_union([from_str, from_none], obj.get("uri"))
486
- return Reference(ref, url, uri)
487
-
488
- def to_dict(self) -> dict:
489
- result: dict = {}
490
- if self.ref is not None:
491
- result["ref"] = from_union([lambda x: from_list(lambda x: from_dict(lambda x: x, x), x), from_str, from_none], self.ref)
492
- if self.url is not None:
493
- result["url"] = from_union([from_str, from_none], self.url)
494
- if self.uri is not None:
495
- result["uri"] = from_union([from_str, from_none], self.uri)
496
- return result
497
-
498
-
499
- class Severity(Enum):
500
- """Explicit severity rating. Typically derived from impact score but provided explicitly for
501
- clarity.
502
-
503
- Severity rating for a requirement. Typically derived from the numeric impact score.
504
- """
505
- CRITICAL = "critical"
506
- HIGH = "high"
507
- INFORMATIONAL = "informational"
508
- LOW = "low"
509
- MEDIUM = "medium"
510
-
511
-
512
- @dataclass
513
- class SourceLocation:
514
- """The explicit location of the requirement within the source code.
515
-
516
- The explicit location of a requirement within source code.
517
- """
518
- line: Optional[float] = None
519
- """The line on which this requirement is located."""
520
-
521
- ref: Optional[str] = None
522
- """Path to the file that this requirement originates from."""
523
-
524
- @staticmethod
525
- def from_dict(obj: Any) -> 'SourceLocation':
526
- assert isinstance(obj, dict)
527
- line = from_union([from_float, from_none], obj.get("line"))
528
- ref = from_union([from_str, from_none], obj.get("ref"))
529
- return SourceLocation(line, ref)
530
-
531
- def to_dict(self) -> dict:
532
- result: dict = {}
533
- if self.line is not None:
534
- result["line"] = from_union([to_float, from_none], self.line)
535
- if self.ref is not None:
536
- result["ref"] = from_union([from_str, from_none], self.ref)
537
- return result
538
-
539
-
540
- @dataclass
541
- class BaselineRequirement:
542
- """A requirement definition without assessment results.
543
-
544
- Core requirement fields shared between baseline requirements and evaluated requirements.
545
- Contains the fundamental requirement definition without assessment results.
546
- """
547
- descriptions: List[Description]
548
- """Array of labeled descriptions. At least one description with label 'default' must be
549
- present. Convention: place default description first. Common labels: 'default', 'check',
550
- 'fix', 'rationale'.
551
- """
552
- id: str
553
- """The requirement identifier. Example: 'SV-238196'."""
554
-
555
- impact: float
556
- """The impactfulness or severity (0.0 to 1.0)."""
557
-
558
- tags: Dict[str, Any]
559
- """A set of tags - usually metadata like CCI, STIG ID, severity."""
560
-
561
- severity: Optional[Severity] = None
562
- """Explicit severity rating. Typically derived from impact score but provided explicitly for
563
- clarity.
564
- """
565
- code: Optional[str] = None
566
- """The raw source code of the requirement. Set to null for manual-only requirements or
567
- requirements not yet implemented. Note that if this is an overlay, it does not include
568
- the underlying source code.
569
- """
570
- refs: Optional[List[Reference]] = None
571
- """The set of references to external documents."""
572
-
573
- source_location: Optional[SourceLocation] = None
574
- """The explicit location of the requirement within the source code."""
575
-
576
- title: Optional[str] = None
577
- """The title - is nullable."""
578
-
579
- @staticmethod
580
- def from_dict(obj: Any) -> 'BaselineRequirement':
581
- assert isinstance(obj, dict)
582
- descriptions = from_list(Description.from_dict, obj.get("descriptions"))
583
- id = from_str(obj.get("id"))
584
- impact = from_float(obj.get("impact"))
585
- tags = from_dict(lambda x: x, obj.get("tags"))
586
- severity = from_union([Severity, from_none], obj.get("severity"))
587
- code = from_union([from_str, from_none], obj.get("code"))
588
- refs = from_union([lambda x: from_list(Reference.from_dict, x), from_none], obj.get("refs"))
589
- source_location = from_union([SourceLocation.from_dict, from_none], obj.get("sourceLocation"))
590
- title = from_union([from_str, from_none], obj.get("title"))
591
- return BaselineRequirement(descriptions, id, impact, tags, severity, code, refs, source_location, title)
592
-
593
- def to_dict(self) -> dict:
594
- result: dict = {}
595
- result["descriptions"] = from_list(lambda x: to_class(Description, x), self.descriptions)
596
- result["id"] = from_str(self.id)
597
- result["impact"] = to_float(self.impact)
598
- result["tags"] = from_dict(lambda x: x, self.tags)
599
- if self.severity is not None:
600
- result["severity"] = from_union([lambda x: to_enum(Severity, x), from_none], self.severity)
601
- if self.code is not None:
602
- result["code"] = from_union([from_str, from_none], self.code)
603
- if self.refs is not None:
604
- result["refs"] = from_union([lambda x: from_list(lambda x: to_class(Reference, x), x), from_none], self.refs)
605
- if self.source_location is not None:
606
- result["sourceLocation"] = from_union([lambda x: to_class(SourceLocation, x), from_none], self.source_location)
607
- if self.title is not None:
608
- result["title"] = from_union([from_str, from_none], self.title)
609
- return result
610
-
611
-
612
- @dataclass
613
- class SupportedPlatform:
614
- """A supported platform target. Example: the platform name being 'ubuntu'."""
615
-
616
- platform: Optional[str] = None
617
- """The location of the platform. Can be: 'os', 'aws', 'azure', or 'gcp'."""
618
-
619
- platform_family: Optional[str] = None
620
- """The platform family. Example: 'redhat'."""
621
-
622
- platform_name: Optional[str] = None
623
- """The platform name - can include wildcards. Example: 'debian'."""
624
-
625
- release: Optional[str] = None
626
- """The release of the platform. Example: '20.04' for 'ubuntu'."""
627
-
628
- @staticmethod
629
- def from_dict(obj: Any) -> 'SupportedPlatform':
630
- assert isinstance(obj, dict)
631
- platform = from_union([from_str, from_none], obj.get("platform"))
632
- platform_family = from_union([from_str, from_none], obj.get("platformFamily"))
633
- platform_name = from_union([from_str, from_none], obj.get("platformName"))
634
- release = from_union([from_str, from_none], obj.get("release"))
635
- return SupportedPlatform(platform, platform_family, platform_name, release)
636
-
637
- def to_dict(self) -> dict:
638
- result: dict = {}
639
- if self.platform is not None:
640
- result["platform"] = from_union([from_str, from_none], self.platform)
641
- if self.platform_family is not None:
642
- result["platformFamily"] = from_union([from_str, from_none], self.platform_family)
643
- if self.platform_name is not None:
644
- result["platformName"] = from_union([from_str, from_none], self.platform_name)
645
- if self.release is not None:
646
- result["release"] = from_union([from_str, from_none], self.release)
647
- return result
648
-
649
-
650
- @dataclass
651
- class HdfBaseline:
652
- """Information on the set of requirements that can be assessed, including baseline metadata
653
- and requirement definitions.
654
-
655
- Shared metadata fields for baselines. Used in both standalone baseline documents and
656
- evaluated baseline results.
657
- """
658
- requirements: List[BaselineRequirement]
659
- """The set of requirements - contains no findings as the assessment has not yet occurred."""
660
-
661
- name: str
662
- """The name - must be unique."""
663
-
664
- depends: Optional[List[Dependency]] = None
665
- """The set of dependencies this baseline depends on."""
666
-
667
- generator: Optional[Generator] = None
668
- """The tool that generated this file."""
669
-
670
- groups: Optional[List[RequirementGroup]] = None
671
- """A set of descriptions for the requirement groups."""
672
-
673
- inputs: Optional[List[Input]] = None
674
- """The input(s) or attribute(s) to be used in the run."""
675
-
676
- integrity: Optional[Integrity] = None
677
- """Cryptographic integrity information for verifying this baseline has not been tampered
678
- with.
679
- """
680
- remediation: Optional[Remediation] = None
681
- """Optional reference to automated remediation resources (Ansible playbooks, Terraform
682
- scripts, etc.) for implementing the security controls defined in this baseline.
683
- """
684
- copyright: Optional[str] = None
685
- """The copyright holder(s)."""
686
-
687
- copyright_email: Optional[str] = None
688
- """The email address or other contact information of the copyright holder(s)."""
689
-
690
- labels: Optional[Dict[str, str]] = None
691
- """Optional key-value labels for flexible grouping. Well-known keys: system, component,
692
- environment, region, team. Values must be strings.
693
- """
694
- license: Optional[str] = None
695
- """The copyright license. Example: 'Apache-2.0'."""
696
-
697
- maintainer: Optional[str] = None
698
- """The maintainer(s)."""
699
-
700
- status: Optional[str] = None
701
- """The status. Example: 'loaded'."""
702
-
703
- summary: Optional[str] = None
704
- """The summary. Example: the Security Technical Implementation Guide (STIG) header."""
705
-
706
- supports: Optional[List[SupportedPlatform]] = None
707
- """The set of supported platform targets."""
708
-
709
- title: Optional[str] = None
710
- """The title - should be human readable."""
711
-
712
- version: Optional[str] = None
713
- """The version of the baseline."""
714
-
715
- @staticmethod
716
- def from_dict(obj: Any) -> 'HdfBaseline':
717
- assert isinstance(obj, dict)
718
- requirements = from_list(BaselineRequirement.from_dict, obj.get("requirements"))
719
- name = from_str(obj.get("name"))
720
- depends = from_union([lambda x: from_list(Dependency.from_dict, x), from_none], obj.get("depends"))
721
- generator = from_union([Generator.from_dict, from_none], obj.get("generator"))
722
- groups = from_union([lambda x: from_list(RequirementGroup.from_dict, x), from_none], obj.get("groups"))
723
- inputs = from_union([lambda x: from_list(Input.from_dict, x), from_none], obj.get("inputs"))
724
- integrity = from_union([Integrity.from_dict, from_none], obj.get("integrity"))
725
- remediation = from_union([Remediation.from_dict, from_none], obj.get("remediation"))
726
- copyright = from_union([from_str, from_none], obj.get("copyright"))
727
- copyright_email = from_union([from_str, from_none], obj.get("copyrightEmail"))
728
- labels = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("labels"))
729
- license = from_union([from_str, from_none], obj.get("license"))
730
- maintainer = from_union([from_str, from_none], obj.get("maintainer"))
731
- status = from_union([from_str, from_none], obj.get("status"))
732
- summary = from_union([from_str, from_none], obj.get("summary"))
733
- supports = from_union([lambda x: from_list(SupportedPlatform.from_dict, x), from_none], obj.get("supports"))
734
- title = from_union([from_str, from_none], obj.get("title"))
735
- version = from_union([from_str, from_none], obj.get("version"))
736
- return HdfBaseline(requirements, name, depends, generator, groups, inputs, integrity, remediation, copyright, copyright_email, labels, license, maintainer, status, summary, supports, title, version)
737
-
738
- def to_dict(self) -> dict:
739
- result: dict = {}
740
- result["requirements"] = from_list(lambda x: to_class(BaselineRequirement, x), self.requirements)
741
- result["name"] = from_str(self.name)
742
- if self.depends is not None:
743
- result["depends"] = from_union([lambda x: from_list(lambda x: to_class(Dependency, x), x), from_none], self.depends)
744
- if self.generator is not None:
745
- result["generator"] = from_union([lambda x: to_class(Generator, x), from_none], self.generator)
746
- if self.groups is not None:
747
- result["groups"] = from_union([lambda x: from_list(lambda x: to_class(RequirementGroup, x), x), from_none], self.groups)
748
- if self.inputs is not None:
749
- result["inputs"] = from_union([lambda x: from_list(lambda x: to_class(Input, x), x), from_none], self.inputs)
750
- if self.integrity is not None:
751
- result["integrity"] = from_union([lambda x: to_class(Integrity, x), from_none], self.integrity)
752
- if self.remediation is not None:
753
- result["remediation"] = from_union([lambda x: to_class(Remediation, x), from_none], self.remediation)
754
- if self.copyright is not None:
755
- result["copyright"] = from_union([from_str, from_none], self.copyright)
756
- if self.copyright_email is not None:
757
- result["copyrightEmail"] = from_union([from_str, from_none], self.copyright_email)
758
- if self.labels is not None:
759
- result["labels"] = from_union([lambda x: from_dict(from_str, x), from_none], self.labels)
760
- if self.license is not None:
761
- result["license"] = from_union([from_str, from_none], self.license)
762
- if self.maintainer is not None:
763
- result["maintainer"] = from_union([from_str, from_none], self.maintainer)
764
- if self.status is not None:
765
- result["status"] = from_union([from_str, from_none], self.status)
766
- if self.summary is not None:
767
- result["summary"] = from_union([from_str, from_none], self.summary)
768
- if self.supports is not None:
769
- result["supports"] = from_union([lambda x: from_list(lambda x: to_class(SupportedPlatform, x), x), from_none], self.supports)
770
- if self.title is not None:
771
- result["title"] = from_union([from_str, from_none], self.title)
772
- if self.version is not None:
773
- result["version"] = from_union([from_str, from_none], self.version)
774
- return result
775
-
776
-
777
- def hdf_baseline_from_dict(s: Any) -> HdfBaseline:
778
- return HdfBaseline.from_dict(s)
779
-
780
-
781
- def hdf_baseline_to_dict(x: HdfBaseline) -> Any:
782
- return to_class(HdfBaseline, x)