ServiceNow is a cloud-based platform for IT Service Management (ITSM) that helps organizations manage digital workflows for enterprise operations. It provides a centralized system for handling incidents, changes, and requests, enabling process automation, visibility across departments, and structured response procedures.
Integrating ServiceNow with Wazuh combines Wazuh threat detection and response capabilities with ServiceNow incident management. Wazuh monitors systems for anomalies such as unauthorized changes, malicious activities, policy violations, and vulnerabilities, and sends these security events to ServiceNow. In ServiceNow, incidents can be tracked, prioritized, and resolved using standardized ITSM workflows. This integration improves response times, coordination between security and IT teams, and provides an audit trail for compliance and reporting.
By automating incident creation and reducing reliance on manual alert checks, organizations can lower the risk of missed or delayed responses and maintain a strong security posture.
This blog post explains how to integrate ServiceNow with Wazuh for proactive incident management.
Infrastructure
We use the following infrastructure for this integration:
- A pre-built, ready-to-use Wazuh OVA 4.12.0, which includes the Wazuh central components (Wazuh server, Wazuh indexer, and Wazuh dashboard). Follow this guide to download and set up the Wazuh virtual machine.
- A Windows 11 endpoint with the Wazuh agent 4.12.0 installed and enrolled on the Wazuh server. This endpoint is required to simulate a high-severity alert.
- A ServiceNow instance.
Note
ServiceNow does not offer a completely free public API. For this blog post, we use a free personal developer instance through their developer program. This is a full-featured environment for testing.
Configuration
To achieve this integration, we configure the Wazuh server to forward alerts to the ServiceNow instance to create incident tickets.
ServiceNow developer instance
This integration requires access to a ServiceNow instance, and in this case, we use a free developer instance. We created a developer account, deployed a free ServiceNow instance, verified the REST API, and confirmed the incident creation on the ServiceNow dashboard as described below.
Create a free developer account
Follow the steps below to create a free developer account:
- Go to: https://developer.servicenow.com.
- Click Sign Up and Start Building (or Sign In if you already have an account).
- Verify your email and complete your profile.

Request a free personal developer instance
Follow the steps below to request a free personal developer instance:
- Log in to your developer account.
- Click Request Instance in the top-right menu.
- Choose your instance and click Request. You will be assigned an instance URL like: https://dev12345.service-now.com.
- Click on the ^ button in the top right, select Change User Role, choose Admin, and click on Change User Role.
- Click Manage instance password to access the credentials.
- Click on the instance URL to log in to your instance.

Note
It takes about 2–5 minutes for your instance to be ready.
Access the REST API
Follow the steps below to access the REST API and create incidents to verify your permissions. From your instance dashboard:
- Click All in the top panel.
- Search for REST API Explorer in the left-hand menu.
- Go to REST API Explorer.
- Options:
- Namespace: now
- API Name: Table API
- API version: latest
- Click Create a record (POST).
- Search for Incident in the tableName field and select it.
- Switch to the RAW tab under the Request Body and add a body like:
{ "short_description": "Wazuh Alert - Unauthorized login", "urgency": "2", "impact": "2" }
- Click Send to verify it works.
- You should get a response similar to the one below in the Response Body section. This confirms you can create incidents with your current permissions.
{ "result": { "parent": "", "made_sla": "true", "caused_by": "", "watch_list": "", "upon_reject": "cancel", "sys_updated_on": "2025-06-19 15:32:52", "child_incidents": "0", "hold_reason": "", "origin_table": "", "task_effective_number": "INC0010001", "approval_history": "", "number": "INC0010001", "resolved_by": "", "sys_updated_by": "admin", "opened_by": { "link": "https://dev196099.service-now.com/api/now/table/sys_user/6816f79cc0a8016401c5a33be04be441", "value": "6816f79cc0a8016401c5a33be04be441" }, "user_input": "", "sys_created_on": "2025-06-19 15:32:52", "sys_domain": { "link": "https://dev196099.service-now.com/api/now/table/sys_user_group/global", "value": "global" }, "state": "1", "route_reason": "", "sys_created_by": "admin", "knowledge": "false", "order": "", "calendar_stc": "", "closed_at": "", "cmdb_ci": "", "delivery_plan": "", "contract": "", "impact": "2", "active": "true", "work_notes_list": "", "business_service": "", "business_impact": "", "priority": "3", "sys_domain_path": "/", "rfc": "", "time_worked": "", "expected_start": "", "opened_at": "2025-06-19 15:32:52", "business_duration": "", "group_list": "", "work_end": "", "caller_id": "", "reopened_time": "", "resolved_at": "", "approval_set": "", "subcategory": "", "work_notes": "", "universal_request": "", "short_description": "Wazuh Alert - Unauthorized login", "close_code": "", "correlation_display": "", "delivery_task": "", "work_start": "", "assignment_group": "", "additional_assignee_list": "", "business_stc": "", "cause": "", "description": "", "origin_id": "", "calendar_duration": "", "close_notes": "", "notify": "1", "service_offering": "", "sys_class_name": "incident", "closed_by": "", "follow_up": "", "parent_incident": "", "sys_id": "0aacbda083162e10b8856060ceaad357", "contact_type": "", "reopened_by": "", "incident_state": "1", "urgency": "2", "problem_id": "", "company": "", "reassignment_count": "0", "activity_due": "", "assigned_to": "", "severity": "3", "comments": "", "approval": "not requested", "sla_due": "", "comments_and_work_notes": "", "due_date": "", "sys_mod_count": "0", "reopen_count": "0", "sys_tags": "", "escalation": "0", "upon_approval": "proceed", "correlation_id": "", "location": "", "category": "inquiry" } }

- Verify this incident was created by checking the incidents dashboard:
- Click All in the top panel.
- Search for Incidents in the left-hand menu.
- Select Incidents under the Service Desk tab.
- Click the filter icon, select choose field, and type in Number.
- Select is in the Choose operator field, and type in the newly created incident ticket number
INC0010001
. - Click the Run filter.

Configuring the Wazuh server
For this test, we use Basic Auth (username and password) on ServiceNow; however, for a production environment, an OAuth token is recommended for security reasons. In order to prevent plaintext credentials from being hardcoded in the integration script, we use environment variables to store authentication secrets.
Perform the following steps on the Wazuh server to create the environment file, configure the Wazuh Integrator module, and the integration script:
- Create a
.env
file in the/var/ossec/integrations
directory and add the following content to it.
SERVICENOW_USER=<YOUR_USERNAME> SERVICENOW_PASS=<YOUR_PASSWORD> SERVICENOW_INSTANCE=<YOUR_INSTANCE>.service-now.com
Replace:
<SERVICENOW_USER>
with your ServiceNow instance username.<SERVICENOW_PASS>
with your ServiceNow instance password.<SERVICENOW_INSTANCE>
with your ServiceNow instance name.
- Update the permissions and ownership of the
.env
file:
# chmod 750 /var/ossec/integrations/.env # chown root:wazuh /var/ossec/integrations/.env
- To install the dependencies required for the integration script, use the
pip
utility to installrequests
andpython-dotenv
. Therequests
module acts as a bridge between Wazuh and ServiceNow for making HTTP requests from Python. Thepython-dotenv
module is used to load configuration variables from the.env
file into the environment:
# /var/ossec/framework/python/bin/pip3 install requests python-dotenv
- Create the custom integration script
custom-servicenow
in the/var/ossec/integrations
directory and add the following content to it.
#!/var/ossec/framework/python/bin/python3.10 # Wazuh -> ServiceNow integration script import json import sys import time import os try: import requests from requests.auth import HTTPBasicAuth from dotenv import load_dotenv except Exception as e: print("Required modules not found. Install with: pip install requests python-dotenv") sys.exit(1) # Load environment variables from .env file in the same directory as this script script_dir = os.path.dirname(os.path.realpath(__file__)) dotenv_path = os.path.join(script_dir, '.env') load_dotenv(dotenv_path) SN_INSTANCE = os.getenv('SERVICENOW_INSTANCE') SN_USER = os.getenv('SERVICENOW_USER') SN_PASS = os.getenv('SERVICENOW_PASS') SN_TABLE_URL = f"https://{SN_INSTANCE}/api/now/table/incident" debug_enabled = True # Set to True for logs pwd = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) now = time.strftime("%a %b %d %H:%M:%S %Z %Y") log_file = '{0}/logs/integrations.log'.format(pwd) def main(args): debug("# Starting") if not SN_INSTANCE or not SN_USER or not SN_PASS: debug("Missing ServiceNow configuration in environment variables.") sys.exit(1) # Read alert file location alert_file_location = args[1] debug("# File location") debug(alert_file_location) # Load alert JSON with open(alert_file_location, 'rb') as alert_file: last_line = alert_file.read().decode('utf-8').splitlines()[-1] if last_line.split(): json_alert = json.loads(last_line) debug("# Processing alert") debug(json_alert) # Build ServiceNow payload msg = generate_payload(json_alert) debug("# Payload to ServiceNow") debug(msg) # Send to ServiceNow send_msg(msg) def debug(msg): if debug_enabled: msg = "{0}: {1}\n".format(now, msg) print(msg) with open(log_file, "a") as f: f.write(msg) def generate_payload(alert): title = alert['rule'].get('description', "No Description") alert_level = str(alert['rule'].get('level', "N/A")) agentname = alert['agent'].get('name', "No Name") agentip = alert['agent'].get('ip', "No IP") location = alert.get('location', "No Location") timestamp = alert.get('timestamp', "No Timestamp") full_log = alert.get('full_log', "No Log") payload = { "short_description": f"Wazuh Alert: {title}", "description": f""" Wazuh Alert Details: Timestamp: {timestamp} Agent Name: {agentname} Agent IP: {agentip} Alert Level: {alert_level} Location: {location} Log: {full_log} """, "urgency": "1", # High "impact": "1", "category": "Security" } return payload def send_msg(payload): try: response = requests.post( SN_TABLE_URL, auth=HTTPBasicAuth(SN_USER, SN_PASS), headers={"Content-Type": "application/json"}, json=payload ) debug(f"ServiceNow response: {response.status_code} {response.text}") except Exception as e: debug(f"Error sending to ServiceNow: {e}") if __name__ == "__main__": try: if len(sys.argv) >= 2: msg = '{0} {1}'.format(now, sys.argv[1]) else: msg = '{0} Wrong arguments'.format(now) with open(log_file, 'a') as f: f.write(msg + '\n') debug("# Exiting: Bad arguments.") sys.exit(1) with open(log_file, 'a') as f: f.write(msg + '\n') main(sys.argv) except Exception as e: debug(str(e)) raise
- Run the command below to update the permissions and ownership of the
custom-servcienow
script:
# chmod 750 /var/ossec/integrations/custom-servicenow # chown root:wazuh /var/ossec/integrations/custom-servicenow
- Edit the
/var/ossec/etc/ossec.conf
file and append the integration below:
<ossec_config> <!-- ServiceNow --> <integration> <name>custom-servicenow</name> <hook_url>https://<SN_INSTANCE>.service-now.com/api/now/table/incident</hook_url> <level>12</level> <!-- send only level 12+ alerts —-> <alert_format>json</alert_format> </integration> </ossec_config>
Where:
<name>
specifies the name of the application. In this case, ServiceNow.<hook_url>
specifies the webhook URL of the external application being integrated. Replace<SN_INSTANCE>
with your ServiceNow instance name, such asdev12345
<level>
specifies the severity of the alerts to be considered for ServiceNow ticket creation.<alert_format>
specifies that the alerts are received in JSON format.
Note
We configure this integration to send alerts with severity levels that are equal to or greater than 12
. You can modify this according to your needs and preferences.
- Append the below rule to the
/var/ossec/etc/rules/local_rules.xml
file to generate a sample alert with severity level 12. This is required to demonstrate the type of alerts to be forwarded to ServiceNow for incident ticket creation.
<rule id="101556" level="12"> <if_sid>60105</if_sid> <field name="win.system.eventID">^529$|^4625$</field> <description>Logon Failure - Unknown user or bad password</description> <mitre> <id>T1531</id> </mitre> </rule>
- Restart the Wazuh manager to apply the changes:
# systemctl restart wazuh-manager
Testing the integration
To test this integration, we attempt to log in with incorrect credentials on the Windows 11 endpoint, which triggers a high-severity alert (level 12
). We then visualize this alert on the Wazuh dashboard and confirm that an incident ticket has been successfully created on the ServiceNow incidents dashboard.
Wazuh dashboard
View the alerts generated by this simulation on the Wazuh dashboard:
- Navigate to Threat intelligence > Threat Hunting.
- Click + Add filter. Then filter by
rule.id
. - In the Operator field, select
is
. - Search and select rule ID
101556
in the Values field. - Click Save.

ServiceNow dashboard
The high-severity alert seen on the Wazuh dashboard is forwarded to the ServiceNow instance to create an incident ticket. Follow the steps below to view and manage the incident ticket:
- Log in to your ServiceNow instance.
- Click All in the top panel of the dashboard.
- Search for Incidents in the left-hand menu.
- Select Incidents under Service Desk.
- Click the filter icon, select choose field, and type in State.
- Select is and New in the Choose operator field.
- Click Run
- Select one of the created incidents on the incidents dashboard and investigate.
- Close or resolve the incident upon completion.

Conclusion
We demonstrated how to integrate ServiceNow with Wazuh in this blog post. This integration helps to bridge the gap between security monitoring and incident management by automating the flow of critical alerts into a centralized ITSM platform. This helps streamline response efforts and ensures that security events are tracked, prioritized, and resolved efficiently.
By leveraging this integration, organizations can enhance their operational resilience, reduce response times, and maintain better visibility and accountability across their security infrastructure.
Discover more about Wazuh by exploring our other blog posts and becoming part of our growing community.