Managed Security Service Providers (MSSPs) and internal SOC teams face major challenges in the current cybersecurity landscape. Managing different SOC deployments across various clients or business units can lead to inconsistencies, inefficiencies, and vulnerabilities. Traditional approaches often fall short, struggling with scalability, agility, and accuracy. This is where Detection-as-Code can play a crucial role, offering transformative solutions to elevate your security operations.
Whether you’re an MSSP looking to enhance client offerings or an internal SOC team striving for operational excellence, adopting Detection-as-Code can be a game-changer. Here’s why it matters.
Detection-as-Code is a modern approach to threat detection that allows security teams to define, manage, and deploy detection logic using code. This methodology enhances accuracy, fosters collaboration, and enables rapid scaling by adopting practices similar to DevOps.
Sekoia SOC Platform has been designed to handle Detection-as-Code natively, leveraging:
To illustrate how Detection-as-Code can be implemented with the Sekoia platform, here’s a quick example of creating a Sigma detection rule and deploying it via the Sekoia API.
Create a file named my_detection.yml
containing a Sigma pattern, such as the following simple content:
name: failed_logon
detection:
selection:
event.category: authentication
action.outcome: failure
condition: selection
---
correlation:
type: event_count
rules:
- failed_logon
group-by:
- action.properties.TargetUserName
- action.properties.TargetDomainName
timespan: 5m
condition:
gte: 10
This example was taken from the Sigma v2.0 and Sigma Correlation Sigma_HQ recent blog posts, with mapping the field names to the ECS format being used in Sekoia.
Use the following Create Rule API endpoint to submit your detection rule via a POST request with a JSON body, containing the detection parameters. Here’s an example using curl
and jq
:
curl -X POST "https://api.sekoia.io/v1/sic/conf/rules-catalog/rules" \
-H "accept: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg payload "$(cat my_detection.yml)" '{
name: "Multiple failed logons for a single user (possible brute force attack)",
type: "sigma",
description: "Detect possible brute force attacks on Windows endpoints and servers",
payload: $payload,
severity: 40,
effort: 3,
alert_type_uuid: "26b9f04e-65c7-4fcd-b0a4-ab5854cc36e7",
enabled: true
}')"
The detection rule should then appear in Sekoia UI.
TIP : To list the different alert types available and their UUIDs, you can use the following List Alert types API endpoint. Here’s an example with curl
:
{
echo -e "UUID\tCategory_name\tValue";
curl -s -H "Authorization: Bearer YOUR_API_KEY" "https://api.sekoia.io/v1/sic/conf/alerts/types?limit=100" | jq -r '.items[] | "\(.uuid)\t\(.category_name)\t\(.value)"';
} | column -t
With this method, you can quickly deploy new ad-hoc detection rules. Now let’s look at how you can store and deploy these detection rules with a Git repository.
In this example, I have selected GitHub as my preferred tool for managing and deploying custom detections. However, this can be easily implemented using other similar platforms like GitLab, Bitbucket, and others.
First, make sure you have a GitHub repository to store and deploy your detections. As this repository will contain sensitive information such as detection settings in Sekoia, it is highly recommended to make it Private.
In case this is a newly created repository, follow the quick-steps instructions given by GitHub.
We will be leveraging GitHub Actions to deploy detections that are merged in the repository. For that, add your Sekoia API key in the GitHub Actions secrets.
Next, you need to authorize your workflow to write to the repository. This is essential for adding the UUIDs of newly deployed detections, which will be necessary for updating any existing detections.
You can find this setting in the repository’s configuration under the Actions → General menu.
Finally, create and merge the following files in your repository:
push_detections.yml
in the folder .github/worklow
of your repositoryname: Deploy detections in Sekoia
on:
push:
branches:
- main
paths:
- detections/**
jobs:
deploy_rules:
runs-on: ubuntu-latest
steps:
- name: Checkout GitHub Action
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install Python packages
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Execute deployment script
env:
SEKOIA_API_KEY: ${{ secrets.SEKOIA_API_KEY }}
run: python deploy_detections.py
- name: Commit and push changes
run: |
git config --global user.name "SOC AllSafe CyberSecurity"
git config --global user.email "[email protected]"
git add -A
git commit -m "Add UUIDs of newly deployed detection rules" --allow-empty
git push
deploy_detections.py
in the root folder of your repositoryimport copy
import glob
import json
import os
import requests
# Sekoia API Base URL depends on the Hosting region https://docs.sekoia.io/getting_started/regions/
API_BASE_URL = "https://api.sekoia.io" # Base URL for FRA1
API_DETECTION_PATH = "/v1/sic/conf/rules-catalog/rules"
# Sekoia API Key is set by an environment variable
SEKOIA_API_KEY = os.getenv("SEKOIA_API_KEY")
def create_detection(query):
url = f"{API_BASE_URL}{API_DETECTION_PATH}"
detection_name = query["name"]
response = requests.post(url, json=query, headers={"Authorization": f"Bearer {SEKOIA_API_KEY}"})
if response.status_code == 200:
print(f"Rule \"{detection_name}\" has been successfully created.")
detection_details = response.json()
return detection_details["uuid"]
else:
error_message = response.text
print("Error: failed to create the rule \"{detection_name}\".\nStatus code: {response.status_code} {error_message}")
return None
def update_detection(query):
uuid = query.pop("uuid")
url = f"{API_BASE_URL}{API_DETECTION_PATH}/{uuid}"
detection_name = query["name"]
response = requests.put(url, json=query, headers={"Authorization": f"Bearer {SEKOIA_API_KEY}"})
if response.status_code == 200:
print(f"Rule \"{detection_name}\" has been successfully updated.")
else:
error_message = response.text
print("Error: failed to update the rule \"{detection_name}\".\nStatus code: {response.status_code} {error_message}")
return None
def deploy_detections():
for json_file in glob.glob("detections/*.json"):
# Check if a sigma content is here
sigma_file = json_file.replace(".json", "_sigma.yml")
if not os.path.isfile(sigma_file):
print(f"Ignoring {json_file} as file {sigma_file} is missing")
continue
# Build the query parameters
detection_description = {}
with open(json_file, "r") as file:
detection_description = json.load(file)
api_query = copy.deepcopy(detection_description)
with open(sigma_file, "r") as file:
api_query["payload"] = file.read()
# Create the detection if no UUID is there, otherwise update it
if "uuid" in api_query:
update_detection(api_query)
else:
uuid = create_detection(api_query)
if uuid:
detection_description["uuid"] = uuid
with open(json_file, "w") as file:
json.dump(detection_description, file, indent=4)
if __name__ == '__main__':
deploy_detections()
requirements.txt
in the root folder of your repositoryrequests==2.28.2
Now you should be ready to deploy your detections with GitHub, let’s try!
Create and merge the following files in the detections
folder of your repository:
bruteforce_windows.json
{
"name": "Multiple failed logons for a single user (possible brute force attack)",
"type": "sigma",
"description": "Detect possible brute force attacks on Windows endpoints and servers",
"severity": 40,
"effort": 3,
"alert_type_uuid": "26b9f04e-65c7-4fcd-b0a4-ab5854cc36e7",
"enabled": true
}
bruteforce_windows_sigma.yml
name: failed_logon
detection:
selection:
event.category: authentication
action.outcome: failure
condition: selection
---
correlation:
type: event_count
rules:
- failed_logon
group-by:
- action.properties.TargetUserName
- action.properties.TargetDomainName
timespan: 5m
condition:
gte: 10
After merging those two files in your repository, you should see a trigger of the GitHub action deploying this detection in Sekoia.
Also, you should now see a uuid
field which has been added to the detections/bruteforce_windows.json
file.
This data will be used on future detection updates, to identify that this detection as already been deployed and needs to be updated, not created again.
From now on you can easily create and deploy additional detection rules using the same method. As soon as these rules are merged in your GitHub repository, they are automatically deployed in Sekoia.
At Sekoia we believe that scaling your SOC services to meet the demands of today’s cybersecurity landscape is essential. For MSSPs, embracing Detection-as-Code and leveraging the advanced capabilities of the Sekoia platform can differentiate your services and deliver superior protection to clients. For internal SOC teams, these tools can lead to heightened efficiency, stronger defenses, and proactive threat management.
Interested to go further? To share experiences with Detection-as-Code within your SOC? Or to discover the Sekoia SOC platform? Contact us through our website www.sekoia.io or via LinkedIn.
You can also read other articles on our blog: