diff --git a/docs/yaml-spec/schema/README.md b/docs/yaml-spec/schema/README.md new file mode 100644 index 0000000000..c70780ecd1 --- /dev/null +++ b/docs/yaml-spec/schema/README.md @@ -0,0 +1,90 @@ +### Objective + +Enable schema validation and auto-completion for custom detection YAMLs within your forked repo, streamlining detection development and ensuring alignment with your own knowledge objects and detection standards. + +### Motivation + +The `contentctl new` CLI wrapper enforces strict keys and values, which can make it difficult to create meaningful detections tailored to your environment (e.g., macOS, GCP). This approach provides analysts with auto-complete functionality and dropdown options, making it easier to populate required fields and adapt detection logic to environment-specific assets. + + +| Step | Description | +| ---- | --------------------------------------------------------------------------------- | +| 1 | Create `.vscode/` folder to store project-specific editor settings | +| 2 | Add `schemas/detection.schema.json` for detection rule structure | +| 3 | Add `.vscode/settings.json` to link schema to detection YAML files | +| 4 | Install VSCode YAML Extension (Red Hat) for schema validation support | +| 5 | Create user snippet (`detection-snippets.code-snippets`) for a detection template | +| 6 | Test typing `newdetection` into a `.yml` file and validate schema enforcement | + +#### Example Usage + + +https://github.com/user-attachments/assets/77ca2d9b-91f3-42a3-b34d-44fee325b892 + + + + +### Setup Instructions + +#### 1. Create the `.vscode/` Folder + +* Open your local cloned detections repository in VSCode. +* Create a `.vscode/` folder at the root level: + + ```bash + mkdir .vscode + ``` +* Your folder structure should now include: + + ``` + .vscode/ + .github/ + your_detections_repo/ + README.md + ``` + +#### 2. Add the Detection Schema + +* Inside `.vscode/`, create a `schemas/` folder: + + ```bash + mkdir .vscode/schemas + ``` +* Add a file named `detection.schema.json` and populate it with your environment specifics. + +#### 3. Link the Schema in VSCode Settings + +* Under `.vscode/`, create `settings.json` and add: + + ```json + { + "yaml.schemas": { + "./.vscode/schemas/detection.schema.json": "path_to_where_your_detections_live/detections/cloud/*.yml" + } + } + ``` +* This applies the schema to any `.yml` files in the detections folder. + +#### 4. Install the YAML Extension + +* Open VSCode Extensions (`Ctrl+Shift+X`) +* Search for **YAML** by **Red Hat** and install it. +* This enables validation and autocomplete based on your schema. + +#### 5. Create the Detection Template Snippet + +* This will allow you to simply type `newdetection` in a new YAML file within your detections folder, and it will prepopulate this template for you. (Highly recommend to edit this as per your requirements) +* Enter `Cmd+Shift+P` in VScode +* Search for `Preferences: Configure User Snippets` +* Search for `New Global Snippets file` +* Name this file `detection-snippets.code-snippets` +* Or you can browse to the location on your local machine `/Users//Library/Application Support/Code/User/snippets` +* Add the `detection-snippets.code-snippets` to that location + + +#### 6. Test Your Setup + +* Navigate to the detections folder and create a new YAML file. +* Type `newdetection` and use `Ctrl+Space` to trigger snippet suggestions. +* You should see schema validation and field descriptions by hovering over fields. + diff --git a/docs/yaml-spec/schema/detection-snippets.code-snippets b/docs/yaml-spec/schema/detection-snippets.code-snippets new file mode 100644 index 0000000000..5c8a216d8d --- /dev/null +++ b/docs/yaml-spec/schema/detection-snippets.code-snippets @@ -0,0 +1,38 @@ +{ + "New Detection YAML": { + "prefix": "newdetection", + "body": [ + "name: ''", + "id: ''", + "version: ''", + "date: ''", + "author: ''", + "status: ''", + "type: ''", + "data_source:", + " - ''", + "description: ''", + "search: ''", + "how_to_implement: ''", + "known_false_positives: ''", + "references:", + " - ''", + "drilldown_searches:", + " - name: ''", + " search: ''", + " earliest_offset: ''", + " latest_offset: ''", + "tags:", + " analytic_story:", + " - ''", + " asset_type: ''", + " mitre_attack_id:", + " - ''", + " product:", + " - ''", + " security_domain: ''" + ], + "description": "Updated minimal template for a new detection YAML file" + } +} +{ \ No newline at end of file diff --git a/docs/yaml-spec/schema/detection.schema.json b/docs/yaml-spec/schema/detection.schema.json new file mode 100644 index 0000000000..a5cd8387ef --- /dev/null +++ b/docs/yaml-spec/schema/detection.schema.json @@ -0,0 +1,254 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "author": { + "description": "Select the author email from allowed options.", + "enum": [ + "", + "", + "", + "", + "" + ], + "type": "string" + }, + "data_source": { + "description": "Select the relevant data sources for the rule.", + "items": { + "enum": [ + "your_data_source_1", + "your_data_source_2", + "your_data_source_3", + "your_data_source_4", + "your_data_source_5", + "your_data_source_6", + "your_data_source_7", + "your_data_source_8", + "your_data_source_9", + "your_data_source_10", + "your_data_source_11" + ], + "type": "string" + }, + "type": "array" + }, + "date": { + "description": "Enter the date in YYYY-MM-DD format.", + "format": "date", + "type": "string" + }, + "description": { + "description": "Provide a description of what the detection rule does.", + "type": "string" + }, + "drilldown_searches": { + "description": "Drilldown searches related to this rule.", + "items": { + "properties": { + "earliest_offset": { + "description": "Earliest time offset. '$info_min_time$'", + "type": "string" + }, + "latest_offset": { + "description": "Latest time offset. '$info_max_time$'", + "type": "string" + }, + "name": { + "description": "Name of the drilldown search. 'Click to see contributing events'", + "type": "string" + }, + "search": { + "description": "SPL query for the drilldown. '%original_detection_search%'", + "type": "string" + } + }, + "required": [ + "name", + "search", + "earliest_offset", + "latest_offset" + ], + "type": "object" + }, + "type": "array" + }, + "how_to_implement": { + "description": "Instructions on how to implement this detection rule. Ensure that the `YAMLRULENAME_filter` macro is available at the end of the SPL search. This macro is used to filter out known false positives.", + "type": "string" + }, + "id": { + "description": "Enter a unique UUID.", + "type": "string" + }, + "known_false_positives": { + "description": "Document any known false positives. Any references to JIRA tickets would go here", + "type": "string" + }, + "name": { + "description": "Enter the name of the rule, matching the YAML file name all lowercase.", + "type": "string" + }, + "references": { + "description": "Provide references (e.g., Runbook links).", + "items": { + "format": "uri", + "type": "string" + }, + "type": "array" + }, + "search": { + "description": "Provide the SPL (Search Processing Language) query for the rule.", + "type": "string" + }, + "status": { + "description": "Define the status of the detection rule.", + "enum": [ + "production", + "experimental", + "deprecated", + "validation" + ], + "type": "string" + }, + "tags": { + "description": "Metadata tags for the rule.", + "properties": { + "analytic_story": { + "description": "Relevant analytic stories.", + "items": { + "enum": [ + "Example Stories", + "BlackMatter Ransomware", + "Suspicious GCP Storage Activities", + "Suspicious Okta Activity", + "Windows Registry Abuse", + "Threat Intelligence Brand Mentions Leaks and Exposure", + "Suspicious GCP Admin Activity", + "GitHub Evasion of Audit Controls", + "GitHub Account Abuse", + "Vault Credential Access and Secret Exposure", + "Log Source Disruption and Ingestion Gaps", + "GCP Firewall Tampering", + "Google Workspace External Sharing" + ], + "type": "string" + }, + "type": "array" + }, + "asset_type": { + "description": "Asset type involved.", + "enum": [ + "AWS Account", + "AWS EKS Kubernetes cluster", + "AWS Federated Account", + "AWS Instance", + "Account", + "Amazon EKS Kubernetes cluster", + "Amazon EKS Kubernetes cluster Pod", + "Amazon Elastic Container Registry", + "Azure Tenant", + "Azure AKS Kubernetes cluster", + "Azure Active Directory", + "CircleCI", + "Cloud Compute Instance", + "Cloud Instance", + "DNS Servers", + "Database Server", + "Domain Server", + "EC2 Snapshot", + "Endpoint", + "GCP", + "GCP Account", + "GCP GKE EKS Kubernetes cluster", + "GCP GKE Kubernetes cluster", + "GCP Kubernetes cluster", + "GCP Storage Bucket", + "GDrive", + "GSuite", + "GitHub", + "Google Cloud Platform tenant", + "Identity", + "Infrastructure", + "Instance", + "Kubernetes", + "Network", + "O365 Tenant", + "Okta Tenant", + "Proxy", + "S3 Bucket", + "Splunk Server", + "VPN Appliance", + "Web Server", + "Web Proxy", + "Web Application", + "Windows" + ], + "type": "string" + }, + "mitre_attack_id": { + "description": "Associated MITRE ATT&CK IDs.", + "items": { + "type": "string" + }, + "type": "array" + }, + "product": { + "description": "Product association.", + "items": { + "enum": [ + "Splunk Enterprise Security", + "Splunk Cloud", + "Splunk Behavioral Analytics" + ], + "type": "string" + }, + "type": "array" + }, + "security_domain": { + "description": "Security domain for the rule.", + "enum": [ + "endpoint", + "network", + "identity", + "application", + "threat", + "access", + "audit" + ], + "type": "string" + } + }, + "type": "object" + }, + "type": { + "description": "Specify the type of detection.", + "enum": [ + "Anomaly", + "Correlation", + "Hunting", + "TTP", + "Baseline", + "Embedded" + ], + "type": "string" + }, + "version": { + "description": "Enter the version number (integer expected).", + "type": "string" + } + }, + "required": [ + "name", + "id", + "version", + "date", + "author", + "status", + "type", + "data_source", + "description", + "search" + ], + "title": "Detection Rule Schema", + "type": "object" +} \ No newline at end of file diff --git a/docs/yaml-spec/schema/settings.json b/docs/yaml-spec/schema/settings.json new file mode 100644 index 0000000000..bf711c8275 --- /dev/null +++ b/docs/yaml-spec/schema/settings.json @@ -0,0 +1,5 @@ +{ + "yaml.schemas": { + "./.vscode/schemas/detection.schema.json": "path_to_where_you_keep_your/detections*.yml" + } +} \ No newline at end of file