Schema/comparison.schema.json

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/xGreeny/hardening-lens/v1.3.0/src/HardeningLens/Schema/comparison.schema.json",
  "title": "Hardening Lens drift comparison",
  "type": "object",
  "required": [
    "schemaVersion",
    "comparedAt",
    "computerName",
    "baseline",
    "baselineContext",
    "catalogContext",
    "referenceScan",
    "differenceScan",
    "summary",
    "changes"
  ],
  "properties": {
    "$schema": {
      "type": "string"
    },
    "schemaVersion": {
      "const": "1.1"
    },
    "comparedAt": {
      "type": "string",
      "format": "date-time"
    },
    "computerName": {
      "type": "string"
    },
    "baseline": {
      "type": "string"
    },
    "baselineContext": {
      "$ref": "#/$defs/baselineContext"
    },
    "catalogContext": {
      "$ref": "#/$defs/catalogContext"
    },
    "referenceScan": {
      "$ref": "#/$defs/scanRef"
    },
    "differenceScan": {
      "$ref": "#/$defs/scanRef"
    },
    "summary": {
      "type": "object",
      "required": [
        "ScoreDelta",
        "CoverageDelta",
        "NewFindings",
        "Resolved",
        "Changed",
        "AddedControls",
        "RemovedControls",
        "Unchanged"
      ],
      "properties": {
        "ScoreDelta": {
          "type": [
            "number",
            "null"
          ]
        },
        "CoverageDelta": {
          "type": [
            "number",
            "null"
          ]
        },
        "NewFindings": {
          "type": "integer",
          "minimum": 0
        },
        "Resolved": {
          "type": "integer",
          "minimum": 0
        },
        "Changed": {
          "type": "integer",
          "minimum": 0
        },
        "AddedControls": {
          "type": "integer",
          "minimum": 0
        },
        "RemovedControls": {
          "type": "integer",
          "minimum": 0
        },
        "Unchanged": {
          "type": "integer",
          "minimum": 0
        }
      },
      "additionalProperties": false
    },
    "changes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "ControlId",
          "Title",
          "Severity",
          "Category",
          "ChangeType",
          "ChangedFields",
          "Before",
          "After",
          "BeforeStatus",
          "AfterStatus",
          "BeforeActual",
          "AfterActual"
        ],
        "properties": {
          "ControlId": {
            "type": "string",
            "pattern": "^HL-[A-Z]+-[0-9]{3}$"
          },
          "Title": {
            "type": "string"
          },
          "Severity": {
            "$ref": "#/$defs/severity"
          },
          "Category": {
            "type": "string"
          },
          "ChangeType": {
            "enum": [
              "Unchanged",
              "NewFinding",
              "Resolved",
              "Changed",
              "AddedControl",
              "RemovedControl"
            ]
          },
          "ChangedFields": {
            "type": "array",
            "items": {
              "enum": [
                "Presence",
                "Status",
                "Severity",
                "Expected",
                "Actual",
                "Evidence",
                "Exception"
              ]
            },
            "uniqueItems": true
          },
          "Before": {
            "oneOf": [
              {
                "$ref": "#/$defs/stateSnapshot"
              },
              {
                "type": "null"
              }
            ]
          },
          "After": {
            "oneOf": [
              {
                "$ref": "#/$defs/stateSnapshot"
              },
              {
                "type": "null"
              }
            ]
          },
          "BeforeStatus": {
            "oneOf": [
              {
                "$ref": "#/$defs/status"
              },
              {
                "type": "null"
              }
            ]
          },
          "AfterStatus": {
            "oneOf": [
              {
                "$ref": "#/$defs/status"
              },
              {
                "type": "null"
              }
            ]
          },
          "BeforeActual": {},
          "AfterActual": {}
        },
        "additionalProperties": false
      }
    }
  },
  "$defs": {
    "status": {
      "enum": [
        "Pass",
        "Fail",
        "Warning",
        "Excepted",
        "Unknown",
        "Error",
        "NotApplicable"
      ]
    },
    "severity": {
      "enum": [
        "Critical",
        "High",
        "Medium",
        "Low",
        "Informational"
      ]
    },
    "nullableDigest": {
      "type": [
        "string",
        "null"
      ],
      "pattern": "^[a-f0-9]{64}$"
    },
    "baselineRef": {
      "type": "object",
      "required": [
        "Name",
        "Version",
        "Digest"
      ],
      "properties": {
        "Name": {
          "type": "string"
        },
        "Version": {
          "type": "string",
          "pattern": "^\\d+\\.\\d+\\.\\d+$"
        },
        "Digest": {
          "$ref": "#/$defs/nullableDigest"
        }
      },
      "additionalProperties": false
    },
    "catalogRef": {
      "type": "object",
      "required": [
        "Version",
        "Digest"
      ],
      "properties": {
        "Version": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^\\d+\\.\\d+\\.\\d+$"
        },
        "Digest": {
          "$ref": "#/$defs/nullableDigest"
        }
      },
      "additionalProperties": false
    },
    "baselineContext": {
      "type": "object",
      "required": [
        "Reference",
        "Difference",
        "Changed"
      ],
      "properties": {
        "Reference": {
          "$ref": "#/$defs/baselineRef"
        },
        "Difference": {
          "$ref": "#/$defs/baselineRef"
        },
        "Changed": {
          "type": "boolean"
        }
      },
      "additionalProperties": false
    },
    "catalogContext": {
      "type": "object",
      "required": [
        "Reference",
        "Difference",
        "Changed"
      ],
      "properties": {
        "Reference": {
          "$ref": "#/$defs/catalogRef"
        },
        "Difference": {
          "$ref": "#/$defs/catalogRef"
        },
        "Changed": {
          "type": "boolean"
        }
      },
      "additionalProperties": false
    },
    "capability": {
      "type": "object",
      "required": [
        "name",
        "available",
        "detail"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "available": {
          "type": "boolean"
        },
        "detail": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "additionalProperties": false
    },
    "scanRef": {
      "type": "object",
      "required": [
        "Id",
        "CollectedAt",
        "ResultSchemaVersion",
        "ModuleVersion",
        "Score",
        "EvidenceCoverage",
        "CollectionDurationMs",
        "ExceptionDigest",
        "Capabilities"
      ],
      "properties": {
        "Id": {
          "type": "string",
          "format": "uuid"
        },
        "CollectedAt": {
          "type": "string",
          "format": "date-time"
        },
        "ResultSchemaVersion": {
          "enum": [
            "1.0",
            "1.1"
          ]
        },
        "ModuleVersion": {
          "type": "string",
          "pattern": "^\\d+\\.\\d+\\.\\d+$"
        },
        "Score": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 100
        },
        "EvidenceCoverage": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 100
        },
        "CollectionDurationMs": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0
        },
        "ExceptionDigest": {
          "$ref": "#/$defs/nullableDigest"
        },
        "Capabilities": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/capability"
          }
        }
      },
      "additionalProperties": false
    },
    "stateSnapshot": {
      "type": "object",
      "required": [
        "Status",
        "Severity",
        "Expected",
        "Actual",
        "Evidence",
        "Exception"
      ],
      "properties": {
        "Status": {
          "$ref": "#/$defs/status"
        },
        "Severity": {
          "$ref": "#/$defs/severity"
        },
        "Expected": {},
        "Actual": {},
        "Evidence": {},
        "Exception": {
          "type": [
            "object",
            "null"
          ]
        }
      },
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}