{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "DetectionRule",
  "description": "JSON schema for a Scanner detection rule.",
  "type": "object",
  "required": [
    "description",
    "name",
    "query_text",
    "run_frequency_s",
    "time_range_s"
  ],
  "properties": {
    "alert_per_row": {
      "description": "Whether to send one alert per row of the results table, instead of a single alert containing the (truncated) results table. Defaults to false.",
      "default": false,
      "type": "boolean"
    },
    "alert_template": {
      "description": "Formatting template for the detection event",
      "anyOf": [
        {
          "$ref": "#/definitions/DetectionAlertTemplateTypes"
        },
        {
          "type": "null"
        }
      ]
    },
    "debounce": {
      "description": "Whether to debounce if a detection event is detected in two overlapping time ranges.",
      "default": true,
      "type": "boolean"
    },
    "dedup_window_s": {
      "description": "The dedup window for the detection rule, in seconds. Events created by this detection rule with exactly-identical values for the dedup keys will be deduplicated, if sent within this amount of time of each other. If not specified, the dedup window is the same as the run frequency. The deduped values are the _output_ values of the alert template.",
      "type": [
        "integer",
        "null"
      ],
      "format": "uint32",
      "minimum": 0.0
    },
    "description": {
      "description": "Description of the detection rule.",
      "type": "string"
    },
    "enabled": {
      "description": "Whether the detection rule is enabled.",
      "default": null,
      "anyOf": [
        {
          "$ref": "#/definitions/DetectionRuleState"
        },
        {
          "type": "null"
        }
      ]
    },
    "event_sink_keys": {
      "description": "Event sinks to send detection events to.",
      "default": [],
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "name": {
      "description": "Name of the detection rule.",
      "type": "string"
    },
    "push_key": {
      "description": "Stable, user-chosen identifier for this rule within its tenant. Used by single-rule upsert endpoints (e.g. `upsert_detection_rule_from_yaml`) to look up the existing [`DetectionRule`] to update; ignored by the GitHub-zipball sync path, which synthesizes its own key from the file path.\n\nAccepts both `push_key` (preferred) and the legacy `sync_key` scanner-cli spelling on the wire.",
      "default": null,
      "type": [
        "string",
        "null"
      ]
    },
    "query_text": {
      "description": "Query for the detection rule.",
      "type": "string"
    },
    "run_frequency_s": {
      "description": "How frequently to run the detection rule, in seconds. `run_frequency_s` must be minute granularity and <= `time_range_s`.",
      "type": "integer",
      "format": "uint32",
      "minimum": 60.0
    },
    "severity": {
      "description": "The severity of the detection. Scanner uses OCSF Severity ID standards for severity tags.",
      "default": "Unknown",
      "allOf": [
        {
          "$ref": "#/definitions/DetectionSeverity"
        }
      ]
    },
    "tags": {
      "description": "Tags for the detection rule.",
      "default": [],
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "tests": {
      "description": "Test to run on the detection rule.",
      "default": [],
      "type": "array",
      "items": {
        "$ref": "#/definitions/DetectionRuleTest"
      }
    },
    "time_range_s": {
      "description": "Lookback period for the detection rule, in seconds. `time_range_s` must be minute granularity.",
      "type": "integer",
      "format": "uint32",
      "minimum": 60.0
    }
  },
  "definitions": {
    "DeprecatedDetectionAlertTemplate": {
      "description": "Deprecated detection alert template where label/values are represented by string pairs.",
      "type": "object",
      "properties": {
        "actions": {
          "default": [],
          "type": "array",
          "items": {
            "type": "array",
            "items": [
              {
                "type": "string"
              },
              {
                "type": "string"
              }
            ],
            "maxItems": 2,
            "minItems": 2
          }
        },
        "info": {
          "default": [],
          "type": "array",
          "items": {
            "type": "array",
            "items": [
              {
                "type": "string"
              },
              {
                "type": "string"
              }
            ],
            "maxItems": 2,
            "minItems": 2
          }
        }
      }
    },
    "DetectionAlertTemplate": {
      "description": "Detection alert template using `TemplateEntry` types.",
      "type": "object",
      "properties": {
        "actions": {
          "default": [],
          "type": "array",
          "items": {
            "$ref": "#/definitions/TemplateEntry"
          }
        },
        "info": {
          "default": [],
          "type": "array",
          "items": {
            "$ref": "#/definitions/TemplateEntryWithDedup"
          }
        }
      }
    },
    "DetectionAlertTemplateTypes": {
      "anyOf": [
        {
          "$ref": "#/definitions/DeprecatedDetectionAlertTemplate"
        },
        {
          "$ref": "#/definitions/DetectionAlertTemplate"
        }
      ]
    },
    "DetectionRuleState": {
      "type": "string",
      "enum": [
        "Active",
        "Staging",
        "Paused"
      ]
    },
    "DetectionRuleTest": {
      "description": "Test to run on a detection rule.",
      "type": "object",
      "required": [
        "dataset_inline",
        "expected_detection_result",
        "name"
      ],
      "properties": {
        "dataset_inline": {
          "description": "The dataset to run on the detection rule (e.g. a list of log events).",
          "type": "string"
        },
        "expected_detection_result": {
          "description": "Whether the given dataset triggers a detection event.",
          "type": "boolean"
        },
        "name": {
          "description": "Name of the detection rule test.",
          "type": "string"
        },
        "now_timestamp": {
          "description": "Timestamp to start the detection rule test.",
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "DetectionSeverity": {
      "description": "The severity of a detection rule. Uses the OCSF severity schema for detection findings. In particular, uses the integer and string representations of the severity levels as described in the OCSF schema spec here: <https://schema.ocsf.io/1.1.0/classes/detection_finding>",
      "oneOf": [
        {
          "description": "The event/finding severity is unknown.",
          "type": "string",
          "enum": [
            "Unknown"
          ]
        },
        {
          "description": "Informational message. No action required.",
          "type": "string",
          "enum": [
            "Informational"
          ]
        },
        {
          "description": "The user decides if action is needed.",
          "type": "string",
          "enum": [
            "Low"
          ]
        },
        {
          "description": "Action is required but the situation is not serious at this time.",
          "type": "string",
          "enum": [
            "Medium"
          ]
        },
        {
          "description": "Action is required immediately.",
          "type": "string",
          "enum": [
            "High"
          ]
        },
        {
          "description": "Action is required immediately and the scope is broad.",
          "type": "string",
          "enum": [
            "Critical"
          ]
        },
        {
          "description": "An error occurred but it is too late to take remedial action.",
          "type": "string",
          "enum": [
            "Fatal"
          ]
        },
        {
          "description": "The event/finding severity is not mapped.",
          "type": "string",
          "enum": [
            "Other"
          ]
        }
      ]
    },
    "TemplateEntry": {
      "type": "object",
      "required": [
        "label",
        "value"
      ],
      "properties": {
        "label": {
          "type": "string"
        },
        "value": {
          "type": "string"
        }
      }
    },
    "TemplateEntryWithDedup": {
      "type": "object",
      "required": [
        "label",
        "value"
      ],
      "properties": {
        "label": {
          "type": "string"
        },
        "use_for_dedup": {
          "default": false,
          "type": "boolean"
        },
        "value": {
          "type": "string"
        }
      }
    }
  }
}
