netskope_api_v2
Netskope API v2 provides a powerful interface for managing and monitoring Netskope deployments. It enables users to retrieve alerts and events, manage URL lists, and control clients. With Netskope API v2, organizations can proactively respond to security threats, enforce web access policies, and efficiently administer their Netskope environment.
Network Security · Netskope
Details
| ID | netskope_api_v2 |
|---|---|
| Provider | Netskope |
| Category | Network Security |
| From Version | 6.9.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Netskope API v2 provides a powerful interface for managing and monitoring Netskope deployments. It enables users to retrieve alerts and events, manage URL lists, and control clients. With Netskope API v2, organizations can proactively respond to security threats, enforce web access policies, and efficiently administer their Netskope environment.
This integration was integrated and tested with version 2 of the Netskope API.
To successfully instantiate an instance of the Netskope API v2 integration under the RBACv3 framework, follow the steps below.
Note: Netskope has deprecated the legacy single-step API token generation process. All new and migrated tenants must use RBACv3 to create API tokens through Service Accounts.
Step 1: Create a Service Account (RBACv3)
Follow the instructions under the section Create a New Service Account.
Step 2: Assign required functional roles
Ensure the Service Account has access to the following functional areas:
In total 4 sections need to be enabled:
- Administration
- Access Control
- DLP
- Events & Analytics

For Administration
In the Administration section, select Function > Audit Log and grant it View rights.

Under Users & Groups, select Manage:

Events & Analytics
Functions that need to be set to view: Application Events, Page Events, Network Events, and Alerts.

For Access Control
Select Access Control, for the Infrastructure function, grant View rights.

For the URL List, set to Manage and Apply.

For DLP
For DLP Incident, set to View.

Step 3
- API Token: Copy the generated API token and store it securely.
- Server URL: Construct the server URL using your account name and region. Example:
If your account name isxsoarand the region isde, your Server URL is: https://xsoar.de.goskope.com/
Configue Netskope (API v2) in Cortex
| Parameter | Description | Required |
|---|---|---|
| Server URL | True | |
| Use system proxy settings | False | |
| Trust any certificate (not secure) | False | |
| API token | Netskope API access token (make sure to generate token for the required endpoints). | True |
| First fetch timestamp | First alert created date to fetch. e.g., “1 min ago”,”2 weeks ago”,”3 months ago”. | False |
| Maximum incidents per fetch | Maximum number of incidents per fetch. Default is 50. The maximum is 100. | False |
| Maximum Netskope events per fetch. Max value is 200. | False | |
| Maximum Netskope DLP incidents per fetch. Max value is 200. | False | |
| Fetch Events | Fetch events as incidents, in addition to the alerts. | False |
| Fetch DLP incidents | Fetch Netskope DLP incidents as incidents, in addition to the alerts. | False |
| Event types to fetch. | The event types to fetch as incidents. | False |
| Alerts Query | Free text query to filter the fetched alerts. For more information, visit Netskope documentation (https://docs.netskope.com/en/get-alerts-data.html). | False |
| Events Query | Free text query to filter the fetched events (if configured). For more information, visit Netskope documentation (https://docs.netskope.com/en/get-alerts-data.html). | False |
| Incident type | False | |
| Fetch incidents | False | |
| User Email | The user email for update incident in Netskope. | False |
| Incidents Fetch Interval | False | |
| Incident Mirroring Direction | Cortex XSOAR only parameter. | False |
| Close Mirrored XSOAR Incident | Cortex XSOAR only parameter. | False |
| Close Mirrored Netskope Incident | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears with the command details in the War Room.
netskope-alert-list
Retrieve alerts generated by Netskope. Select the desired alerts using the alert_type parameter. Mandatory inputs include start_time and end_time, or insertion_start_time and insertion_end_time (If end_time or insertion_end_time is not provided, it defaults to the current date and time). Additionally, it is not permissible to supply a combination of the aforementioned options.
Base Command
netskope-alert-list
Input
| Argument Name | Description | Required |
|---|---|---|
| start_time | Restrict events to those that have dates greater than the provided date string (for example “YYYY-MM-DDThh:mm”, “1 min ago”, “2 weeks ago”). When this argument is provided, the ‘end_time’ argument must be provided as well. | Optional |
| end_time | Restrict events to those that have dates less than or equal to the provided date string (for example “YYYY-MM-DDThh:mm”, “1 min ago”, “2 weeks ago”). When this argument is provided, the ‘start_time’ argument must also be provided. If the start_time argument is provided and this argument is not - the default value will be set for now. | Optional |
| insertion_start_time | Restrict events to those that were inserted into the system after the provided date string (for example “YYYY-MM-DDThh:mm”, “1 min ago”, “2 weeks ago”). When this argument is provided, the ‘insertion_end_time’ argument must also be provided. | Optional |
| insertion_end_time | Restrict events to those that were inserted into the system before the provided date string (for example “YYYY-MM-DDThh:mm”, “1 min ago”, “2 weeks ago”). When this argument is provided, the ‘insertion_start_time’ argument must also be provided. If the insertion_start_time argument is provided and this argument is not - the default value will be set for now. | Optional |
| query | Free query to filter the alerts. For example, “alert_name like test”. For more information, please visit Netskope documentation: https://docs.netskope.com/en/get-alerts-data.html. | Optional |
| alert_type | Select alerts by their type. | Optional |
| acked | Whether to retrieve acknowledged alerts. Possible values are: True, False. | Optional |
| page | Page number of paginated results. Minimum value: 1. | Optional |
| limit | The maximum number of records to retrieve. Default is 50. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netskope.Alert._appsession_start | String | The timestamp marking the start of an application session. |
| Netskope.Alert._category_id | String | The unique identifier for a category. |
| Netskope.Alert._category_name | String | The name or label associated with a category. |
| Netskope.Alert._category_tags | Number | Numeric tags or labels associated with the category. |
| Netskope.Alert._content_version | Number | A numeric value representing the content version. |
| Netskope.Alert._correlation_id | String | An identifier used for correlating events or data. |
| Netskope.Alert._creation_timestamp | Number | The timestamp when the data or event was created. |
| Netskope.Alert._ef_received_at | Date | The timestamp indicating when the event was received. |
| Netskope.Alert._event_id | String | A unique identifier for the event. |
| Netskope.Alert._forwarded_by | String | Information indicating the source responsible for forwarding the event. |
| Netskope.Alert._gef_src_dp | String | The source data path for the event. |
| Netskope.Alert._id | String | A unique identifier for the event or data. |
| Netskope.Alert._insertion_epoch_timestamp | Number | Insertion timestamp. |
| Netskope.Alert._nshostname | String | The hostname associated with Netskope. |
| Netskope.Alert._raw_event_inserted_at | Date | The timestamp indicating when the raw event was inserted. |
| Netskope.Alert._service_identifier | String | An identifier associated with a specific service. |
| Netskope.Alert._session_begin | String | The timestamp marking the beginning of a session. |
| Netskope.Alert._skip_geoip_lookup | String | A flag indicating whether GeoIP lookup should be skipped. |
| Netskope.Alert._src_epoch_now | Number | A numeric value representing the source epoch. |
| Netskope.Alert.access_method | String | Cloud app traffic can be steered to the Netskope cloud using different deployment methods such as Client (Netskope Client), Secure Forwarder etc. Administrators can also upload firewall and/or proxy logs for log analytics. This field shows the actual access method that triggered the event. For log uploads this shows the actual log type such as PAN, Websense, etc. |
| Netskope.Alert.acked | String | Whether the user acknowledged the alert or not. |
| Netskope.Alert.action | String | Action taken on the event for the policy. |
| Netskope.Alert.activity | String | Description of the user-performed activity. |
| Netskope.Alert.alert | String | Indicates whether the alert is generated or not. Populated as yes for all alerts. |
| Netskope.Alert.alert_name | String | Name of the alert. |
| Netskope.Alert.alert_type | String | Type of the alert. |
| Netskope.Alert.app | String | Specific cloud application used by the user (e.g., app = Dropbox). |
| Netskope.Alert.app_session_id | Number | Unique App/Site Session ID for traffic_type = CloudApp and Web. An app session starts when a user starts using a cloud app/site and ends once they have been inactive for a certain period of time (15 mins). Use app_session_id to check all the user activities in a single app session. app_session_id is unique for a user, device, browser, and domain. |
| Netskope.Alert.appcategory | String | Application category as designated by Netskope. |
| Netskope.Alert.appsuite | String | Information related to the suite of applications or software used. |
| Netskope.Alert.browser | String | Shows the actual browser from where the cloud app was accessed. |
| Netskope.Alert.browser_session_id | Number | Browser session ID. If there is an idle timeout of 15 minutes, it will time out the session. |
| Netskope.Alert.category | String | A classification or grouping label for data or events. |
| Netskope.Alert.cci | Number | Cloud Confidence Index, indicating the readiness and security of cloud applications. |
| Netskope.Alert.ccl | String | “Cloud Confidence Level. CCL measures the enterprise readiness of the cloud apps taking into consideration those apps’ security, auditability, and business continuity. Each app is assigned one of five cloud confidence levels: excellent, high, medium, low, or poor. Useful for querying if users are accessing a cloud app with a lower CCL.” |
| Netskope.Alert.connection_id | Number | Each connection has a unique ID. Shows the ID for the connection event. |
| Netskope.Alert.count | Number | Number of raw log lines/events sessionized or suppressed during the suppressed interval. |
| Netskope.Alert.device | String | Device type from where the user accessed the cloud app. It could be a Macintosh, Windows device, iPad, etc. |
| Netskope.Alert.device_classification | String | Designation of the device as determined by the Netskope Client as to whether the device is managed or not. |
| Netskope.Alert.domain | String | Domain value. This will hold the host header value or SNI or extracted from an absolute URI. |
| Netskope.Alert.dst_country | String | Application’s two-letter country code as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.dst_latitude | Number | Latitude of the application as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.dst_location | String | Application’s city as determined by maxmind or IP2Location Geolocation database. |
| Netskope.Alert.dst_longitude | Number | Longitude of the application as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.dst_region | String | Application’s state or region as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.dst_timezone | String | Destination timezone. |
| Netskope.Alert.dst_zipcode | String | Application’s zip code as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.dstip | String | IP address where the destination app is hosted. |
| Netskope.Alert.hostname | String | Host name. |
| Netskope.Alert.incident_id | Number | A unique identifier for an incident or event. |
| Netskope.Alert.ja3 | String | A field indicating JA3 information. |
| Netskope.Alert.ja3s | String | A field indicating JA3S information. |
| Netskope.Alert.managed_app | String | Whether or not the app in question is managed. |
| Netskope.Alert.managementID | String | Management ID. |
| Netskope.Alert.netskope_pop | String | Netskope Point of Presence, related to network infrastructure. |
| Netskope.Alert.notify_template | String | The template used for notifications or alerts. |
| Netskope.Alert.nsdeviceuid | String | Device identifiers on macOS and Windows. |
| Netskope.Alert.organization_unit | String | Organization units for which the event correlates to. This ties to user information extracted from Active Directory using the Directory Importer/AD Connector application. |
| Netskope.Alert.os | String | Operating system of the host that generated the event. |
| Netskope.Alert.os_version | String | Operating system version of the host. |
| Netskope.Alert.other_categories | String | Additional categories or labels not specified elsewhere. |
| Netskope.Alert.page | String | The URL of the originating page. |
| Netskope.Alert.page_site | String | Information about the web page or site being accessed. |
| Netskope.Alert.policy | String | Name of the policy configured by an admin. |
| Netskope.Alert.policy_id | String | The Netskope internal ID for the policy created by an admin. |
| Netskope.Alert.port | String | The network port used for communication. |
| Netskope.Alert.protocol | String | The communication protocol or method used. |
| Netskope.Alert.request_id | Number | Unique request ID for the event. |
| Netskope.Alert.severity | String | Severity used by watchlist and malware alerts. |
| Netskope.Alert.site | String | For traffic_type = CloudApp, site = app, and for traffic_type = Web, it will be the second-level domain name + top-level domain name. For example, in “www.cnn.com”, it is “cnn.com”. |
| Netskope.Alert.src_country | String | User’s country’s two-letter country code as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.src_latitude | Number | Latitude of the user as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.src_location | String | User’s city as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.src_longitude | Number | Longitude of the user as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.src_region | String | Source state or region as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.src_time | Date | A timestamp associated with the source or event. |
| Netskope.Alert.src_timezone | String | Source timezone. Shows the long-format timezone designation. |
| Netskope.Alert.src_zipcode | String | Source zip code as determined by Maxmind or IP2Location Geolocation database. |
| Netskope.Alert.srcip | String | IP address of the source/user. |
| Netskope.Alert.telemetry_app | String | Typically, SaaS app websites use web analytics code within the pages to gather analytic data. When a SaaS app action or page is shown, there is subsequent traffic generated to tracking apps such as doubleclick.net, Optimizely, etc. These tracking apps are listed if applicable in the Telemetry App field. |
| Netskope.Alert.timestamp | Number | Timestamp when the event/alert happened. Event timestamp in Unix epoch format. |
| Netskope.Alert.traffic_type | String | “Type of the traffic: CloudApp or Web. CloudApp indicates CASB and web indicates HTTP traffic. Web traffic is only captured for inline access method. It is currently not captured for Risk Insights.” |
| Netskope.Alert.transaction_id | Number | Unique ID for a given request/response. |
| Netskope.Alert.type | String | Shows if it is an application event or a connection event. Application events are recorded to track user events inside a cloud app. Connection events show the actual HTTP connection. |
| Netskope.Alert.ur_normalized | String | All lowercase user email. |
| Netskope.Alert.url | String | URL of the application that the user visited as provided by the log or data plane traffic. |
| Netskope.Alert.user | String | User email. |
| Netskope.Alert.useragent | String | Browser HTTP user agent header. |
| Netskope.Alert.userip | String | IP address of the user. |
| Netskope.Alert.userkey | String | User ID or email. |
| Netskope.Alert._client_timeout | Number | Information related to client timeouts. |
| Netskope.Alert._dlp_backup_profile | String | Information related to DLP (Data Loss Prevention) backup profiles. |
| Netskope.Alert._nsp_dur_back | Number | Duration information for NSP (Network Security Platform) on the back end. |
| Netskope.Alert._nsp_dur_front | Number | Duration information for NSP on the front end. |
| Netskope.Alert._nsp_retrans_back | Number | Retransmission information for NSP on the back end. |
| Netskope.Alert._nsp_retrans_front | Number | Retransmission information for NSP on the front end. |
| Netskope.Alert._nsp_rtt_back | Number | Round-trip time information for NSP on the back end. |
| Netskope.Alert._nsp_rtt_front | Number | Round-trip time information for NSP on the front end. |
| Netskope.Alert._resource_name | String | The name associated with a resource. |
| Netskope.Alert._scan_source | String | Information indicating the source of a scan. |
| Netskope.Alert._tenant_max_file_size | Number | The maximum file size allowed for a tenant. |
| Netskope.Alert.all_policy_matches | String | Information related to policy matches. |
| Netskope.Alert.browser_version | String | Browser version. |
| Netskope.Alert.file_size | Number | Size of the file in bytes. |
| Netskope.Alert.file_type | String | File type. |
| Netskope.Alert.md5 | String | MD5 of the file. |
| Netskope.Alert.object | String | Name of the object which is being acted on. It could be a filename, folder name, report name, document name, etc. |
| Netskope.Alert.object_type | String | Type of the object which is being acted on. Object type could be a file, folder, report, document, message, etc. |
| Netskope.Alert.web_universal_connector | String | Universal web connector information. |
Command example
!netskope-alert-list start_time="2023-05-05 11:06" alert_type=policy limit=2
Context Example
{
"Netskope": {
"Alert": [
{
"_appsession_start": "yes",
"_category_id": "8",
"_category_name": "Collaboration",
"_category_tags": [10001, 564, 8],
"_content_version": 1687272302,
"_correlation_id": "011c0f84-9938-460b-8cbe-dab38fa6cb31",
"_creation_timestamp": 1687656279,
"_ef_received_at": 1687656276462,
"_event_id": "724d1174-d78c-4197-8243-4fbd3644b192",
"_forwarded_by": "msg-relayer",
"_gef_src_dp": "IL-TLV1",
"_id": "c3c98336e9d6807dd821b8dc",
"_insertion_epoch_timestamp": 1687656283,
"_nshostname": "dppool1-2-egress",
"_raw_event_inserted_at": 1687656276776,
"_service_identifier": "service-nsproxy",
"_session_begin": "1",
"_skip_geoip_lookup": "yes",
"_src_epoch_now": 1687667040,
"access_method": "Client",
"acked": "false",
"action": "block",
"activity": "Browse",
"alert": "yes",
"alert_id": "c3c98336e9d6807dd821b8dc",
"alert_name": "365 block",
"alert_type": "policy",
"app": "Microsoft Teams",
"app_session_id": 3379014715943843300,
"appcategory": "Collaboration",
"appsuite": "Office365",
"browser": "Native",
"browser_session_id": 2893692091617575400,
"category": "Collaboration",
"cci": 92,
"ccl": "excellent",
"connection_id": 1717056737521399300,
"count": 1,
"device": "Windows Device",
"device_classification": "unmanaged",
"domain": "config.teams.microsoft.com",
"dst_country": "US",
"dst_latitude": 47.682899475097656,
"dst_location": "Redmond",
"dst_longitude": -122.12090301513672,
"dst_region": "Washington",
"dst_timezone": "America/Los_Angeles",
"dst_zipcode": "N/A",
"dstip": "8.8.8.8",
"hostname": "DESKTOP-TOR2VO7",
"incident_id": 6782360912641091000,
"ja3": "a0e9f5d64349fb13191bc781f81f42e1",
"ja3s": "NotAvailable",
"managed_app": "no",
"managementID": "",
"netskope_pop": "IL-TLV1",
"notify_template": "block_page.html",
"nsdeviceuid": "A633E874-D3B2-0FB7-F5CC-AF89F428B182",
"organization_unit": "",
"os": "Windows 10",
"os_version": "Windows 10",
"other_categories": ["Test web Policy Beni", "Technology", "Collaboration"],
"page": "config.teams.microsoft.com",
"page_site": "Microsoft Teams",
"policy": "365 block",
"policy_id": "84BE7DC6087E38BCA19B3788C5E02A67 2023-06-22 14:42:51.404368",
"port": "443",
"protocol": "HTTPS/1.1",
"request_id": 2605870162901070000,
"severity": "unknown",
"site": "Microsoft Teams",
"src_country": "IL",
"src_latitude": 32.0803,
"src_location": "Tel Aviv",
"src_longitude": 34.7805,
"src_region": "Tel Aviv",
"src_time": "Sun Jun 25 04:24:00 2023",
"src_timezone": "Asia/Jerusalem",
"src_zipcode": "N/A",
"srcip": "8.8.8.8",
"telemetry_app": "",
"timestamp": "2023-06-25T01:24:36.000Z",
"traffic_type": "CloudApp",
"transaction_id": 6782360912641091000,
"type": "nspolicy",
"ur_normalized": "example@qmasters.co",
"url": "config.teams.microsoft.com/config/v1/ODSP_Sync_Client/23.119.0606.0001",
"user": "example@qmasters.co",
"useragent": "OneDrive-23.119.0606.0001",
"userip": "8.8.8.8",
"userkey": "example@qmasters.co"
},
{
"_appsession_start": "yes",
"_category_id": "8",
"_category_name": "Collaboration",
"_category_tags": [10001, 564, 8],
"_content_version": 1687272302,
"_correlation_id": "46647142-2f24-4802-b8f5-22814e80353a",
"_creation_timestamp": 1687659879,
"_ef_received_at": 1687659876494,
"_event_id": "6827a5eb-de85-48af-8eae-6d3034084fd6",
"_forwarded_by": "msg-relayer",
"_gef_src_dp": "IL-TLV1",
"_id": "da711d311019f02d79ebc8f4",
"_insertion_epoch_timestamp": 1687659883,
"_nshostname": "dppool1-2-egress",
"_raw_event_inserted_at": 1687659876771,
"_service_identifier": "service-nsproxy",
"_session_begin": "1",
"_skip_geoip_lookup": "yes",
"_src_epoch_now": 1687670640,
"access_method": "Client",
"acked": "false",
"action": "block",
"activity": "Browse",
"alert": "yes",
"alert_id": "da711d311019f02d79ebc8f4",
"alert_name": "365 block",
"alert_type": "policy",
"app": "Microsoft Teams",
"app_session_id": 4359394467077842400,
"appcategory": "Collaboration",
"appsuite": "Office365",
"browser": "Native",
"browser_session_id": 2893692091617575400,
"category": "Collaboration",
"cci": 92,
"ccl": "excellent",
"connection_id": 8981978357397935000,
"count": 1,
"device": "Windows Device",
"device_classification": "unmanaged",
"domain": "config.teams.microsoft.com",
"dst_country": "AT",
"dst_latitude": 48.2049,
"dst_location": "Vienna",
"dst_longitude": 16.3662,
"dst_region": "Vienna",
"dst_timezone": "Europe/Vienna",
"dst_zipcode": "1010",
"dstip": "8.8.8.8",
"hostname": "DESKTOP-TOR2VO7",
"incident_id": 1478029261577663500,
"ja3": "a0e9f5d64349fb13191bc781f81f42e1",
"ja3s": "NotAvailable",
"managed_app": "no",
"managementID": "",
"netskope_pop": "IL-TLV1",
"notify_template": "block_page.html",
"nsdeviceuid": "A633E874-D3B2-0FB7-F5CC-AF89F428B182",
"organization_unit": "",
"os": "Windows 10",
"os_version": "Windows 10",
"other_categories": ["Test web Policy Beni", "Technology", "Collaboration"],
"page": "config.teams.microsoft.com",
"page_site": "Microsoft Teams",
"policy": "365 block",
"policy_id": "84BE7DC6087E38BCA19B3788C5E02A67 2023-06-22 14:42:51.404368",
"port": "443",
"protocol": "HTTPS/1.1",
"request_id": 2605900362175087600,
"severity": "unknown",
"site": "Microsoft Teams",
"src_country": "IL",
"src_latitude": 32.0803,
"src_location": "Tel Aviv",
"src_longitude": 34.7805,
"src_region": "Tel Aviv",
"src_time": "Sun Jun 25 05:24:00 2023",
"src_timezone": "Asia/Jerusalem",
"src_zipcode": "N/A",
"srcip": "8.8.8.8",
"telemetry_app": "",
"timestamp": "2023-06-25T02:24:36.000Z",
"traffic_type": "CloudApp",
"transaction_id": 1478029261577663500,
"type": "nspolicy",
"ur_normalized": "example@qmasters.co",
"url": "config.teams.microsoft.com/config/v1/ODSP_Sync_Client/23.119.0606.0001",
"user": "example@qmasters.co",
"useragent": "OneDrive-23.119.0606.0001",
"userip": "8.8.8.8",
"userkey": "example@qmasters.co"
}
]
}
}
Human Readable Output
Alert List
Showing page 1.
Current page size: 2.
Alert Id Alert Name Alert Type Severity Action Activity Type Category Name Event Id Domain Dst Country Policy Port Protocol Md5 Timestamp c3c98336e9d6807dd821b8dc 365 block policy unknown block Browse nspolicy Collaboration 724d1174-d78c-4197-8243-4fbd3644b192 config.teams.microsoft.com US 365 block 443 HTTPS/1.1 2023-06-25T01:24:36.000Z da711d311019f02d79ebc8f4 365 block policy unknown block Browse nspolicy Collaboration 6827a5eb-de85-48af-8eae-6d3034084fd6 config.teams.microsoft.com AT 365 block 443 HTTPS/1.1 2023-06-25T02:24:36.000Z
netskope-event-list
Get events extracted from SaaS traffic. You may choose what events to receive with the event_type parameter. You must provide start_time and end_time, or insertion_start_time and insertion_end_time (If end_time or insertion_end_time isn’t provided - it defaults to the current date and time). Also, you cannot provide a combination of the options mentioned above.
Base Command
netskope-event-list
Input
| Argument Name | Description | Required |
|---|---|---|
| event_type | Select events by their type. Available types: page,application,audit,infrastructure,network. Possible values are: page, application, audit, infrastructure, network. | Required |
| query | Free query to filter the events. For example, “app eq Dropbox”. For more information, please visit Netskope documentation: https://docs.netskope.com/en/get-events-data.html. | Optional |
| start_time | Restrict events to those that have dates greater than the provided date string (for example “YYYY-MM-DDThh:mm”, “1 min ago”, “2 weeks ago”). When this argument is provided, the ‘end_time’ argument must also be provided. | Optional |
| end_time | Restrict events to those that have dates less than or equal to the provided date string (for example “YYYY-MM-DDThh:mm”, “1 min ago”, “2 weeks ago”). When this argument is provided, the ‘start_time’ argument must also be provided. If the start_time argument is provided and this argument is not - the default value will be set for now. | Optional |
| insertion_start_time | Restrict events to those that were inserted into the system after the provided date string (for example “YYYY-MM-DDThh:mm”, “1 min ago”, “2 weeks ago”). When this argument is provided, the ‘insertion_end_time’ argument must also be provided. | Optional |
| insertion_end_time | Restrict events to those that were inserted into the system before the provided date string (for example “YYYY-MM-DDThh:mm”, “1 min ago”, “2 weeks ago”). When this argument is provided, the ‘insertion_start_time’ argument must also be provided. If the insertion_start_time argument is provided and this argument is not - the default value will be set for now. | Optional |
| page | Page number of paginated results. Minimum value: 1. | Optional |
| limit | The maximum number of records to retrieve. Default is 50. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netskope.Event._appsession_start | String | Netskope event application session start. |
| Netskope.Event._category_id | String | Netskope event category ID. |
| Netskope.Event._category_name | String | Netskope event category name. |
| Netskope.Event._category_tags | Number | Netskope event category tags. |
| Netskope.Event._content_version | Number | Netskope event content version. |
| Netskope.Event._correlation_id | String | Netskope event correlation ID. |
| Netskope.Event._creation_timestamp | Number | Netskope event creation timestamp. |
| Netskope.Event._ef_received_at | Date | The timestamp indicating when the event was received. |
| Netskope.Event._event_id | String | Netskope event event ID. |
| Netskope.Event._forwarded_by | String | Netskope event forwarded by. |
| Netskope.Event._gef_src_dp | String | The source data path for the event. |
| Netskope.Event._id | String | Netskope event ID. |
| Netskope.Event._insertion_epoch_timestamp | Number | Netskope event insertion epoch timestamp |
| Netskope.Event._nshostname | String | The hostname associated with Netskope. |
| Netskope.Event._raw_event_inserted_at | Date | The date the Netskope raw event was inserted. |
| Netskope.Event._service_identifier | String | Netskope event service identifier. |
| Netskope.Event._session_begin | String | The timestamp marking the beginning of a session. |
| Netskope.Event._skip_geoip_lookup | String | Netskope event skip GeoIP lookup. |
| Netskope.Event._src_epoch_now | Number | A numeric value representing the source epoch. |
| Netskope.Event.access_method | String | Netskope event access method. |
| Netskope.Event.action | String | Netskope event action. |
| Netskope.Event.activity | String | Netskope event activity. |
| Netskope.Event.alert | String | Netskope event alert. |
| Netskope.Event.app | String | Netskope event app. |
| Netskope.Event.app_session_id | Number | Netskope event app session ID. |
| Netskope.Event.appcategory | String | Netskope event app category. |
| Netskope.Event.appsuite | String | Netskope event app suite. |
| Netskope.Event.browser | String | Netskope event browser. |
| Netskope.Event.browser_session_id | Number | Netskope event browser session ID. |
| Netskope.Event.category | String | Netskope event category. |
| Netskope.Event.cci | Number | Netskope event Cloud Confidence Index. |
| Netskope.Event.ccl | String | Netskope event Cloud Confidence Levels. |
| Netskope.Event.connection_id | Number | Netskope event connection ID. |
| Netskope.Event.count | Number | Netskope event count. |
| Netskope.Event.device | String | Netskope event device. |
| Netskope.Event.device_classification | String | Netskope event device classification. |
| Netskope.Event.dom | String | Netskope event Document Object Model (DOM). |
| Netskope.Event.dst_country | String | Netskope event destination country. |
| Netskope.Event.dst_latitude | Number | Netskope event destination latitude. |
| Netskope.Event.dst_location | String | Netskope event destination location. |
| Netskope.Event.dst_longitude | Number | Netskope event destination longitude. |
| Netskope.Event.dst_region | String | Netskope event destination region. |
| Netskope.Event.dst_timezone | String | Netskope event destination timezone. |
| Netskope.Event.dst_zipcode | String | Netskope event destination zip code. |
| Netskope.Event.dstip | String | Netskope event destination IP. |
| Netskope.Event.hostname | String | Netskope event host name. |
| Netskope.Event.incident_id | Number | Netskope event incident ID. |
| Netskope.Event.ja3 | String | A field indicating JA3 information. |
| Netskope.Event.ja3s | String | A field indicating JA3S information. |
| Netskope.Event.managed_app | String | Netskope event managed app. |
| Netskope.Event.managementID | String | Netskope event management ID. |
| Netskope.Event.netskope_pop | String | Netskope event Netskope POP. |
| Netskope.Event.notify_template | String | Netskope event notify template. |
| Netskope.Event.nsdeviceuid | String | Netskope event Netskope device UID. |
| Netskope.Event.organization_unit | String | Netskope event organization unit. |
| Netskope.Event.os | String | Netskope event operating system. |
| Netskope.Event.os_version | String | Netskope event operating system version. |
| Netskope.Event.other_categories | String | Netskope event other categories. |
| Netskope.Event.page | String | Netskope event page. |
| Netskope.Event.page_site | String | Netskope event page site. |
| Netskope.Event.policy | String | Netskope event policy. |
| Netskope.Event.policy_id | String | Netskope event policy ID. |
| Netskope.Event.port | Number | Netskope event port. |
| Netskope.Event.protocol | String | Netskope event protocol. |
| Netskope.Event.request_id | Number | Netskope event request ID. |
| Netskope.Event.severity | String | Netskope event severity. |
| Netskope.Event.site | String | Netskope event site. |
| Netskope.Event.src_country | String | Netskope event source country. |
| Netskope.Event.src_latitude | Number | Netskope event source latitude. |
| Netskope.Event.src_location | String | Netskope event source location. |
| Netskope.Event.src_longitude | Number | Netskope event source longitude. |
| Netskope.Event.src_region | String | Netskope event source region. |
| Netskope.Event.src_time | Date | Netskope event source time. |
| Netskope.Event.src_timezone | String | Netskope event source timezone. |
| Netskope.Event.src_zipcode | String | Netskope event source zip code. |
| Netskope.Event.srcip | String | Netskope event source IP. |
| Netskope.Event.telemetry_app | String | Netskope event telemetry app. |
| Netskope.Event.timestamp | Number | Netskope event timestamp. |
| Netskope.Event.traffic_type | String | Netskope event traffic type. |
| Netskope.Event.transaction_id | Number | Netskope event transaction ID. |
| Netskope.Event.type | String | Netskope event type. |
| Netskope.Event.ur_normalized | String | All lowercase user email. |
| Netskope.Event.url | String | Netskope event URL. |
| Netskope.Event.user | String | Netskope event user. |
| Netskope.Event.useragent | String | Netskope event user agent. |
| Netskope.Event.userip | String | Netskope event user IP. |
| Netskope.Event.userkey | String | Netskope event user key. |
Command example
!netskope-event-list event_type=page start_time="10 days ago" limit=2
Human Readable Output
Event List
Showing page 1.
Current page size: 2.
No entries.
netskope-url-list-update
Update the URL List with the values provided. please note that this command overrides the list.
Base Command
netskope-url-list-update
Input
| Argument Name | Description | Required |
|---|---|---|
| url_list_id | The URL list ID to update (use netskope-url-list-list command to get URL list ID). | Required |
| name | The updated URL list name. | Required |
| urls | The updated URL list items (For Exact - Enter URLs like .example.com, or IP addresses, separated by a new line. For Regex - Enter URLs like ^client[0-9]\.google\.com , ^app\.slack\.com/./netskope, or ^google.com, separated by a new line). | Required |
| list_type | The updated URL list type. Possible values are: exact, regex. | Required |
| deploy | Whether to deploy URL list changes or not. Default is False. Possible values are: True, False. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netskope.URLList.id | Number | Netskope URL list ID. |
| Netskope.URLList.name | String | Netskope URL list name. |
| Netskope.URLList.data.urls | String | Netskope URL list data URLs. |
| Netskope.URLList.data.type | String | Netskope URL list data type. |
| Netskope.URLList.data.json_version | Number | Netskope URL list data JSON version. |
| Netskope.URLList.modify_by | String | Netskope URL list modify by. |
| Netskope.URLList.modify_time | Date | Netskope URL list modify time. |
| Netskope.URLList.modify_type | String | Netskope URL list modify type. |
| Netskope.URLList.pending | String | Netskope URL list pending status. |
Command example
!netskope-url-list-update url_list_id=11 name="QMASTERS list" urls="google.com" list_type=regex deploy=false
Context Example
{
"Netskope": {
"URLList": {
"id": 11,
"json_version": 2,
"modify_by": "Tal New Token",
"modify_time": "2023-07-18",
"modify_type": "Edited",
"name": "QMASTERS list",
"pending": "pending",
"type": "regex",
"urls": ["google.com"]
}
}
}
Human Readable Output
URL List
Id Json Version Modify By Modify Time Modify Type Name Pending Type Urls 11 2 Tal New Token 2023-07-18 Edited QMASTERS list pending regex google.com
netskope-url-list-create
Create a new URL list.
Base Command
netskope-url-list-create
Input
| Argument Name | Description | Required |
|---|---|---|
| name | The unique name for the URL list. | Required |
| urls | The URL list items (For Exact - Enter URLs like .example.com, or IP addresses, separated by a new line. For Regex - Enter URLs like ^client[0-9]\.google\.com , ^app\.slack\.com/./netskope, or ^google.com, separated by a new line). | Required |
| list_type | The URL list type. Possible values are: exact, regex. | Required |
| deploy | Whether to deploy URL list changes or not. Default is False. Possible values are: True, False. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netskope.URLList.id | Number | Netskope URL list ID. |
| Netskope.URLList.name | String | Netskope URL list name. |
| Netskope.URLList.data.urls | String | Netskope URL list data URLs. |
| Netskope.URLList.data.type | String | Netskope URL list data type. |
| Netskope.URLList.data.json_version | Number | Netskope URL list data JSON version. |
| Netskope.URLList.modify_type | String | Netskope URL list modify type. |
| Netskope.URLList.modify_by | String | Netskope URL list modify by. |
| Netskope.URLList.modify_time | Date | Netskope URL list modify time. |
| Netskope.URLList.pending | String | Netskope URL list pending status. |
Command example
!netskope-url-list-create name="New QMASTERS list" urls="xsoar.com,qmasters.com,google.com" list_type=regex deploy=false
Context Example
{
"Netskope": {
"URLList": {
"id": 12,
"json_version": 2,
"modify_by": "Tal New Token",
"modify_time": "2023-07-18",
"modify_type": "Created",
"name": "New QMASTERS list",
"pending": "pending",
"type": "regex",
"urls": ["xsoar.com", "qmasters.com", "google.com"]
}
}
}
Human Readable Output
URL List
Id Json Version Modify By Modify Time Modify Type Name Pending Type Urls 12 2 Tal New Token 2023-07-18 Created New QMASTERS list pending regex xsoar.com,
qmasters.com,
google.com
netskope-url-lists-list
Get all URL Lists or a specific by specifying the list ID.
Base Command
netskope-url-lists-list
Input
| Argument Name | Description | Required |
|---|---|---|
| url_list_id | The URL list ID to get. | Optional |
| pending | Get a list of only applied or pending URL lists. Possible values are: applied, pending. | Optional |
| field | Comma separated data values to return in response call (for example: name, id, data, modify_by, modify_time, modify_type, pending). Defaults to all values. | Optional |
| all_results | Whether to retrieve all results or not. Defaults is false. Possible values are: True, False. | Optional |
| limit | The maximum number of records to retrieve. Default is 50. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netskope.URLList.id | Number | Netskope URL list ID. |
| Netskope.URLList.name | String | Netskope URL list name. |
| Netskope.URLList.data.urls | String | Netskope URL list data URLs. |
| Netskope.URLList.modify_by | String | Netskope URL list modify by. |
| Netskope.URLList.modify_time | Date | Netskope URL list modify time. |
| Netskope.URLList.modify_type | String | Netskope URL list modify type. |
| Netskope.URLList.pending | String | Netskope URL list pending status. |
Command example
!netskope-url-lists-list
Context Example
{
"Netskope": {
"URLList": [
{
"data": {
"json_version": 2,
"type": "exact",
"urls": ["g.g"]
},
"id": 1,
"modify_by": "example@qmasters.co",
"modify_time": "2023-07-16T00:00:00.000Z",
"modify_type": "Edited",
"name": "myList",
"pending": 0
},
{
"data": {
"json_version": 2,
"type": "regex",
"urls": ["google.com"]
},
"id": 2,
"modify_by": "Tal New Token",
"modify_time": "2023-07-18T00:00:00.000Z",
"modify_type": "Edited",
"name": "NewURLList",
"pending": 0
},
{
"data": {
"json_version": 2,
"type": "exact",
"urls": ["google.com", "www.abc.com", "example.com", "lulu.com"]
},
"id": 4,
"modify_by": "Netskope REST API",
"modify_time": "2023-07-05T10:24:57.000Z",
"modify_type": "Edited",
"name": "Tal-newURLlist",
"pending": 0
},
{
"data": {
"json_version": 2,
"type": "exact",
"urls": ["google.com", "example.com", "lulu.com"]
},
"id": 5,
"modify_by": "Netskope REST API",
"modify_time": "2023-07-05T00:00:00.000Z",
"modify_type": "Created",
"name": "New URL list",
"pending": 0
},
{
"data": {
"json_version": 2,
"type": "exact",
"urls": ["google.com", "example.com", "lulu.com"]
},
"id": 6,
"modify_by": "Netskope REST API",
"modify_time": "2023-07-05T00:00:00.000Z",
"modify_type": "Created",
"name": "New URL list 2",
"pending": 0
},
{
"data": {
"json_version": 2,
"type": "regex",
"urls": ["xsoar.com", "qmasters.com"]
},
"id": 8,
"modify_by": "Netskope REST API",
"modify_time": "2023-07-17T00:00:00.000Z",
"modify_type": "Created",
"name": "NewNewURLlist",
"pending": 0
},
{
"data": {
"json_version": 2,
"type": "regex",
"urls": ["xsoar.com", "qmasters.com"]
},
"id": 9,
"modify_by": "Netskope REST API",
"modify_time": "2023-07-17T00:00:00.000Z",
"modify_type": "Created",
"name": "NewNewURLlist1",
"pending": 0
}
]
}
}
Human Readable Output
URL List
Id Json Version Modify By Modify Time Modify Type Name Pending Type Urls 1 2 example@qmasters.co 2023-07-16T00:00:00.000Z Edited myList applied exact g.g 2 2 Tal New Token 2023-07-18T00:00:00.000Z Edited NewURLList applied regex google.com 4 2 Netskope REST API 2023-07-05T10:24:57.000Z Edited Tal-newURLlist applied exact google.com,
www.abc.com,
example.com,
lulu.com5 2 Netskope REST API 2023-07-05T00:00:00.000Z Created New URL list applied exact google.com,
example.com,
lulu.com6 2 Netskope REST API 2023-07-05T00:00:00.000Z Created New URL list 2 applied exact google.com,
example.com,
lulu.com8 2 Netskope REST API 2023-07-17T00:00:00.000Z Created NewNewURLlist applied regex xsoar.com,
qmasters.com9 2 Netskope REST API 2023-07-17T00:00:00.000Z Created NewNewURLlist1 applied regex xsoar.com,
qmasters.com
netskope-url-list-delete
Delete a URL list by the list ID.
Base Command
netskope-url-list-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| url_list_id | The URL list ID to delete (use netskope-url-list-list to get the URL list ID). | Required |
| deploy | Whether to deploy URL list changes or not. Default is False. Possible values are: True, False. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netskope.URLList.id | Number | Netskope URL list ID. |
| Netskope.URLList.name | String | Netskope URL list name. |
Command example
!netskope-url-list-delete url_list_id=10
Context Example
{
"Netskope": {
"URLList": {
"data": {
"json_version": 2,
"type": "regex",
"urls": ["xsoar.com", "qmasters.com"]
},
"id": 10,
"modify_by": "Netskope REST API",
"modify_time": "2023-07-17T00:00:00.000Z",
"modify_type": "Deleted",
"name": "TalURLlist",
"pending": 1
}
}
}
Human Readable Output
The URL list 10 was deleted successfully
netskope-client-list
Get information about Netskope SCIM users. The command provides a list of users who have been imported into the Netskope tenant through SCIM integration. Users imported through other methods, such as manual CSV import or manual creation, will not be included in the returned results.
Base Command
netskope-client-list
Input
| Argument Name | Description | Required |
|---|---|---|
| filter | Filter the Netskope user by ‘key eq value’ template. For example: userName eq “someUserName” OR externalId eq “User-Ext_id”. | Optional |
| page | Page number of paginated results. Minimum value: 1. | Optional |
| limit | The maximum number of records to retrieve. Default is 50. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netskope.Client.id | Number | Netskope client ID. |
| Netskope.Client.name | String | Netskope client name. |
| Netskope.Client.userName | String | Netskope client username. |
| Netskope.Client.externalId | String | Netskope client external ID. |
| Netskope.Client.active | Boolean | Netskope client activate. |
| Netskope.Client.emails | String | Netskope client emails. |
Command example
!netskope-client-list page=1 limit=2
Context Example
{
"Netskope": {
"Client": [
{
"active": true,
"client_id": "6a4dbb07-f465-4a6c-8af2-1c84ced65010",
"emails": ["email1@netskope.local"],
"family_name": "last_name",
"given_name": "first_name",
"user_name": "upn1"
},
{
"active": true,
"client_id": "f8d26597-e4a4-400d-a24b-40318a9e80e5",
"emails": ["email11@netskope.local"],
"family_name": "last_name1",
"given_name": "first_name1",
"user_name": "upn2"
}
]
}
}
Human Readable Output
Client List
Showing page 1.
Current page size: 2.
Client Id User Name Given Name Family Name Emails Active 6a4dbb07-f465-4a6c-8af2-1c84ced65010 upn1 first_name last_name email1@netskope.local true f8d26597-e4a4-400d-a24b-40318a9e80e5 upn2 first_name1 last_name1 email11@netskope.local true
netskope-url-list-add
Update the URL list with the values provided. Note that this command appends the list.
Base Command
netskope-url-list-add
Input
| Argument Name | Description | Required |
|---|---|---|
| url_list_id | The URL list ID to update (use netskope-url-list-list command to get URL list ID). | Required |
| urls | The updated URL list items (For Exact - Enter URLs like .example.com, or IP addresses, separated by a new line. For Regex - Enter URLs like ^client[0-9]\.google\.com , ^app\.slack\.com/./netskope, or ^google.com, separated by a new line). | Required |
| list_type | The updated URL list type. Possible values are: exact, regex. | Required |
| deploy | Whether to deploy URL list changes or not. Possible values are: True, False. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netskope.URLList.id | Number | Netskope URL list ID. |
| Netskope.URLList.name | String | Netskope URL list name. |
| Netskope.URLList.data.urls | String | Netskope URL list data URLs. |
| Netskope.URLList.data.type | String | Netskope URL list data type. |
| Netskope.URLList.data.json_version | Number | Netskope URL list data JSON version. |
| Netskope.URLList.modify_by | String | Netskope URL list modify by. |
| Netskope.URLList.modify_time | Date | Netskope URL list modify time. |
| Netskope.URLList.modify_type | String | Netskope URL list modify type. |
| Netskope.URLList.pending | Number | Netskope URL list pending. |
netskope-incident-dlp-list
Fetch DLP incidents.
Base Command
netskope-incident-dlp-list
Input
| Argument Name | Description | Required |
|---|---|---|
| start_time | Restrict incidents to those that have updated dates greater than the provided date string (for example “YYYY-MM-DDThh:mm”, “1 min ago”, “2 weeks ago”). Default is ‘1 hour ago’. Default is 1 hour ago. | Optional |
| end_time | Restrict incidents to those that have updated dates less than or equal to the provided date string (for example “YYYY-MM-DDThh:mm”, “1 min ago”, “2 weeks ago”). Default is ‘now’. Default is now. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Netskope.Incident._id | String | |
| Netskope.Incident.access_method | String | |
| Netskope.Incident.acting_user | String | |
| Netskope.Incident.activity | String | |
| Netskope.Incident.app | String | |
| Netskope.Incident.app_session_id | Number | |
| Netskope.Incident.assignee | String | |
| Netskope.Incident.connection_id | Number | |
| Netskope.Incident.dlp_incident_id | Number | |
| Netskope.Incident.dlp_match_info | Unknown | |
| Netskope.Incident.dlp_match_info.dlp_action | String | |
| Netskope.Incident.dlp_match_info.dlp_forensic_id | Number | |
| Netskope.Incident.dlp_match_info.dlp_policy | String | |
| Netskope.Incident.dlp_match_info.dlp_profile_name | String | |
| Netskope.Incident.dlp_match_info.dlp_rules | Unknown | |
| Netskope.Incident.dlp_match_info.dlp_rules.dlp_incident_rule_count | Number | |
| Netskope.Incident.dlp_match_info.dlp_rules.dlp_match_type | String | |
| Netskope.Incident.dlp_match_info.dlp_rules.dlp_rule_name | String | |
| Netskope.Incident.dlp_match_info.dlp_rules.dlp_rule_severity | String | |
| Netskope.Incident.dlp_parent_id | Number | |
| Netskope.Incident.dst_location | String | |
| Netskope.Incident.file_lang | String | |
| Netskope.Incident.file_size | Number | |
| Netskope.Incident.file_type | String | |
| Netskope.Incident.from_user | String | |
| Netskope.Incident.instance_id | String | |
| Netskope.Incident.md5 | String | |
| Netskope.Incident.object | String | |
| Netskope.Incident.object_id | String | |
| Netskope.Incident.object_type | String | |
| Netskope.Incident.severity | String | |
| Netskope.Incident.site | String | |
| Netskope.Incident.src_location | String | |
| Netskope.Incident.status | String | |
| Netskope.Incident.timestamp | Number | |
| Netskope.Incident.title | String | |
| Netskope.Incident.true_obj_category | String | |
| Netskope.Incident.true_obj_type | String | |
| Netskope.Incident.url | String | |
| Netskope.Incident.user | String | |
| Netskope.Incident.owner_pdl | String | |
| Netskope.Incident.classification | String | |
| Netskope.Incident.to_user | String | |
| Netskope.Incident.cc | String | |
| Netskope.Incident.owner | String | |
| Netskope.Incident.destination_site | String | |
| Netskope.Incident.user_id | String | |
| Netskope.Incident.instance | String | |
| Netskope.Incident.channel | String | |
| Netskope.Incident.bcc | String | |
| Netskope.Incident.inline_dlp_match_info | Unknown | |
| Netskope.Incident.exposure | String | |
| Netskope.Incident.file_path | String | |
| Netskope.Incident.original_file_snapshot_id | String | |
| Netskope.Incident.destination_app | String | |
| Netskope.Incident.latest_incident_id | Number | |
| Netskope.Incident.dlp_file | String | |
| Netskope.Incident.zip_file_id | String | |
| Netskope.Incident.referer | String | |
| Netskope.Incident.destination_instance_id | String |
Command example
!netskope-incident-dlp-list
Context Example
{
"Netskope": {
"Incident": [
{
"_id": "dg",
"access_method": "Client",
"acting_user": "d@d.co",
"activity": "Upload",
"app": "Microsoft Office 365 OneDrive for Business",
"app_session_id": 6089117609268013425,
"assignee": "d@d.co",
"connection_id": 1888383367374049276,
"dlp_incident_id": 7061311227778495851,
"dlp_match_info": [
{
"dlp_action": "block",
"dlp_forensic_id": 7061311227778495851,
"dlp_policy": "DLP test policy - Beni",
"dlp_profile_name": "test dlp profile -beni",
"dlp_rules": [
{
"dlp_incident_rule_count": 1,
"dlp_match_type": "FileFilter",
"dlp_rule_name": "test dlp profile - beni",
"dlp_rule_severity": "Medium"
}
]
}
],
"dlp_parent_id": 7061311227778495851,
"dst_location": "Redmond",
"file_lang": "Unknown",
"file_size": 10,
"file_type": "text/plain",
"from_user": "d@d.co",
"instance_id": "d",
"md5": "fsd",
"object": "d.txt",
"object_id": "01",
"object_type": "File",
"severity": "Critical",
"site": "Microsoft Office 365 OneDrive for Business",
"src_location": "Tel Aviv",
"status": "in_progress",
"timestamp": 1710928898,
"title": "d.txt",
"true_obj_category": "Text",
"true_obj_type": "Plain Text file",
"url": "v1.g.f",
"user": "sdf",
"owner_pdl": "",
"classification": "",
"to_user": "",
"cc": "",
"owner": "",
"destination_site": "",
"user_id": "",
"instance": "",
"channel": "",
"bcc": "",
"inline_dlp_match_info": [],
"exposure": "",
"file_path": "",
"original_file_snapshot_id": "",
"destination_app": "",
"latest_incident_id": 0,
"dlp_file": "",
"zip_file_id": "",
"referer": "",
"destination_instance_id": ""
}
]
}
}
Human Readable Output
Client List
Showing page 1.
Current page size: 2.
Object Id Status Severity Activity Assignee Timestamp Acting User App Instance Id Object Type 12 new High FormPost None 1725903291 None Form
get-mapping-fields
Returns the list of fields for an incident type.
Base Command
get-mapping-fields
Input
| Argument Name | Description | Required |
| —————– | ————— | ———— |
Context Output
There is no context output for this command.
update-remote-system
Updates the remote incident or detection with local incident or detection changes. This method is only used for debugging purposes and will not update the current incident or detection.
Base Command
update-remote-system
Input
| Argument Name | Description | Required |
| —————– | ————— | ———— |
Context Output
There is no context output for this command.
get-remote-data
Gets remote data from a remote incident. This method does not update the current incident, and should be used for debugging purposes.
Base Command
get-remote-data
Input
| Argument Name | Description | Required |
|---|---|---|
| id | The ticket ID. | Required |
| lastUpdate | Retrieves entries that were created after lastUpdate. | Required |
Context Output
There is no context output for this command.
get-modified-remote-data
Gets the list of incidents that were modified since the last update time. Note that this method is here for debugging purposes. The get-modified-remote-data command is used as part of a Mirroring feature, which is available in Cortex XSAIM/XSOAR from version 6.1.
Base Command
get-modified-remote-data
Input
| Argument Name | Description | Required |
|---|---|---|
| lastUpdate | A date string in local time representing the last time the incident was updated. The incident is only returned if it was modified after the last update time. | Optional |
Context Output
There is no context output for this command.
Incident Mirroring
You can enable incident mirroring between Cortex XSAIM/XSOAR incidents and Netskope (API v2) LOCAL corresponding events (available from Cortex XSAIM/XSOAR version 6.0.0).
To set up the mirroring:
- Enable Fetching incidents in your instance configuration.
-
In the Mirroring Direction integration parameter, select in which direction the incidents should be mirrored:
Option Description None Turns off incident mirroring. Incoming Any changes in Netskope (API v2) LOCAL events (mirroring incoming fields) will be reflected in Cortex XSOAR incidents. Outgoing Any changes in Cortex XSAIM/XSOAR incidents will be reflected in Netskope (API v2) LOCAL events (outgoing mirrored fields). Incoming and Outgoing - Optional: Check the Close Mirrored XSAIM/XSOAR Incident integration parameter to close the Cortex XSAIM/XSOAR incident when the corresponding event is closed in Netskope (API v2) LOCAL.
Newly fetched incidents will be mirrored in the chosen direction. However, this selection does not affect existing incidents.
Important Note: To ensure the mirroring works as expected, mappers are required, both for incoming and outgoing, to map the expected fields in Cortex XSAIM/XSOAR and Netskope (API v2) LOCAL.
Configuration parameters
url— Server URL (required)proxy— Use system proxy settingsinsecure— Trust any certificate (not secure)credentials— (required)first_fetch— First fetch timestampmax_fetch— Maximum incidents per fetchmax_events_fetch— Maximum Netskope events per fetch. Max value is 200.max_dlp_incidents_fetch— Maximum Netskope DLP incidents per fetch. Max value is 200.fetch_events— Fetch Eventsfetch_dlp_incidents— Fetch DLP incidentsevent_types— Event types to fetch.alerts_query— Alerts Queryevents_query— Events QueryincidentType— Incident typeisFetch— Fetch incidentsuser_email— User EmailincidentFetchInterval— Incidents Fetch Intervalmirror_direction— Incident Mirroring Directionclose_incident— Close Mirrored XSOAR Incidentclose_netskope_incident— Close Mirrored Netskope Incident
Commands (13)
-
get-mapping-fieldsReturns the list of fields for an incident type.
-
get-modified-remote-dataGets the list of incidents that were modified since the last update time. Note that this method is here for debugging purposes. The get-modified-remote-data command is used as part of a Mirroring feature, which is available in Cortex XSOAR from version 6.1.
-
get-remote-dataGets remote data from a remote incident. This method does not update the current incident, and should be used for debugging purposes.
-
netskope-alert-listGet alerts generated by Netskope. You may choose what alerts to receive with the alert_type parameter. You must provide start_time and end_time, or insertion_start_time and insertion_end_time. (Note that if end_time or insertion_end_time aren't provided. the date time would be set as now.) You cannot provide a combination of the options mentioned above.
-
netskope-client-listGet information about Netskope SCIM users. The command provides a list of users who have been imported into the Netskope tenant through SCIM integration. Users imported through other methods, such as manual CSV import or manual creation, will not be included in the returned results.
-
netskope-event-listGet events extracted from SaaS traffic. You may choose what events to receive with the event_type parameter. You must provide start_time and end_time, or insertion_start_time and insertion_end_time. (Note that if end_time or insertion_end_time aren't provided, the date time would be set as now.) You cannot provide a combination of the options mentioned above.
-
netskope-incident-dlp-listFetch DLP incidents by update time. The maximum recommended time range should be no more from 3 days.
-
netskope-url-list-addUpdate the URL list with the values provided. Note that this command appends the list.
-
netskope-url-list-createCreate a new URL list.
-
netskope-url-list-deleteDelete a URL list by the list ID.
-
netskope-url-list-updateUpdate the URL list with the values provided. Note that this command overrides the list.
-
netskope-url-lists-listGet all URL lists or a specific URL list by specifying the list ID.
-
update-remote-systemUpdates the remote incident or detection with local incident or detection changes. This method is only used for debugging purposes and will not update the current incident or detection.
import copy from collections.abc import Callable from http import HTTPStatus from typing import Any, NamedTuple import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 MAX_IDS_NUMBER = 289262 DEFAULT_WAIT_TIME = 5 MIN_PAGE_NUM = 1 MAX_PAGE_SIZE = 50 MIN_PAGE_SIZE = 1 MAX_LIMIT = 50 MIN_LIMIT = 1 MAX_FETCH_PER_EVENT_TYPE = 50 JS_NUMBER_LIMIT = 2**53 - 1 TIME_FORMAT = "%d-%m-%Y %H:%M" ALERT_HEADERS = [ "alert_id", "alert_name", "alert_type", "severity", "action", "activity", "type", "acked", "_category_name", "_event_id", "domain", "dst_country", "policy", "port", "protocol", "md5", "timestamp", ] EVENT_HEADERS = { "application": [ "event_id", "alert", "action", "activity", "category", "hostname", "policy", "severity", "type", "useragent", "timestamp", ], "page": [ "event_id", "category", "domain", "page", "type", "user", "appcategory", "bypass_reason", "src_location", "srcip", "dst_location", "dstip", "timestamp", ], "audit": [ "event_id", "audit_log_event", "severity_level", "count", "supporting_data", "timestamp", ], "infrastructure": [ "event_id", "hostname", "timestamp", "serial", "metric_name", "metric_value", ], "network": [ "event_id", "category", "domain", "page", "type", "user", "policy", "action", "protocol", "src_location", "srcip", "dst_location", "dstip", "timestamp", ], } URL_HEADER = [ "id", "name", "urls", "type", "pending", "modify_by", "modify_time", "modify_type", ] INCIDENT_HEADERS = [ "object_id", "status", "severity", "activity", "assignee", "timestamp", "acting_user", "app", "instance_id", "object_type", ] MIRRORING_FIELDS = ["status", "severity", "original_status", "original_severity"] MIRROR_DIRECTION_MAPPING = { "Incoming": "In", "Outgoing": "Out", "Incoming and Outgoing": "Both", } class Pagination(NamedTuple): updated_page: int limit: int pagination_message: str class TimeArgs(NamedTuple): start_time_number: int | None end_time_number: int | None insertion_start_time_number: int | None insertion_end_time_number: int | None class Client(BaseClient): def __init__( self, server_url: str, api_token: str, verify: bool = False, proxy: bool = False, user_mail: str | None = None, ): self.user_mail = user_mail headers = {"Netskope-Api-Token": api_token} super().__init__(base_url=server_url, verify=verify, proxy=proxy, headers=headers) def list_alert( self, page: int, limit: int, alert_type: str | None = None, query: str | None = None, acked: bool | None = None, start_time: int | None = None, end_time: int | None = None, insertion_start_time: int | None = None, insertion_end_time: int | None = None, ) -> dict[str, Any]: """Get alerts generated by Netskope. Args: page (int): Page number of paginated results. limit (int): The maximum number of records to retrieve. alert_type (Optional[str], optional): Alert type. Defaults to None. query (Optional[str], optional): Free query to filter the alerts. Defaults to None. acked (Optional[bool], optional): Whether to retrieve acknowledged alerts or not. Defaults to None. start_time (Optional[int], optional): Restrict alerts to those that have dates greater than the provided date. Defaults to None. end_time (Optional[int], optional): Restrict alerts to those that have dates less than or equal to the provided date. Defaults to None. insertion_start_time (Optional[int], optional): Restrict alerts to those that were inserted to the system after the provided date. Defaults to None. insertion_end_time (Optional[int], optional): Restrict alerts to those that were inserted to the system before the provided date. Defaults to None. Returns: Dict[str, Any]: API response from Netskope. """ params = assign_params( limit=limit, offset=page, starttime=start_time, endtime=end_time, insertionstarttime=insertion_start_time, insertionendtime=insertion_end_time, type=alert_type, query=query, acked=acked, ) return self._http_request("GET", "api/v2/events/data/alert", params=params) def list_event( self, page: int, limit: int, event_type: str, start_time: int | None = None, end_time: int | None = None, insertion_start_time: int | None = None, insertion_end_time: int | None = None, query: str | None = None, ) -> dict[str, Any]: """Get events from Netskope. Args: page (int): Page number of paginated results. limit (int): The maximum number of records to retrieve. event_type (str): Event type. start_time (Optional[int], optional): Restrict events to those that have dates greater than the provided date. Defaults to None. end_time (Optional[int], optional): Restrict events to those that have dates less than or equal to the provided date . Defaults to None. insertion_start_time (Optional[int], optional): Restrict events to those that were inserted to the system after the provided date. Defaults to None. insertion_end_time (Optional[int], optional): Restrict events to those that were inserted to the system before the provided date. Defaults to None. query (Optional[str], optional): Free query to filter the events. Defaults to None. Returns: Dict[str, Any]: API response from Netskope. """ params = assign_params( limit=limit, offset=page, starttime=start_time, endtime=end_time, insertionstarttime=insertion_start_time, insertionendtime=insertion_end_time, query=query, ) return self._http_request("GET", f"api/v2/events/data/{event_type}", params=params) def update_url_list( self, url_list_id: str, name: str | None = None, urls: list[str] | None = None, list_type: str | None = None, ) -> dict[str, Any]: """Update (override) the given URL list. Args: url_list_id (str): URL list ID. name (str): URL list name. urls (List[str]): URL lists. list_type (str): URL list type. Returns: Dict[str, Any]: API response from Netskope. """ data = { "data": {"type": list_type, "urls": urls}, "name": name, } return self._http_request("PUT", f"api/v2/policy/urllist/{url_list_id}", json_data=data) def patch_url_list( self, url_list_id: str, urls: list[str] | None = None, list_type: str | None = None, ) -> dict[str, Any]: """Update the given URL list. Args: url_list_id (str): URL list ID. urls (List[str]): URL lists. list_type (str): URL list type. Returns: Dict[str, Any]: API response from Netskope. """ data = {"data": {"type": list_type, "urls": urls}} return self._http_request("PATCH", f"api/v2/policy/urllist/{url_list_id}/append", json_data=data) def create_url_list( self, name: str, urls: list[str], list_type: str, ) -> dict[str, Any]: """Create URL list. Args: name (str): URL list name. urls (List[str]): URL lists. list_type (str): URL list type. Returns: Dict[str, Any]: API response from Netskope. """ data = { "data": {"type": list_type, "urls": urls}, "name": name, } return self._http_request("POST", "api/v2/policy/urllist", json_data=data) def list_url_list( self, url_list_id: str | None, pending: int | None = None, field: list[str] | None = None, ) -> dict[str, Any]: """Get all URL Lists or a specific URL list by the list ID. Args: url_list_id (Optional[str]): _description_ pending (Optional[int]): _description_ field (List[str]): _description_ Returns: Dict[str, Any]: API response from Netskope. """ params = assign_params( pending=pending, field=field, ) url_suffix = f"/{url_list_id}" if url_list_id else "" return self._http_request( "GET", f"api/v2/policy/urllist{url_suffix}", params=params, ) def delete_url_list(self, url_list_id: str) -> dict[str, Any]: """Delete a URL list by the list ID. Args: url_list_id (str): URL list ID. Returns: Dict[str, Any]: API response from Netskope. """ return self._http_request( "DELETE", f"api/v2/policy/urllist/{url_list_id}", ) def list_client( self, page: int, limit: int, client_filter: str | None = None, ) -> dict[str, Any]: """Get information about Netskope SCIM users. Args: page (int): Page number of paginated results. limit (int): The maximum number of records to retrieve. client_filter (str, optional): Filter the Netskope user by 'key eq value' template. Defaults to None. Returns: Dict[str, Any]: API response from Netskope. """ params = assign_params(count=limit, startIndex=page, filter=client_filter) return self._http_request( "GET", "api/v2/scim/Users", params=params, ) def deploy_url_list(self) -> dict[str, Any]: """Deploy URL list changes. Returns: Dict[str, Any]: API response from Netskope. """ return self._http_request( "POST", "api/v2/policy/urllist/deploy", ) def list_dlp_incident(self, timestamp: int) -> dict[str, Any]: """Fetch DLP incidents. Args: timestamp (int): The timestamp to filter by. Returns: dict[str, Any]: The API response with large integers converted to strings. """ response = self._http_request( "GET", url_suffix="api/v2/events/dataexport/events/incident", params={"operation": timestamp}, retries=10, status_list_to_retry=[409, 429], backoff_factor=DEFAULT_WAIT_TIME, ) # Convert large integers to strings to prevent JavaScript precision loss if incidents := response.get("result"): for incident in incidents: convert_large_integers_to_strings(incident) return response def update_dlp_incident( self, object_id: str, field: str, old_value: str, new_value: str, ) -> dict[str, Any]: """Update DLP incident. Args: object_id (str): The incident object ID. field (str): The field to update. old_value (str): The old value. new_value (str): The new value. Returns: dict[str, Any]: The API response. """ return self._http_request( "PATCH", url_suffix="api/v2/incidents/update", json_data=remove_empty_elements( { "payload": [ { "object_id": object_id, "field": field, "old_value": old_value, "new_value": new_value, "user": self.user_mail, } ] } ), ) def list_alert_command( client: Client, args: dict[str, Any], ) -> CommandResults: """Get alerts generated by Netskope. Args: client (Client): Netskope API client. args (Dict[str, Any]): command arguments. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ pagination_data = pagination(args) page = pagination_data.updated_page limit = pagination_data.limit pagination_message = pagination_data.pagination_message alert_type = args.get("alert_type") query = args.get("query") acked = optional_arg_to_boolean(args.get("retrieve_acknowledged")) time_args = convert_time_args_to_num(args) start_time = time_args.start_time_number end_time = time_args.end_time_number insertion_start_time = time_args.insertion_start_time_number insertion_end_time = time_args.insertion_end_time_number response = client.list_alert( page=page, limit=limit, start_time=start_time, end_time=end_time, insertion_start_time=insertion_start_time, insertion_end_time=insertion_end_time, alert_type=alert_type, query=query, acked=acked, ) output = response["result"] for alert in output: alert["alert_id"] = alert["_id"] alert["timestamp"] = timestamp_to_datestring(alert["timestamp"] * 1000) convert_large_integers_to_strings(alert) readable_output = tableToMarkdown( name="Alert List", metadata=pagination_message, t=remove_empty_elements(output), headers=ALERT_HEADERS, headerTransform=string_to_table_header, ) return CommandResults( readable_output=readable_output, outputs_prefix="Netskope.Alert", outputs_key_field="id", outputs=output, raw_response=response, ) def list_event_command( client: Client, args: dict[str, Any], ) -> CommandResults: """Get events extracted from SaaS traffic. Args: client (Client): Netskope API client. args (Dict[str, Any]): command arguments. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ pagination_data = pagination(args) page = pagination_data.updated_page limit = pagination_data.limit pagination_message = pagination_data.pagination_message event_type = args["event_type"] query = args.get("query") time_args = convert_time_args_to_num(args) start_time = time_args.start_time_number end_time = time_args.end_time_number insertion_start_time = time_args.insertion_start_time_number insertion_end_time = time_args.insertion_end_time_number response = client.list_event( page=page, limit=limit, start_time=start_time, end_time=end_time, insertion_start_time=insertion_start_time, insertion_end_time=insertion_end_time, event_type=event_type, query=query, ) output = response["result"] for event in output: event["event_id"] = event["_id"] event["timestamp"] = timestamp_to_datestring(event["timestamp"] * 1000) convert_large_integers_to_strings(event) readable_output = tableToMarkdown( name="Event List", metadata=pagination_message, t=remove_empty_elements(output), headers=EVENT_HEADERS[event_type], headerTransform=string_to_table_header, ) return CommandResults( readable_output=readable_output, outputs_prefix="Netskope.Event", outputs_key_field="id", outputs=output, raw_response=response, ) def update_url_list_command( client: Client, args: dict[str, Any], ) -> CommandResults: """Update (override) URL List. Args: client (Client): Netskope API client. args (Dict[str, Any]): command arguments. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ url_list_id = args["url_list_id"] name = args.get("name") urls = argToList(args.get("urls")) list_type = args.get("list_type", "").lower() or None is_overwrite = optional_arg_to_boolean(args.get("is_overwrite")) if not all([name, urls, list_type]) or not is_overwrite: list_response = client.list_url_list(url_list_id=url_list_id) name = name or list_response.get("name") list_type = list_type or dict_safe_get(list_response, ["data", "type"]) exist_urls = dict_safe_get(list_response, ["data", "urls"]) if not is_overwrite: urls += exist_urls else: urls = urls or exist_urls response = client.update_url_list( url_list_id, name, urls, list_type, ) deploy_url_list_if_required(args, client.deploy_url_list) output = get_updated_url_list(response) readable_output = tableToMarkdown( name="URL list was updated successfully", t=remove_empty_elements(output), headers=URL_HEADER, headerTransform=string_to_table_header, ) return CommandResults( readable_output=readable_output, outputs_prefix="Netskope.URLList", outputs_key_field="id", outputs=output, raw_response=response, ) def add_url_list_command( client: Client, args: dict[str, Any], ) -> CommandResults: """Update URL List. Args: client (Client): Netskope API client. args (Dict[str, Any]): command arguments. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ url_list_id = args["url_list_id"] urls = argToList(args.get("urls")) list_type = args.get("list_type", "").lower() or None response = client.patch_url_list(url_list_id, urls, list_type) deploy_url_list_if_required(args, client.deploy_url_list) output = get_updated_url_list(response) readable_output = tableToMarkdown( name="URL list was updated successfully", t=remove_empty_elements(output), headers=URL_HEADER, headerTransform=string_to_table_header, ) return CommandResults( readable_output=readable_output, outputs_prefix="Netskope.URLList", outputs_key_field="id", outputs=output, raw_response=response, ) def create_url_list_command( client: Client, args: dict[str, Any], ) -> CommandResults: """Create a new URL list. Args: client (Client): Netskope API client. args (Dict[str, Any]): command arguments. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ name = args["name"] urls = argToList(args["urls"]) list_type = args.get("list_type", "").lower() response = client.create_url_list( name, urls, list_type, ) deploy_url_list_if_required(args, client.deploy_url_list) output = get_updated_url_list(response) readable_output = tableToMarkdown( name="URL list was created successfully", t=remove_empty_elements(output), headers=URL_HEADER, headerTransform=string_to_table_header, ) return CommandResults( readable_output=readable_output, outputs_prefix="Netskope.URLList", outputs_key_field="id", outputs=output, raw_response=response, ) def lists_url_list_command(client: Client, args: dict[str, Any]) -> CommandResults: """Get all URL Lists or a specific URL list. Args: client (Client): Netskope API client. args (Dict[str, Any]): command arguments. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ url_list_id = args.get("url_list_id") pending = args.get("pending") fields = argToList(args.get("field")) all_results = optional_arg_to_boolean(args.get("all_results")) pending = int(pending == "pending") updated_fields = [] updated_fields = ["data" if field in ("urls", "type") else field for field in fields] response = client.list_url_list(url_list_id=url_list_id, pending=pending, field=updated_fields) output = get_updated_url_list(response) if not all_results: limit = arg_to_number(args["limit"]) output = output[:limit] readable_output = tableToMarkdown( name="URL Lists", t=remove_empty_elements(output), headers=fields or URL_HEADER, headerTransform=string_to_table_header, ) return CommandResults( readable_output=readable_output, outputs_prefix="Netskope.URLList", outputs_key_field="id", outputs=response, raw_response=response, ) def delete_url_list_command( client: Client, args: dict[str, Any], ) -> CommandResults: """Delete a URL list by the list ID. Args: client (Client): Netskope API client. args (Dict[str, Any]): command arguments. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ url_list_id = args["url_list_id"] response = client.delete_url_list(url_list_id) deploy_url_list_if_required(args, client.deploy_url_list) return CommandResults( readable_output=f"The URL list {url_list_id} was deleted successfully", outputs_prefix="Netskope.URLList", outputs_key_field="id", outputs=response, raw_response=response, ) def list_client_command( client: Client, args: dict[str, Any], ) -> CommandResults: """Get information about Netskope SCIM users. Args: client (Client): Netskope API client. args (Dict[str, Any]): command arguments. Returns: CommandResults: outputs, readable outputs and raw response for XSOAR. """ pagination_data = pagination(args, False) page = pagination_data.updated_page limit = pagination_data.limit pagination_message = pagination_data.pagination_message client_filter = args.get("filter") updated_client_filter = convert_client_filter(client_filter) if client_filter else None response = client.list_client(page, limit, updated_client_filter) output = response.get("Resources", []) output = get_updated_list_client(output) readable_output = tableToMarkdown( name="Client List", t=remove_empty_elements(output), metadata=pagination_message, headers=[ "client_id", "external_id", "user_name", "given_name", "family_name", "emails", "active", ], headerTransform=string_to_table_header, ) return CommandResults( readable_output=readable_output, outputs_prefix="Netskope.Client", outputs_key_field="id", outputs=output, raw_response=response, ) def list_dlp_incident_command( client: Client, args: dict[str, Any], ) -> CommandResults: """Fetch DLP incidents. Args: client (Client): A session to run HTTP requests to the API. args (dict[str, Any]): Arguments passed down by the CLI to configure the request. Returns: CommandResults: Outputs of the command that represent an entry in the warroom. """ start_time_dt = arg_to_datetime(args["start_time"]) end_time_dt = arg_to_datetime(args["end_time"]) if not start_time_dt or not end_time_dt: raise DemistoException("Time argument is required.") start_time = int(start_time_dt.timestamp()) end_time = int(end_time_dt.timestamp()) incidents = [] hourly_timestamps = get_hourly_timestamps( start_time=start_time, end_time=end_time, ) for timestamp in hourly_timestamps: response = client.list_dlp_incident(timestamp=timestamp) if dlp_incidents := response["result"]: incidents += dlp_incidents incidents = remove_duplicates(incidents, "object_id") readable_output = tableToMarkdown( name="DLP Incident List:", t=incidents, headers=INCIDENT_HEADERS, headerTransform=string_to_table_header, ) return CommandResults( raw_response=incidents, outputs=incidents, outputs_key_field="object_id", outputs_prefix="Netskope.Incident", readable_output=readable_output, ) def test_module(client: Client) -> str: try: client.list_client(1, 1) return "ok" except DemistoException as exc: if exc.res is not None and exc.res.status_code in [ HTTPStatus.UNAUTHORIZED, HTTPStatus.NOT_FOUND, HTTPStatus.FORBIDDEN, ]: return "Authorization Error: Unknown API key or Netskope URL" return exc.message def fetch_incidents(client: Client, params: dict[str, Any]): """Fetch Netskope alerts, DLP incidents, and events (if requested) as incidents in XSOAR. In case of DLP incidents: the incidents will fetch by timestamp and will saved in XSOAR and integration context to handle duplicates issue. Args: client (Client): Netskope API client. params (Dict[str, Any]): Integration parameters. """ incidents: list[dict] = [] last_run: dict[str, Any] = {} mirror_direction = MIRROR_DIRECTION_MAPPING.get(params["mirror_direction"], None) event_types = argToList(params.get("event_types")) alert_query = params.get("alerts_query") alert_max_fetch = arg_to_number(params.get("max_fetch") or 50) or MAX_LIMIT num_event_types = len(event_types) if event_types else 1 max_fetch_per_event_type = MAX_FETCH_PER_EVENT_TYPE // num_event_types if event_types and (event_max_fetch := arg_to_number(params.get("max_events_fetch") or 50)) is not None: max_fetch_per_event_type = event_max_fetch // (len(event_types)) if params.get("fetch_events") and event_types: events, events_last_run = fetch_events_as_incidents( list_event_func=client.list_event, params=params, max_fetch_per_event_type=max_fetch_per_event_type, last_run=last_run, mirror_direction=mirror_direction, ) incidents += events last_run.update(events_last_run) if params.get("fetch_dlp_incidents"): dlp_incidents, dlp_incidents_last_run = fetch_dlp_incidents_as_incidents( list_event_func=client.list_dlp_incident, params=params, last_run=last_run, mirror_direction=mirror_direction, ) incidents += dlp_incidents last_run.update(dlp_incidents_last_run) alerts, alerts_last_run = fetch_alerts_as_incidents( list_event_func=client.list_alert, params=params, max_fetch=alert_max_fetch, alert_query=alert_query, last_run=last_run, mirror_direction=mirror_direction, ) incidents += alerts last_run.update(alerts_last_run) return last_run, incidents def get_modified_remote_data(client: Client) -> GetModifiedRemoteDataResponse: """ Queries for incidents that were modified since the last update. Args: client: Netskope API client. Returns: GetModifiedRemoteDataResponse: modified tickets from Netskope. """ # get the fetch last run time to check if exist incidents was updated for sync incidents start_timestamp = get_demisto_integration_context("dlp_incident_last_run_timestamp", None) end_timestamp = date_to_seconds_timestamp(datetime.now()) if not start_timestamp: start_timestamp = end_timestamp - 600 hourly_timestamps = get_hourly_timestamps( start_time=start_timestamp, end_time=end_timestamp, ) demisto.debug(f"Get modified remote data from {start_timestamp} - {end_timestamp}") dlp_incidents = [] modified_tickets = [] for timestamp in hourly_timestamps: response = client.list_dlp_incident(timestamp=timestamp) if data := response["result"]: dlp_incidents += data dlp_incidents = remove_duplicates(dlp_incidents, "object_id") # save the updated incidents for get_remote_data_command set_demisto_integration_context("dlp_incidents_to_update", dlp_incidents, "append") for ticket in dlp_incidents: modified_tickets.append(ticket["object_id"]) demisto.debug(f"There are {len(modified_tickets)} modified incidents from Netskope") return GetModifiedRemoteDataResponse(modified_tickets) def get_mapping_fields_command() -> GetMappingFieldsResponse: """ Pulls the remote schema for the different incident types, and their associated incident fields, from the remote system. Returns: GetMappingFieldsResponse: Dictionary with keys as field names. """ demisto.debug("Get Netskope mapping fields") mapping_response = GetMappingFieldsResponse() incident_type_scheme = SchemeTypeMapping(type_name="Netskope Incident") for field in MIRRORING_FIELDS: incident_type_scheme.add_field(field) mapping_response.add_scheme_type(incident_type_scheme) return mapping_response def update_remote_system( client: Client, args: dict[str, Any], params: dict[str, Any], ) -> str: """ This command pushes local changes to the remote system. Args: client: XSOAR Client to use. args: args['data']: the data to send to the remote system. args['entries']: the entries to send to the remote system. args['incident_changed']: boolean telling us if the local incident indeed changed or not. args['remote_incident_id']: the remote incident id. Returns: The remote incident id - ticket_id """ parsed_args = UpdateRemoteSystemArgs(args) incident_id = parsed_args.remote_incident_id demisto.debug( f"Got the following delta keys {list(parsed_args.delta.keys())!s}" if parsed_args.delta else "There is no delta fields in Netskope" ) try: if parsed_args.incident_changed and parsed_args.delta: demisto.debug(f"Incident changed: {parsed_args.incident_changed}, {parsed_args.delta=}, {parsed_args.inc_status=}") update_args: dict[str, Any] = parsed_args.delta # fetch old arguments data for API call old_args: dict[str, Any] = parsed_args.data updated_arguments = {} if parsed_args.inc_status == IncidentStatus.DONE and params.get("close_netskope_incident"): updated_arguments["field"] = "status" updated_arguments["old_value"] = old_args["original_status"] updated_arguments["new_value"] = "closed" updated_arguments["object_id"] = incident_id else: for key, value in update_args.items(): if key in MIRRORING_FIELDS: updated_arguments["field"] = key updated_arguments["old_value"] = old_args[f"original_{key}"] updated_arguments["new_value"] = value updated_arguments["object_id"] = incident_id if updated_arguments: demisto.debug(f"Send remote ID [{incident_id}] updates to Netskope. {updated_arguments=}|| {update_args=}") client.update_dlp_incident(**updated_arguments) except Exception as error: demisto.info(f"Error in Netskope outgoing mirror for incident {incident_id}. Error message: {error}") finally: return incident_id def get_remote_data_command( args: dict[str, Any], params: dict[str, Any], ) -> GetRemoteDataResponse: """ Gets new information about the incidents in the remote system and updates existing incidents in Cortex XSOAR. Args: args (Dict[str, Any]): command arguments. params (Dict[str, Any]): command parameters. Returns: List[Dict[str, Any]]: first entry is the incident (which can be completely empty) and the new entries. """ parsed_args = GetRemoteDataArgs(args) incident_id = parsed_args.remote_incident_id demisto.debug(f"Check if incident {incident_id} updated") # fetch updated incidents (that saved in get_modified_remote_data command) dlp_incidents: list = get_demisto_integration_context("dlp_incidents_to_update", []) mirrored_ticket = {} for incident in dlp_incidents: # get the incident data by the relevant incident ID if incident["object_id"] == incident_id: mirrored_ticket = incident # remove the incident from integration context dlp_incidents.remove(mirrored_ticket) set_demisto_integration_context("dlp_incidents_to_update", dlp_incidents, "override") break entries = [] mirrored_ticket["incident_type"] = "dlp_incident" if mirrored_ticket.get("status") == "closed" and params.get("close_incident"): entries.append( { "Type": EntryType.NOTE, "Contents": { "dbotIncidentClose": True, "closeReason": "Closed from Netskope.", }, "ContentsFormat": EntryFormat.JSON, } ) return GetRemoteDataResponse(mirrored_ticket, entries) # HELPERS FUNCTIONS # def convert_large_integers_to_strings(data: dict[str, Any]) -> None: """Convert large integers to strings to prevent JavaScript precision loss. JavaScript cannot safely represent integers larger than 2^53-1 (Number.MAX_SAFE_INTEGER). This function converts such integers to strings in-place to preserve their exact values. Args: data (dict[str, Any]): Dictionary containing potential large integer values. Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER """ for key, value in list(data.items()): if isinstance(value, int) and value > JS_NUMBER_LIMIT: demisto.debug(f"Converting large integer to string: {key}={value}") data[key] = str(value) def get_hourly_timestamps(start_time: int, end_time: int) -> list[int]: """Get a list of timestamps with a one hour gap between the received start and end timestamps. Args: start_time (int): The start timestamp. end_time (int): The end timestamp. Returns: list[int]: The timestamps list. """ timestamps = [] current_timestamp = start_time while current_timestamp <= end_time: timestamps.append(current_timestamp) current_timestamp += 3600 # Increment by 3600 seconds (1 hour) return timestamps def remove_duplicates( dicts_list: list[dict[str, Any]], key: str, ) -> list[dict[str, Any]]: """Remove duplicates from a list of dicts by unique key. Args: dicts_list (list[dict[str, Any]]): The list of dicts to update. key (str): The unique key. Returns: list[dict[str, Any]]: The updated list with no duplicates. """ object_map = {} for item in dicts_list: object_id = item[key] object_map[object_id] = item return list(object_map.values()) def parse_incident( incident: dict, incident_type: str, mirror_direction: str | None = None, ) -> dict: """ Parse alert/event to XSOAR Incident. Args: incident (dict): alert/event item. incident_type (str): Incident type. Returns: dict: XSOAR Incident. """ incident_id = incident["object_id"] if incident_type == "dlp_incident" else incident["_id"] incident["incident_type"] = incident_type incident["mirror_direction"] = mirror_direction incident["mirror_instance"] = demisto.integrationInstance() convert_large_integers_to_strings(incident) return { "name": f"{incident_type} ID: {incident_id}", "incident_type": incident_type, "mirror_direction": mirror_direction, "mirror_instance": demisto.integrationInstance(), "occurred": convert_datetime_int_to_iso(incident["timestamp"]), "rawJSON": json.dumps(incident), } def convert_datetime_int_to_iso(creation_timestamp: int) -> datetime: """Convert datetime to iso. Args: creation_timestamp (int): creation timestamp argument. Returns: datetime: Updated argument. """ date_string = convert_number_to_str_date(creation_timestamp) alert_date = datetime.strptime(date_string, TIME_FORMAT) return FormatIso8601(alert_date) + "Z" def fetch_events_as_incidents( list_event_func: Callable, params: dict[str, Any], max_fetch_per_event_type: int, last_run: dict[str, Any], mirror_direction: str | None = None, ) -> tuple[list, dict]: """Fetch events from Netskope as incidents. Args: list_event_func (Callable): Netskope API client. params (Dict[str, Any]): Integration parameters. max_fetch_per_event_type (int): Maximum number per event type. last_run (Dict[str, Any]): Last run argument. mirror_direction (str | None): Mirror direction. Returns:Callable Tuple[list, dict]: Events as incidents and updated last_run argument. """ incidents = [] event_types = argToList(params.get("event_types")) event_query = params.get("event_query") for event_type in event_types: relevant_events = [] last_run_id, last_run_timestamp = get_last_run(params, event_type) end_time_number = date_to_seconds_timestamp(datetime.now()) response = list_event_func( event_type=event_type, query=event_query, limit=max_fetch_per_event_type, page=0, start_time=last_run_timestamp, end_time=end_time_number, ) events = response["result"] for event in events: if last_run_id != event["_id"]: event["incident_type"] = event_type incidents.append(parse_incident(event, f"{event_type}-event", mirror_direction)) relevant_events.append(event) last_run = update_last_run( relevant_events=relevant_events, incident_type=event_type, last_run=last_run, last_run_id=last_run_id, last_run_time_number=last_run_timestamp, ) return incidents, last_run def fetch_dlp_incidents_as_incidents( list_event_func: Callable, params: dict[str, Any], last_run: dict[str, Any], mirror_direction: str | None = None, ) -> tuple[list, dict]: """Fetch DLP incidents from Netskope as incidents. The incidents will be saved in the integration context to avoid duplicates. Args: list_event_func (Callable): Netskope API client. params (Dict[str, Any]): Integration parameters. last_run (dict[str, Any]): Last run. mirror_direction (str | None): Mirror direction. Returns:Callable Tuple[list, dict]: DLP incidents as incidents and updated last_run argument. """ incidents = [] new_incidents = [] new_incident_ids = [] last_run_id, last_run_timestamp = get_last_run(params, "dlp_incident") # when last run is rest - update integration context data if not last_run_id: set_demisto_integration_context("dlp_incident_ids", [], "override") set_demisto_integration_context("dlp_incident_last_run_timestamp", None, "override") set_demisto_integration_context("dlp_incidents_to_update", [], "override") end_time_number = date_to_seconds_timestamp(datetime.now()) max_fetch = int(params.get("max_dlp_incidents_fetch") or 50) hourly_timestamps = get_hourly_timestamps( start_time=last_run_timestamp, end_time=end_time_number, ) dlp_incidents = [] # get incident IDs that exist in XSOAR to avoid duplicates exist_dlp_incidents: list = get_demisto_integration_context("dlp_incident_ids", []) for timestamp in hourly_timestamps: response = list_event_func(timestamp) if response.get("result"): dlp_incidents += response["result"] dlp_incidents = remove_duplicates(dlp_incidents, "object_id") last_run_timestamp = timestamp if len(dlp_incidents) >= max_fetch: dlp_incidents = dlp_incidents[:max_fetch] break for incident in dlp_incidents: incident_id = incident["object_id"] if incident_id not in exist_dlp_incidents: incidents.append(parse_incident(incident, "dlp_incident", mirror_direction)) new_incidents.append(incident) new_incident_ids.append(incident_id) if new_incident_ids: # set the new incident IDs to avoid duplicates on next fetch set_demisto_integration_context("dlp_incident_ids", new_incident_ids, "append") last_run_timestamp = max(new_incidents, key=lambda k: k["timestamp"])["timestamp"] + 1 else: last_run_timestamp = end_time_number # set the updated fetch last run time for get_modified_remote_data command # to update existing incidents and ensure full sync set_demisto_integration_context("dlp_incident_last_run_timestamp", last_run_timestamp, "override") last_run = update_last_run( relevant_events=new_incidents, incident_type="dlp_incident", last_run=last_run, last_run_id=last_run_id, last_run_time_number=last_run_timestamp, ) return incidents, last_run def fetch_alerts_as_incidents( list_event_func: Callable, params: dict[str, Any], max_fetch: int, last_run: dict[str, Any], alert_query: str | None = None, mirror_direction: str | None = None, ) -> tuple[list, dict]: """Fetch DLP incidents from Netskope as incidents. Args: list_event_func (Callable): Netskope API client. params (Dict[str, Any]): Integration parameters. max_fetch (int): Maximum number per event type. last_run (dict[str, Any]): Last run data. alert_query (str, optional): Alert query. Defaults to None. mirror_direction (str, optional): Mirror direction. Defaults to None. Returns:Callable Tuple[list, dict]: DLP incidents as incidents and updated last_run argument. """ incidents = [] new_incidents = [] last_run_id, last_run_timestamp = get_last_run(params, "alert") end_time_number = date_to_seconds_timestamp(datetime.now()) response = list_event_func( query=alert_query, limit=max_fetch, page=0, start_time=last_run_timestamp, end_time=end_time_number, ) alerts = response["result"] for alert in alerts: if last_run_id != alert["_id"]: alert["incident_type"] = alert["alert_type"] incidents.append(parse_incident(alert, "alert", mirror_direction)) new_incidents.append(alert) last_run = update_last_run( relevant_events=new_incidents, incident_type="alert", last_run=last_run, last_run_id=last_run_id, last_run_time_number=last_run_timestamp, ) return incidents, last_run def update_last_run( relevant_events: list, incident_type: str, last_run: dict, last_run_id: Any | None, last_run_time_number: int, ) -> dict[str, Any]: """Update the last run argument by alert type for next run. Args: relevant_events (list): The new incidents. incident_type (str): Incident type. last_run (dict): Last run argument. last_run_id (int): Last run ID. last_run_time_number (int): The last run time number. Returns: Dict[str, Any]: Updated last run argument. """ if relevant_events: last_run_alert = max(relevant_events, key=lambda k: k["timestamp"]) last_run[incident_type] = { "id": (last_run_alert["object_id"] if incident_type == "dlp_incident" else last_run_alert["_id"]), "time": last_run_time_number if incident_type == "dlp_incident" else last_run_alert["timestamp"] + 1, "date": convert_number_to_str_date(last_run_time_number), } else: last_run[incident_type] = { "id": last_run_id, "time": last_run_time_number, "date": convert_number_to_str_date(last_run_time_number), } demisto.setLastRun(last_run) return last_run def get_last_run( args: dict[str, Any], incident_type: str, ) -> tuple[Any | None, int]: """Get last run arguments. Args: args (Dict[str, Any]): XSOAR arguments. incident_type (str): Incident type. Returns: Tuple: Updated last run arguments. """ last_run = demisto.getLastRun() ticket_last_run = last_run.get(incident_type) last_run_id = None if last_run and ticket_last_run: last_run_time = ticket_last_run.get("time") last_run_id = ticket_last_run.get("id") else: last_run_time = args.get("first_fetch", "3 Days") first_fetch = arg_to_datetime(arg=last_run_time, arg_name="First fetch time", required=True) if not first_fetch: raise ValueError("First fetch time not specified") last_run_timestamp = date_to_seconds_timestamp(first_fetch) return last_run_id, last_run_timestamp def deploy_url_list_if_required( args: dict[str, Any], deploy_url_list_func: Callable, ): """Deploys URL list changes if required. Args: client (Client): Netskope API client. args (Dict[str, Any]): command arguments. """ if optional_arg_to_boolean(args.get("deploy")): deploy_url_list_func() def convert_client_filter(client_filter: str) -> str: """Convert client filter to the appropriate format. Args: client_filter (str): client filter. Returns: str: Updated filter. """ filter_parts = [part.strip() for part in client_filter.split("eq")] if len(filter_parts) != 2: raise DemistoException("Filter must contain 'key' eq 'value'") attribute_name, attribute_value = filter_parts attribute_value = attribute_value.strip().strip('"') modified_filter = f'{attribute_name} eq "{attribute_value}"' return modified_filter def get_updated_list_client(response: list | dict) -> list: """Updates URL list response. Args: response (Union[List, Dict]): The API response. Returns: List: Updated URL list. """ outputs = [] for list_client in response: output = copy.deepcopy(list_client) output["client_id"] = output.pop("id") output |= output.pop("name", {}) output["emails"] = [email.get("value") for email in output.get("emails", [])] output = snakify(output) outputs.append(output) return outputs def get_updated_url_list(response: list | dict) -> list: """Updates URL list response. Args: response (Union[List, Dict]): The API response. Returns: List: Updated URL list. """ response = [response] if isinstance(response, dict) else response outputs = [] number_to_pending_status = { 0: "applied", 1: "pending", } for url_list in response: output = copy.deepcopy(url_list) output |= output.pop("data", {}) output["pending"] = number_to_pending_status.get(output.get("pending")) outputs.append(output) return outputs def parse_start_end_times(start_str: str, end_str: str | None) -> tuple[int | None, int | None]: """Convert string date to timestamp. Args: start_str (str): String start date. end_str (Optional[str]): String end date. Returns: Tuple: Timestamp start & end dates. """ start_number = arg_to_seconds_timestamp(start_str) if start_str else None end_number = arg_to_seconds_timestamp(end_str) if end_str else date_to_seconds_timestamp(datetime.now()) return start_number, end_number def convert_time_args_to_num(args: dict[str, Any]) -> TimeArgs: """Convert relevant time arguments to numbers timestamp. Args: args (Dict[str, Any]): command arguments. Raises: ValueError: When specified all time arguments or not specified none of them. Returns: Tuple: The updated time arguments. """ start_time_str = args.get("start_time") end_time_str = args.get("end_time") insertion_start_time_str = args.get("insertion_start_time") insertion_end_time_str = args.get("insertion_end_time") start_time_number = None end_time_number = None insertion_start_time_number = None insertion_end_time_number = None if start_time_str: start_time_number, end_time_number = parse_start_end_times(start_time_str, end_time_str) elif insertion_start_time_str: insertion_start_time_number, insertion_end_time_number = parse_start_end_times( insertion_start_time_str, insertion_end_time_str ) else: raise ValueError("Provide either the `start_time` argument or `insertion_start_time`.") return TimeArgs( start_time_number, end_time_number, insertion_start_time_number, insertion_end_time_number, ) def convert_number_to_str_date(number: int) -> str: """Convert number to date string. Args: number (int): The date number to convert. Returns: str: The string date. """ return datetime.fromtimestamp(float(number)).strftime(TIME_FORMAT) def arg_to_seconds_timestamp(arg: str | datetime) -> int | None: """ Converts an XSOAR date string argument to a timestamp in seconds. Args: arg (Optional[str]): The argument to convert. Returns: Optional[int]: A timestamp if arg can be converted, or None if arg is None. """ date_arg = arg_to_datetime(arg) if date_arg is None: return None return date_to_seconds_timestamp(date_arg) def date_to_seconds_timestamp(date_str_or_dt: str | datetime) -> int: """ Converts date string or datetime object to a timestamp in seconds. Args: date_str_or_dt (Union[str, datetime]): The datestring or datetime. Returns: int: The timestamp in seconds. """ return date_to_timestamp(date_str_or_dt) // 1000 def validate_pagination_arguments( page: int | None = None, limit: int | None = None, ): """Validate pagination arguments according to their default. Args: page (int, optional): Page number of paginated results. page_size (int, optional): Number of items per page. limit (int, optional): The maximum number of records to retrieve. Raises: ValueError: Incase page is lower than 1 or Incase limit is lower than 1. """ if page is not None and page < MIN_PAGE_NUM: raise ValueError(f"page argument must be greater than {MIN_PAGE_NUM}.") if limit is not None and limit < MIN_LIMIT: raise ValueError(f"limit argument must be greater than {MIN_LIMIT}.") def pagination(args: dict[str, Any], start_count_from_zero: bool = True) -> Pagination: """Return the correct limit and offset for the API based on the user arguments page and limit. Args: args (Dict[str, Any]): Command arguments from XSOAR. start_count_from_zero (bool, optional): Whether to start the offset count from or 1. Defaults to True. Returns: Tuple: page, limit, pagination_message. """ page = arg_to_number(args.get("page")) or 1 limit = arg_to_number(args.get("limit")) or 50 validate_pagination_arguments(page, limit) pagination_message = f"Showing page {page}. \n Current page size: {limit}." updated_page = (page - 1) * limit + (0 if start_count_from_zero else 1) return Pagination(updated_page, limit, pagination_message) def optional_arg_to_boolean(arg: str | bool | None) -> bool | None: """Retrieve arg boolean value if it's not none. Args: arg (Union[str, bool, None]): Boolean argument. Returns: Optional[bool]: The argument boolean value. """ return argToBoolean(arg) if arg is not None else None def get_demisto_integration_context( key: str, default_value: Any, ) -> Any: """Get the integration context for a given key. Args: key (str): The key to retrieve. default_value (Any): The default value to return in case the key dont exist. Returns: Any: The value of the given key. """ return get_integration_context().get(key, default_value) def set_demisto_integration_context( key: str, value_to_update: Any, action: str, ): """Set the integration context for the given key and value. Args: key (str): The integration context key to update his value. value_to_update (Any): The value to update. action (str): The action to take when update the value. """ integration_context = get_integration_context() if action == "append": if not integration_context.get(key): integration_context[key] = [] integration_context[key] += value_to_update # check if integration context size is reached to 40mb if len(integration_context[key]) >= MAX_IDS_NUMBER: # remove the first items to avoid overflow number_of_items_to_remove = len(integration_context[key]) - MAX_IDS_NUMBER integration_context[key] = integration_context[key][number_of_items_to_remove:] else: integration_context[key] = value_to_update set_integration_context(integration_context) def main() -> None: # pragma: no cover params: dict[str, Any] = demisto.params() args: dict[str, Any] = demisto.args() url = params["url"] api_token = params["credentials"]["password"] proxy = params.get("proxy", False) verify_certificate: bool = not params.get("insecure", False) user_email = params.get("user_email") command = demisto.command() demisto.debug(f"Command being called is {command}") try: client: Client = Client( url, api_token, verify_certificate, proxy, user_email, ) commands = { "netskope-alert-list": list_alert_command, "netskope-event-list": list_event_command, "netskope-url-list-update": update_url_list_command, "netskope-url-list-create": create_url_list_command, "netskope-url-lists-list": lists_url_list_command, "netskope-url-list-delete": delete_url_list_command, "netskope-client-list": list_client_command, "netskope-url-list-add": add_url_list_command, "netskope-incident-dlp-list": list_dlp_incident_command, } if command == "test-module": return_results(test_module(client)) elif command == "get-remote-data": return_results(get_remote_data_command(args, params)) elif command == "get-modified-remote-data": return_results(get_modified_remote_data(client)) elif command == "update-remote-system": return_results(update_remote_system(client, args, params)) elif command == "get-mapping-fields": return_results(get_mapping_fields_command()) elif command == "fetch-incidents": last_run, incidents = fetch_incidents(client, params) demisto.setLastRun(last_run) demisto.incidents(incidents) elif command in commands: return_results(commands[command](client, args)) else: raise NotImplementedError(f"{command} command is not implemented.") except Exception as e: return_error(str(e)) if __name__ in ["__main__", "builtin", "builtins"]: main()