Axonius
This integration is for fetching information about assets in Axonius.
Data Enrichment & Threat Intelligence · Axonius
Details
| ID | Axonius |
|---|---|
| Provider | Axonius |
| Category | Data Enrichment & Threat Intelligence |
| From Version | 5.0.0 |
| Docker Image | demisto/axonius:1.1.0.8767810 |
| Supported Modules | Agentix XSIAM |
README
This integration is for fetching information about assets in Axonius.
This integration was integrated and tested with version 3.9 of Axonius
Configure Axonius in Cortex
| Parameter | Required |
|---|---|
| Server URL (e.g. https://example.net) | True |
| Axonius API Key | True |
| Axonius API Secret | True |
| Trust any certificate (not secure) | False |
| Use system proxy settings | 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 in the War Room with the command details.
axonius-get-devices-by-savedquery
Gather device info by saved query
Base Command
axonius-get-devices-by-savedquery
Input
| Argument Name | Description | Required |
|---|---|---|
| saved_query_name | The name of the devices saved query within Axonius. See https://docs.axonius.com/docs/saved-queries-devices. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Devices.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Devices.adapters | String | The specific adapter names with asset information. |
| Axonius.Devices.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Devices.hostname | String | The hostnames of the assset. |
| Axonius.Devices.name | String | The names of the asset. |
| Axonius.Devices.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Devices.network_interfaces_macs | String | The MAC addresses of the asset. |
| Axonius.Devices.network_interfaces_ips | String | The IP addresses of the asset. |
| Axonius.Devices.os_type | String | The OS type (Windows, Linux, macOS,…). |
| Axonius.Devices.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-devices-by-savedquery saved_query_name=example_query
Context Example
{
"Axonius": {
"Devices": {
"adapter_list_length": 5,
"adapters": [
"nexpose_adapter",
"esx_adapter",
"active_directory_adapter",
"solarwinds_orion_adapter",
"crowd_strike_adapter",
"esx_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"esx_adapter"
],
"aggregated_hostname": [
"DC4"
],
"aggregated_last_seen": "2020-09-08T06:44:31+00:00",
"aggregated_name": [
"Windows%20Server%202012%20r2%20dc4.TestDomain.test%20(Avidor)",
"DC4",
"Windows Server 2012 R2",
"Windows Server - 2012 - R2"
],
"aggregated_network_interfaces_ips": [
"x.x.x.x",
],
"aggregated_network_interfaces_mac": [
"00:0C:29:B6:DA:46",
"00:50:56:91:DE:BB",
"00:50:56:91:3A:EC",
"00:50:56:91:33:E2",
"00:50:56:91:21:B3"
],
"aggregated_os_type": [
"Windows"
],
"internal_axon_id": "d530db3cfef6a2220b315d54fa1901b2"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_hostname aggregated_last_seen aggregated_name aggregated_network_interfaces_ips aggregated_network_interfaces_mac aggregated_os_type internal_axon_id 5 nexpose_adapter,
esx_adapter,
active_directory_adapter,
solarwinds_orion_adapter,
crowd_strike_adapter,
esx_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
esx_adapterDC4 2020-09-08T06:44:31+00:00 Windows%20Server%202012%20r2%20dc4.TestDomain.test%20(Avidor),
DC4,
Windows Server 2012 R2,
Windows Server - 2012 - R2192.168.20.17,
192.168.20.58,
fe80::2dba:9118:1fc8:7759,
192.168.20.36,
192.168.20.50,
192.168.20.6100:0C:29:B6:DA:46,
00:50:56:91:DE:BB,
00:50:56:91:3A:EC,
00:50:56:91:33:E2,
00:50:56:91:21:B3Windows d530db3cfef6a2220b315d54fa1901b2
axonius-get-devices-by-aql
Gather devices info by AQL query
Base Command
axonius-get-devices-by-aql
Input
| Argument Name | Description | Required |
|---|---|---|
| query | The AQL query to filter devices by. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Devices.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Devices.adapters | String | The specific adapter names with asset information. |
| Axonius.Devices.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Devices.hostname | String | The hostnames of the assset. |
| Axonius.Devices.name | String | The names of the asset. |
| Axonius.Devices.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Devices.network_interfaces_macs | String | The MAC addresses of the asset. |
| Axonius.Devices.network_interfaces_ips | String | The IP addresses of the asset. |
| Axonius.Devices.os_type | String | The OS type (Windows, Linux, macOS,…). |
| Axonius.Devices.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-devices-by-aql query="((\"specific_data.data.name\" == ({\"$exists\":true,\"$ne\":\"\"})))" max_results="50"
Context Example
{
"Axonius": {
"Devices": {
"adapter_list_length": 5,
"adapters": [
"nexpose_adapter",
"esx_adapter",
"active_directory_adapter",
"solarwinds_orion_adapter",
"crowd_strike_adapter",
"esx_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"esx_adapter"
],
"aggregated_hostname": [
"DC4"
],
"aggregated_last_seen": "2020-09-08T06:44:31+00:00",
"aggregated_name": [
"Windows%20Server%202012%20r2%20dc4.TestDomain.test%20(Avidor)",
"DC4",
"Windows Server 2012 R2",
"Windows Server - 2012 - R2"
],
"aggregated_network_interfaces_ips": [
"x.x.x.x",
],
"aggregated_network_interfaces_mac": [
"00:0C:29:B6:DA:46",
"00:50:56:91:DE:BB",
"00:50:56:91:3A:EC",
"00:50:56:91:33:E2",
"00:50:56:91:21:B3"
],
"aggregated_os_type": [
"Windows"
],
"internal_axon_id": "d530db3cfef6a2220b315d54fa1901b2"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_hostname aggregated_last_seen aggregated_name aggregated_network_interfaces_ips aggregated_network_interfaces_mac aggregated_os_type internal_axon_id 5 nexpose_adapter,
esx_adapter,
active_directory_adapter,
solarwinds_orion_adapter,
crowd_strike_adapter,
esx_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
esx_adapterDC4 2020-09-08T06:44:31+00:00 Windows%20Server%202012%20r2%20dc4.TestDomain.test%20(Avidor),
DC4,
Windows Server 2012 R2,
Windows Server - 2012 - R2192.168.20.17,
192.168.20.58,
fe80::2dba:9118:1fc8:7759,
192.168.20.36,
192.168.20.50,
192.168.20.6100:0C:29:B6:DA:46,
00:50:56:91:DE:BB,
00:50:56:91:3A:EC,
00:50:56:91:33:E2,
00:50:56:91:21:B3Windows d530db3cfef6a2220b315d54fa1901b2
axonius-get-users-by-aql
Gather users info by AQL query
Base Command
axonius-get-users-by-aql
Input
| Argument Name | Description | Required |
|---|---|---|
| query | The AQL query to filter users by. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Users.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Users.adapters | String | The specific adapter names with asset information. |
| Axonius.Users.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Users.username | String | Username of the asset. |
| Axonius.Users.mail | String | Email address of the asset. |
| Axonius.Users.is_admin | Boolean | If the asset has admin privileges. |
| Axonius.Users.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Users.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-users-by-aql query="((\"specific_data.data.username\" == ({\"$exists\":true,\"$ne\":\"\"})))" max_results="50"
Context Example
{
"Axonius": {
"Users": {
"adapter_list_length": 1,
"adapters": [
"active_directory_adapter"
],
"aggregated_domain": "TestDomain.test",
"aggregated_is_admin": false,
"aggregated_last_seen": "2018-11-01T14:48:59+00:00",
"aggregated_username": "test_ldap_login_user",
"internal_axon_id": "4d5f47f067388e8ffc53b6bbe8a10800"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_domain aggregated_is_admin aggregated_last_seen aggregated_username internal_axon_id 1 active_directory_adapter TestDomain.test false 2018-11-01T14:48:59+00:00 test_ldap_login_user 4d5f47f067388e8ffc53b6bbe8a10800
axonius-get-users-by-savedquery
Gather user info by saved query
Base Command
axonius-get-users-by-savedquery
Input
| Argument Name | Description | Required |
|---|---|---|
| saved_query_name | The name of the users saved query within Axonius. See https://docs.axonius.com/docs/saved-queries-users. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Users.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Users.adapters | String | The specific adapter names with asset information. |
| Axonius.Users.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Users.username | String | Username of the asset. |
| Axonius.Users.mail | String | Email address of the asset. |
| Axonius.Users.is_admin | Boolean | If the asset has admin privileges. |
| Axonius.Users.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Users.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-users-by-savedquery saved_query_name=example_query
Context Example
{
"Axonius": {
"Users": {
"adapter_list_length": 1,
"adapters": [
"active_directory_adapter"
],
"aggregated_domain": "TestDomain.test",
"aggregated_is_admin": false,
"aggregated_last_seen": "2018-11-01T14:48:59+00:00",
"aggregated_username": "test_ldap_login_user",
"internal_axon_id": "4d5f47f067388e8ffc53b6bbe8a10800"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_domain aggregated_is_admin aggregated_last_seen aggregated_username internal_axon_id 1 active_directory_adapter TestDomain.test false 2018-11-01T14:48:59+00:00 test_ldap_login_user 4d5f47f067388e8ffc53b6bbe8a10800
axonius-get-users-by-mail
Gather user info by email address
Base Command
axonius-get-users-by-mail
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The user email address to search for within Axonius. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Users.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Users.adapters | String | The specific adapter names with asset information. |
| Axonius.Users.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Users.username | String | Username of the asset. |
| Axonius.Users.mail | String | Email address of the asset. |
| Axonius.Users.is_admin | Boolean | If the asset has admin privileges. |
| Axonius.Users.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Users.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-users-by-mail value=Administrator@testdomain.test
Context Example
{
"Axonius": {
"Users": {
"adapter_list_length": 1,
"adapters": [
"active_directory_adapter"
],
"aggregated_mail": [
"Administrator@testdomain.test"
],
"aggregated_username": [
"Administrator"
],
"internal_axon_id": "a6f0d051a30d401b7f73416fbc90a3cf"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_mail aggregated_username internal_axon_id 1 active_directory_adapter Administrator@testdomain.test Administrator a6f0d051a30d401b7f73416fbc90a3cf
axonius-get-users-by-mail-regex
Gather user info by email address using regex
Base Command
axonius-get-users-by-mail-regex
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The user email address to search for within Axonius. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Users.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Users.adapters | String | The specific adapter names with asset information. |
| Axonius.Users.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Users.username | String | Username of the asset. |
| Axonius.Users.mail | String | Email address of the asset. |
| Axonius.Users.is_admin | Boolean | If the asset has admin privileges. |
| Axonius.Users.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Users.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-users-by-mail-regex value=Administrator
Context Example
{
"Axonius": {
"Users": {
"adapter_list_length": 1,
"adapters": [
"active_directory_adapter"
],
"aggregated_mail": [
"Administrator@testdomain.test"
],
"aggregated_username": [
"Administrator"
],
"internal_axon_id": "a6f0d051a30d401b7f73416fbc90a3cf"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_mail aggregated_username internal_axon_id 1 active_directory_adapter Administrator@testdomain.test Administrator a6f0d051a30d401b7f73416fbc90a3cf
axonius-get-users-by-username
Gather user info by username
Base Command
axonius-get-users-by-username
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The username to search for within Axonius. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Users.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Users.adapters | String | The specific adapter names with asset information. |
| Axonius.Users.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Users.username | String | Username of the asset. |
| Axonius.Users.mail | String | Email address of the asset. |
| Axonius.Users.is_admin | Boolean | If the asset has admin privileges. |
| Axonius.Users.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Users.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-users-by-username value=test_ldap_login_user
Context Example
{
"Axonius": {
"Users": {
"adapter_list_length": 1,
"adapters": [
"active_directory_adapter"
],
"aggregated_username": "test_ldap_login_user",
"internal_axon_id": "4d5f47f067388e8ffc53b6bbe8a10800"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_username internal_axon_id 1 active_directory_adapter test_ldap_login_user 4d5f47f067388e8ffc53b6bbe8a10800
axonius-get-users-by-username-regex
Gather user info by username using regex
Base Command
axonius-get-users-by-username-regex
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The username to search for within Axonius. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Users.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Users.adapters | String | The specific adapter names with asset information. |
| Axonius.Users.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Users.username | String | Username of the asset. |
| Axonius.Users.mail | String | Email address of the asset. |
| Axonius.Users.is_admin | Boolean | If the asset has admin privileges. |
| Axonius.Users.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Users.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-users-by-username-regex value=test
Context Example
{
"Axonius": {
"Users": {
"adapter_list_length": 1,
"adapters": [
"active_directory_adapter"
],
"aggregated_username": "test_ldap_login_user",
"internal_axon_id": "4d5f47f067388e8ffc53b6bbe8a10800"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_username internal_axon_id 1 active_directory_adapter test_ldap_login_user 4d5f47f067388e8ffc53b6bbe8a10800
axonius-get-devices-by-hostname
Gather device info by hostname
Base Command
axonius-get-devices-by-hostname
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The hostname to search for within Axonius. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Devices.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Devices.adapters | String | The specific adapter names with asset information. |
| Axonius.Devices.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Devices.hostname | String | The hostnames of the assset. |
| Axonius.Devices.name | String | The names of the asset. |
| Axonius.Devices.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Devices.network_interfaces_macs | String | The MAC addresses of the asset. |
| Axonius.Devices.network_interfaces_ips | String | The IP addresses of the asset. |
| Axonius.Devices.os_type | String | The OS type (Windows, Linux, macOS,…). |
| Axonius.Devices.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-devices-by-hostname value=DC4
Context Example
{
"Axonius": {
"Devices": {
"adapter_list_length": 5,
"adapters": [
"nexpose_adapter",
"esx_adapter",
"active_directory_adapter",
"solarwinds_orion_adapter",
"crowd_strike_adapter",
"esx_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"esx_adapter"
],
"aggregated_hostname": [
"DC4"
],
"aggregated_network_interfaces_ips": [
"x.x.x.x",
],
"aggregated_network_interfaces_mac": [
"00:0C:29:B6:DA:46",
"00:50:56:91:DE:BB",
"00:50:56:91:3A:EC",
"00:50:56:91:33:E2",
"00:50:56:91:21:B3"
],
"aggregated_network_interfaces_subnets": [
"x.x.x.x/24"
],
"internal_axon_id": "d530db3cfef6a2220b315d54fa1901b2"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_hostname aggregated_network_interfaces_ips aggregated_network_interfaces_mac aggregated_network_interfaces_subnets internal_axon_id 5 nexpose_adapter,
esx_adapter,
active_directory_adapter,
solarwinds_orion_adapter,
crowd_strike_adapter,
esx_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
esx_adapterDC4 192.168.20.17,
192.168.20.58,
fe80::2dba:9118:1fc8:7759,
192.168.20.36,
192.168.20.50,
192.168.20.6100:0C:29:B6:DA:46,
00:50:56:91:DE:BB,
00:50:56:91:3A:EC,
00:50:56:91:33:E2,
00:50:56:91:21:B3x.x.x.x/24 d530db3cfef6a2220b315d54fa1901b2
axonius-get-devices-by-hostname-regex
Gather device info by hostname using regex
Base Command
axonius-get-devices-by-hostname-regex
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The hostname to search for within Axonius using regex. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Devices.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Devices.adapters | String | The specific adapter names with asset information. |
| Axonius.Devices.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Devices.hostname | String | The hostnames of the assset. |
| Axonius.Devices.name | String | The names of the asset. |
| Axonius.Devices.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Devices.network_interfaces_macs | String | The MAC addresses of the asset. |
| Axonius.Devices.network_interfaces_ips | String | The IP addresses of the asset. |
| Axonius.Devices.os_type | String | The OS type (Windows, Linux, macOS,…). |
| Axonius.Devices.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-devices-by-hostname-regex value=DC4
Context Example
{
"Axonius": {
"Devices": {
"adapter_list_length": 5,
"adapters": [
"nexpose_adapter",
"esx_adapter",
"active_directory_adapter",
"solarwinds_orion_adapter",
"crowd_strike_adapter",
"esx_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"esx_adapter"
],
"aggregated_hostname": [
"DC4"
],
"aggregated_network_interfaces_ips": [
"x.x.x.x",
],
"aggregated_network_interfaces_mac": [
"00:0C:29:B6:DA:46",
"00:50:56:91:DE:BB",
"00:50:56:91:3A:EC",
"00:50:56:91:33:E2",
"00:50:56:91:21:B3"
],
"aggregated_network_interfaces_subnets": [
"x.x.x.x/24"
],
"internal_axon_id": "d530db3cfef6a2220b315d54fa1901b2"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_hostname aggregated_network_interfaces_ips aggregated_network_interfaces_mac aggregated_network_interfaces_subnets internal_axon_id 5 nexpose_adapter,
esx_adapter,
active_directory_adapter,
solarwinds_orion_adapter,
crowd_strike_adapter,
esx_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
esx_adapterDC4 192.168.20.17,
192.168.20.58,
fe80::2dba:9118:1fc8:7759,
192.168.20.36,
192.168.20.50,
192.168.20.6100:0C:29:B6:DA:46,
00:50:56:91:DE:BB,
00:50:56:91:3A:EC,
00:50:56:91:33:E2,
00:50:56:91:21:B3x.x.x.x/24 d530db3cfef6a2220b315d54fa1901b2
axonius-get-devices-by-ip
Gather device info by IP address
Base Command
axonius-get-devices-by-ip
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The IP address to search for within Axonius. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Devices.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Devices.adapters | String | The specific adapter names with asset information. |
| Axonius.Devices.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Devices.hostname | String | The hostnames of the assset. |
| Axonius.Devices.name | String | The names of the asset. |
| Axonius.Devices.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Devices.network_interfaces_macs | String | The MAC addresses of the asset. |
| Axonius.Devices.network_interfaces_ips | String | The IP addresses of the asset. |
| Axonius.Devices.os_type | String | The OS type (Windows, Linux, macOS,…). |
| Axonius.Devices.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-devices-by-ip value=192.168.20.17
Context Example
{
"Axonius": {
"Devices": {
"adapter_list_length": 5,
"adapters": [
"nexpose_adapter",
"esx_adapter",
"active_directory_adapter",
"solarwinds_orion_adapter",
"crowd_strike_adapter",
"esx_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"esx_adapter"
],
"aggregated_hostname": [
"DC4"
],
"aggregated_network_interfaces_ips": [
"x.x.x.x",
],
"aggregated_network_interfaces_mac": [
"00:0C:29:B6:DA:46",
"00:50:56:91:DE:BB",
"00:50:56:91:3A:EC",
"00:50:56:91:33:E2",
"00:50:56:91:21:B3"
],
"aggregated_network_interfaces_subnets": [
"x.x.x.x/24"
],
"internal_axon_id": "d530db3cfef6a2220b315d54fa1901b2"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_hostname aggregated_network_interfaces_ips aggregated_network_interfaces_mac aggregated_network_interfaces_subnets internal_axon_id 5 nexpose_adapter,
esx_adapter,
active_directory_adapter,
solarwinds_orion_adapter,
crowd_strike_adapter,
esx_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
esx_adapterDC4 192.168.20.17,
192.168.20.58,
fe80::2dba:9118:1fc8:7759,
192.168.20.36,
192.168.20.50,
192.168.20.6100:0C:29:B6:DA:46,
00:50:56:91:DE:BB,
00:50:56:91:3A:EC,
00:50:56:91:33:E2,
00:50:56:91:21:B3x.x.x.x/24 d530db3cfef6a2220b315d54fa1901b2
axonius-get-devices-by-ip-regex
Gather device info by IP address using regex
Base Command
axonius-get-devices-by-ip-regex
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The IP address to search for within Axonius. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Devices.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Devices.adapters | String | The specific adapter names with asset information. |
| Axonius.Devices.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Devices.hostname | String | The hostnames of the assset. |
| Axonius.Devices.name | String | The names of the asset. |
| Axonius.Devices.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Devices.network_interfaces_macs | String | The MAC addresses of the asset. |
| Axonius.Devices.network_interfaces_ips | String | The IP addresses of the asset. |
| Axonius.Devices.os_type | String | The OS type (Windows, Linux, macOS,…). |
| Axonius.Devices.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-devices-by-ip-regex value=192.168
Context Example
{
"Axonius": {
"Devices": {
"adapter_list_length": 5,
"adapters": [
"nexpose_adapter",
"esx_adapter",
"active_directory_adapter",
"solarwinds_orion_adapter",
"crowd_strike_adapter",
"esx_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"esx_adapter"
],
"aggregated_hostname": [
"DC4"
],
"aggregated_network_interfaces_ips": [
"x.x.x.x",
],
"aggregated_network_interfaces_mac": [
"00:0C:29:B6:DA:46",
"00:50:56:91:DE:BB",
"00:50:56:91:3A:EC",
"00:50:56:91:33:E2",
"00:50:56:91:21:B3"
],
"aggregated_network_interfaces_subnets": [
"x.x.x.x/24"
],
"internal_axon_id": "d530db3cfef6a2220b315d54fa1901b2"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_hostname aggregated_network_interfaces_ips aggregated_network_interfaces_mac aggregated_network_interfaces_subnets internal_axon_id 5 nexpose_adapter,
esx_adapter,
active_directory_adapter,
solarwinds_orion_adapter,
crowd_strike_adapter,
esx_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
esx_adapterDC4 192.168.20.17,
192.168.20.58,
fe80::2dba:9118:1fc8:7759,
192.168.20.36,
192.168.20.50,
192.168.20.6100:0C:29:B6:DA:46,
00:50:56:91:DE:BB,
00:50:56:91:3A:EC,
00:50:56:91:33:E2,
00:50:56:91:21:B3x.x.x.x/24 d530db3cfef6a2220b315d54fa1901b2
axonius-get-devices-by-mac
Gather device info by MAC address
Base Command
axonius-get-devices-by-mac
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The MAC address to search for within Axonius. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Devices.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Devices.adapters | String | The specific adapter names with asset information. |
| Axonius.Devices.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Devices.hostname | String | The hostnames of the assset. |
| Axonius.Devices.name | String | The names of the asset. |
| Axonius.Devices.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Devices.network_interfaces_macs | String | The MAC addresses of the asset. |
| Axonius.Devices.network_interfaces_ips | String | The IP addresses of the asset. |
| Axonius.Devices.os_type | String | The OS type (Windows, Linux, macOS,…). |
| Axonius.Devices.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-devices-by-mac value=00:0C:29:B6:DA:46
Context Example
{
"Axonius": {
"Devices": {
"adapter_list_length": 5,
"adapters": [
"nexpose_adapter",
"esx_adapter",
"active_directory_adapter",
"solarwinds_orion_adapter",
"crowd_strike_adapter",
"esx_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"esx_adapter"
],
"aggregated_hostname": [
"DC4"
],
"aggregated_network_interfaces_ips": [
"x.x.x.x",
],
"aggregated_network_interfaces_mac": [
"00:0C:29:B6:DA:46",
"00:50:56:91:DE:BB",
"00:50:56:91:3A:EC",
"00:50:56:91:33:E2",
"00:50:56:91:21:B3"
],
"aggregated_network_interfaces_subnets": [
"x.x.x.x/24"
],
"internal_axon_id": "d530db3cfef6a2220b315d54fa1901b2"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_hostname aggregated_network_interfaces_ips aggregated_network_interfaces_mac aggregated_network_interfaces_subnets internal_axon_id 5 nexpose_adapter,
esx_adapter,
active_directory_adapter,
solarwinds_orion_adapter,
crowd_strike_adapter,
esx_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
esx_adapterDC4 192.168.20.17,
192.168.20.58,
fe80::2dba:9118:1fc8:7759,
192.168.20.36,
192.168.20.50,
192.168.20.6100:0C:29:B6:DA:46,
00:50:56:91:DE:BB,
00:50:56:91:3A:EC,
00:50:56:91:33:E2,
00:50:56:91:21:B3x.x.x.x/24 d530db3cfef6a2220b315d54fa1901b2
axonius-get-devices-by-mac-regex
Gather device info by MAC address using regex
Base Command
axonius-get-devices-by-mac-regex
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The MAC address to search for within Axonius. | Required |
| max_results | The maximum number of results to return. Default is 50. | Optional |
| fields | Comma separated list of Axonius fields to return. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Devices.adapter_list_length | Number | The number of adapters with information about the asset. |
| Axonius.Devices.adapters | String | The specific adapter names with asset information. |
| Axonius.Devices.internal_axon_id | String | The internal unique Axonius identifier for the asset. |
| Axonius.Devices.hostname | String | The hostnames of the assset. |
| Axonius.Devices.name | String | The names of the asset. |
| Axonius.Devices.last_seen | Date | Last seen date/time of the asset. |
| Axonius.Devices.network_interfaces_macs | String | The MAC addresses of the asset. |
| Axonius.Devices.network_interfaces_ips | String | The IP addresses of the asset. |
| Axonius.Devices.os_type | String | The OS type (Windows, Linux, macOS,…). |
| Axonius.Devices.labels | String | Tags assigned to the asset. |
Command Example
!axonius-get-devices-by-mac-regex value=DA:46
Context Example
{
"Axonius": {
"Devices": {
"adapter_list_length": 5,
"adapters": [
"nexpose_adapter",
"esx_adapter",
"active_directory_adapter",
"solarwinds_orion_adapter",
"crowd_strike_adapter",
"esx_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"crowd_strike_adapter",
"esx_adapter"
],
"aggregated_hostname": [
"DC4"
],
"aggregated_network_interfaces_ips": [
"x.x.x.x",
],
"aggregated_network_interfaces_mac": [
"00:0C:29:B6:DA:46",
"00:50:56:91:DE:BB",
"00:50:56:91:3A:EC",
"00:50:56:91:33:E2",
"00:50:56:91:21:B3"
],
"aggregated_network_interfaces_subnets": [
"x.x.x.x/24"
],
"internal_axon_id": "d530db3cfef6a2220b315d54fa1901b2"
}
}
}
Human Readable Output
Results
adapter_list_length adapters aggregated_hostname aggregated_network_interfaces_ips aggregated_network_interfaces_mac aggregated_network_interfaces_subnets internal_axon_id 5 nexpose_adapter,
esx_adapter,
active_directory_adapter,
solarwinds_orion_adapter,
crowd_strike_adapter,
esx_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
crowd_strike_adapter,
esx_adapterDC4 192.168.20.17,
192.168.20.58,
fe80::2dba:9118:1fc8:7759,
192.168.20.36,
192.168.20.50,
192.168.20.6100:0C:29:B6:DA:46,
00:50:56:91:DE:BB,
00:50:56:91:3A:EC,
00:50:56:91:33:E2,
00:50:56:91:21:B3x.x.x.x/24 d530db3cfef6a2220b315d54fa1901b2
axonius-add-note
Add note to assets
Base Command
axonius-add-note
Input
| Argument Name | Description | Required |
|---|---|---|
| note | Note to add. | Required |
| ids | IDs of assets. | Required |
| type | Type of Asset. Device or User. Possible values are: devices, users. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.assets.updates | Number | Number of assets updated. |
axonius-add-tag
Add tag to assets
Base Command
axonius-add-tag
Input
| Argument Name | Description | Required |
|---|---|---|
| tag_name | Name of tag to add. | Required |
| ids | IDs of assets. | Required |
| type | Type of Asset. Device or User. Possible values are: devices, users. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.assets.updates | Number | Number of assets updated. |
axonius-remove-tag
Remove tag from assets
Base Command
axonius-remove-tag
Input
| Argument Name | Description | Required |
|---|---|---|
| tag_name | Name of tag to remove. | Required |
| ids | IDs of assets. | Required |
| type | Type of Asset. Devices or Users. Possible values are: devices, users. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.asset.updates | Number | Number of assets updated. |
axonius-get-saved-queries
Get all saved query of a given asset type.
Base Command
axonius-get-saved-queries
Input
| Argument Name | Description | Required |
|---|---|---|
| type | Type of Asset. Device or User. Possible values are: devices, users. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Devices.saved_queries | Unknown | Saved queries. |
| Axonius.Users.saved_queries | Unknown | Saved queries. |
axonius-get-tags
Get all tags of a given asset type.
Base Command
axonius-get-tags
Input
| Argument Name | Description | Required |
|---|---|---|
| type | Type of Asset. Device or User. Possible values are: devices, users. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.tags | Unknown | Axonius Tags. |
axonius-get-assets
Fetch assets of any type using the Axonius v2 API (POST /api/v2/assets/{asset_type}). Supports all asset types including vulnerability_instances. Use next_token for pagination. Large responses (>10 MB) may be stored as a downloadable file by XSOAR instead of being written to the context. NOTE: All calls write to the fixed context key Axonius.Assets regardless of asset_type. If a playbook calls this command more than once with different asset types, each call overwrites the previous result. To avoid data loss, store or transform the context output (e.g. using Set) before issuing a second call with a different type.
Base Command
axonius-get-assets
Input
| Argument Name | Description | Required |
|---|---|---|
| asset_type | The asset type to fetch (e.g. devices, users, vulnerability_instances). See axonius-get-asset-types for all supported values. | Required |
| query | The AQL filter string to narrow the returned assets. | Optional |
| fields | A comma-separated list of fields to include in the response. | Optional |
| fields_to_exclude | A comma-separated list of fields to exclude from the response. | Optional |
| page_size | The number of assets to request per page (1–2000). Keep this value small for large asset types (e.g. vulnerability_instances) to avoid XSOAR context size limits (~10 MB). Default is 50. | Optional |
| limit | The maximum number of assets to return from the page (defaults to page_size). | Optional |
| next_token | The pagination cursor returned from a previous call as Axonius.Assets.next_token. Pass this value to retrieve the next page of results. | Optional |
| include_metadata | Whether to include metadata in the response. Possible values are: true, false. Default is false. | Optional |
| include_details | Whether to include detailed asset data in the response. Possible values are: true, false. Default is false. | Optional |
| use_cache_entry | Whether to use a cached response entry if available. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Assets.asset_type | String | The asset type that was queried. |
| Axonius.Assets.assets | Unknown | The list of asset records returned by the query. |
| Axonius.Assets.count | Number | The number of assets returned in this page. |
| Axonius.Assets.total_count | Number | The total number of assets matching the query (when available). |
| Axonius.Assets.next_token | String | The pagination cursor for the next page of results. Pass this as next_token in the next call. |
axonius-get-asset-types
Return the list of all available asset types in the Axonius instance (GET /api/v2/assets/asset_types).
Base Command
axonius-get-asset-types
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.AssetTypes.asset_type | String | The asset type name. |
| Axonius.AssetTypes | Unknown | The list of available asset types. |
axonius-get-custom-data
List custom data management entries (GET /api/v2/custom_data_management).
Base Command
axonius-get-custom-data
Input
| Argument Name | Description | Required |
|---|---|---|
| page | The page number to retrieve (1-indexed). Default is 1. | Optional |
| page_size | The number of entries to return per page. Default is 50. | Optional |
| limit | The maximum number of entries to return (defaults to page_size). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.CustomData.id | String | The custom data entry unique identifier. |
| Axonius.CustomData | Unknown | The list of custom data entries. |
axonius-create-custom-data
Create a new custom data entry (POST /api/v2/custom_data_management).
Base Command
axonius-create-custom-data
Input
| Argument Name | Description | Required |
|---|---|---|
| payload | The JSON string representing the custom data payload to create. Refer to Axonius API documentation for the required schema. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.CustomData | Unknown | The created custom data entry. |
axonius-delete-custom-data
Delete a custom data entry by ID (DELETE /api/v2/custom_data_management/{id}).
Base Command
axonius-delete-custom-data
Input
| Argument Name | Description | Required |
|---|---|---|
| id | The ID of the custom data entry to delete. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.CustomData.id | String | The ID of the deleted custom data entry. |
| Axonius.CustomData.deleted | Boolean | The flag indicating whether the entry was deleted. |
axonius-get-enforcements
List enforcement sets (GET /api/v2/enforcements).
Base Command
axonius-get-enforcements
Input
| Argument Name | Description | Required |
|---|---|---|
| page | The page number to retrieve (1-indexed). Default is 1. | Optional |
| page_size | The number of enforcements to return per page. Default is 50. | Optional |
| limit | The maximum number of enforcements to return (defaults to page_size). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Enforcements.uuid | String | The enforcement unique identifier. |
| Axonius.Enforcements.name | String | The enforcement name. |
| Axonius.Enforcements | Unknown | The full list of enforcement objects. |
axonius-run-enforcement
Trigger an enforcement run (POST /api/v2/enforcements/{enforcement_id}/run).
Base Command
axonius-run-enforcement
Input
| Argument Name | Description | Required |
|---|---|---|
| enforcement_id | The UUID of the enforcement to run. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Enforcements.enforcement_id | String | The ID of the enforcement that was triggered. |
| Axonius.Enforcements.triggered | Boolean | The flag indicating whether the enforcement was triggered successfully. |
axonius-get-queries
List saved queries (GET /api/v2/queries).
Base Command
axonius-get-queries
Input
| Argument Name | Description | Required |
|---|---|---|
| asset_type | The asset type to filter queries by (e.g. devices, users). | Optional |
| page | The page number to retrieve (1-indexed). Default is 1. | Optional |
| page_size | The number of queries to return per page. Default is 50. | Optional |
| limit | The maximum number of queries to return (defaults to page_size). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Queries.uuid | String | The query unique identifier. |
| Axonius.Queries.name | String | The query name. |
| Axonius.Queries | Unknown | The full list of query objects. |
axonius-create-query
Create a new saved query (POST /api/v2/queries).
Base Command
axonius-create-query
Input
| Argument Name | Description | Required |
|---|---|---|
| name | The name for the new saved query. | Required |
| query | The AQL filter string for the query. | Required |
| asset_type | The asset type this query applies to. Default is devices. | Optional |
| description | The optional description for the query. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Queries.uuid | String | The UUID of the created query. |
| Axonius.Queries.name | String | The name of the created query. |
| Axonius.Queries | Unknown | The created query object. |
axonius-delete-query
Delete a saved query (DELETE /api/v2/queries/{query_id}).
Base Command
axonius-delete-query
Input
| Argument Name | Description | Required |
|---|---|---|
| query_id | The UUID of the query to delete. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.Queries.query_id | String | The ID of the deleted query. |
| Axonius.Queries.deleted | Boolean | The flag indicating whether the query was deleted. |
axonius-get-grouped-vulnerabilities
Fetch all vulnerability instances, flatten them, group by CVE ID, and return the Top N CVEs sorted by affected host count. Computes average_cvss_score per CVE. Outputs as Axonius.GroupedVulnerabilities keyed by cve_id.
Base Command
axonius-get-grouped-vulnerabilities
Input
| Argument Name | Description | Required |
|---|---|---|
| query | The optional AQL filter applied before grouping. | Optional |
| team_name | The team name to filter vulnerability instances by. | Optional |
| urgent | Whether to filter by urgency on vulnerability instances. Possible values are: true, false. | Optional |
| top_n | The number of top CVEs to return (sorted by affected_hosts_count descending). Default is 10. | Optional |
| page_size | The number of records per page when fetching all instances. Default is 100. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Axonius.GroupedVulnerabilities.cve_id | String | The CVE identifier. |
| Axonius.GroupedVulnerabilities.affected_hosts_count | Number | The number of hosts affected by this CVE. |
| Axonius.GroupedVulnerabilities.average_cvss_score | Number | The average CVSS score across all instances of this CVE. |
Configuration parameters
ax_url— Server URL (e.g. https://example.net) (required)credentials— API Key (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (30)
-
axonius-add-noteAdd note to assets.
-
axonius-add-tagAdd tag to assets.
-
axonius-create-custom-dataCreate a new custom data entry (POST /api/v2/custom_data_management).
-
axonius-create-queryCreate a new saved query (POST /api/v2/queries).
-
axonius-delete-custom-dataDelete a custom data entry by ID (DELETE /api/v2/custom_data_management/{id}).
-
axonius-delete-queryDelete a saved query (DELETE /api/v2/queries/{query_id}).
-
axonius-get-asset-typesReturn the list of all available asset types in the Axonius instance (GET /api/v2/assets/asset_types).
-
axonius-get-assetsFetch assets of any type using the Axonius v2 API (POST /api/v2/assets/{asset_type}). Supports all asset types including vulnerability_instances. Use next_token for pagination. Large responses (>10 MB) may be stored as a downloadable file by XSOAR instead of being written to the context. NOTE: All calls write to the fixed context key Axonius.Assets regardless of asset_type. If a playbook calls this command more than once with different asset types, each call overwrites the previous result. To avoid data loss, store or transform the context output (e.g. using Set) before issuing a second call with a different type.
-
axonius-get-custom-dataList custom data management entries (GET /api/v2/custom_data_management).
-
axonius-get-devices-by-aqlGather devices info by AQL query.
-
axonius-get-devices-by-hostnameGather device info by hostname.
-
axonius-get-devices-by-hostname-regexGather device info by hostname using regex.
-
axonius-get-devices-by-ipGather device info by IP address.
-
axonius-get-devices-by-ip-regexGather device info by IP address using regex.
-
axonius-get-devices-by-macGather device info by MAC address.
-
axonius-get-devices-by-mac-regexGather device info by MAC address using regex.
-
axonius-get-devices-by-savedqueryGather device info by saved query.
-
axonius-get-enforcementsList enforcement sets (GET /api/v2/enforcements).
-
axonius-get-grouped-vulnerabilitiesFetch all vulnerability instances, flatten them, group by CVE ID, and return the Top N CVEs sorted by affected host count. Computes average_cvss_score per CVE. Outputs as Axonius.GroupedVulnerabilities keyed by cve_id.
-
axonius-get-queriesList saved queries (GET /api/v2/queries).
-
axonius-get-saved-queriesGet all saved query of a given asset type.
-
axonius-get-tagsGet all tags of a given asset type.
-
axonius-get-users-by-aqlGather users info by AQL query.
-
axonius-get-users-by-mailGather user info by email address.
-
axonius-get-users-by-mail-regexGather user info by email address using regex.
-
axonius-get-users-by-savedqueryGather user info by saved query.
-
axonius-get-users-by-usernameGather user info by username.
-
axonius-get-users-by-username-regexGather user info by username using regex.
-
axonius-remove-tagRemove tag from assets.
-
axonius-run-enforcementTrigger an enforcement run (POST /api/v2/enforcements/{enforcement_id}/run).
"""Demisto Integration for Axonius.""" import json import requests from axonius_api_client.api.assets.devices import Devices from axonius_api_client.api.assets.users import Users from axonius_api_client.connect import Connect from axonius_api_client.tools import dt_parse, strip_left from CommonServerPython import * # Added ignore RemovedInMarshmallow4Warning in Axonius_test file. MAX_ROWS: int = 50 """Maximum number of assets to allow user to fetch.""" SKIPS: List[str] = ["specific_data.data.image", "view"] """Fields to remove from each asset if found.""" FIELDS_TIME: List[str] = ["seen", "fetch", "time", "date"] """Fields to try and convert to date time if they have these words in them.""" AXONIUS_ID = "internal_axon_id" V2_PAGE_SIZE_DEFAULT: int = 50 """Default page size for v2 API pagination.""" V2_PAGE_SIZE_ALL_PAGES: int = 100 """Page size used when fetching all pages.""" MAX_PAGES: int = 200 """Maximum number of pages to fetch in a single paginated request (infinite-loop guard).""" REQUEST_TIMEOUT: int = 30 """HTTP request timeout in seconds to prevent silent hangs in Playbooks.""" def get_int_arg( key: str, required: Optional[bool] = False, default: Optional[int] = None, ) -> int: """Get a key from a command arg and convert it into an int.""" args: dict = demisto.args() value: int = args.get(key, default) if value is None and required: raise ValueError(f"No value supplied for argument {key!r}") try: return int(value) except Exception: raise ValueError(f"Supplied value {value!r} for argument {key!r} is not an integer.") def get_csv_arg( key: str, required: Optional[bool] = False, default: Optional[str] = "", ) -> List[str]: """Get string values from CSV.""" args: dict = demisto.args() value: List[str] = argToList(arg=args.get(key, default)) value = [x for x in value if x] if not value and required: raise ValueError(f"No value supplied for argument {key!r}") return value def test_module(client: Connect) -> str: """Tests Axonius API Client connectivity.""" client.start() return "ok" def parse_kv(key: str, value: Any) -> Any: """Parse time stamp into required format.""" for word in FIELDS_TIME: if word in key: try: return dt_parse(value).isoformat() except Exception: return value return value def parse_key(key: str) -> str: """Parse fields into required format.""" if key.startswith("specific_data.data."): key = strip_left(obj=key, fix="specific_data.data.") key = f"aggregated_{key}" if key.startswith("adapters_data."): key = strip_left(obj=key, fix="adapters_data.") key = key.replace(".", "_") return key def parse_asset(asset: dict) -> dict: """Initiate field format correction on assets.""" return {parse_key(key=k): parse_kv(key=k, value=v) for k, v in asset.items() if k not in SKIPS} def get_saved_queries(client: Connect, args: dict) -> CommandResults: # noqa: F821, F405 """Get assets with their defined fields returned by a saved query.""" api_obj = client.devices if args["type"] == "devices" else client.users saved_queries = api_obj.saved_query.get() return parse_assets( assets=saved_queries, api_obj=api_obj, outputs_key_field="", extension="saved_queries", exclude_raw=True, ) def make_api_call( endpoint: str, payload: dict = None, method: str = "POST", query_params: dict = None, ) -> requests.Response | None: """Make an authenticated HTTP API call to the Axonius instance. Args: endpoint: API endpoint path (appended to the base URL). payload: JSON body for POST/DELETE requests. method: HTTP method — GET, POST, or DELETE (default: POST). query_params: URL query parameters for GET requests. Returns: The HTTP response, or None if no URL is configured. """ params: dict = demisto.params() url: str | None = params.get("ax_url") key: str = params.get("credentials", {}).get("identifier") secret: str = params.get("credentials", {}).get("password") certverify: bool = not params.get("insecure", False) if not url: return None url = url + "/" if url[-1] != "/" else url url = url + endpoint headers: dict = { "accept": "application/json", "api-key": key, "api-secret": secret, "content-type": "application/json", } try: if method == "GET": return requests.get(url, headers=headers, params=query_params, verify=certverify, timeout=REQUEST_TIMEOUT) elif method == "DELETE": return requests.delete(url, json=payload, headers=headers, verify=certverify, timeout=REQUEST_TIMEOUT) else: return requests.post(url, json=payload, headers=headers, verify=certverify, timeout=REQUEST_TIMEOUT) except requests.exceptions.Timeout as exc: raise DemistoException(f"Request to Axonius timed out: {exc}") from exc except requests.exceptions.RequestException as exc: raise DemistoException(f"Error connecting to Axonius: {exc}") from exc def _handle_api_response(response: Optional[requests.Response], endpoint: str) -> dict: """Validate an API response and return parsed JSON. Raises: DemistoException: on missing URL, non-2xx status, or invalid JSON. """ if response is None: raise DemistoException("No URL configured for the Axonius instance.") if not response.ok: raise DemistoException(f"API call to '{endpoint}' failed with HTTP {response.status_code}: {response.text[:1000]}") if not response.content: return {} try: return response.json() except ValueError as exc: raise DemistoException(f"Failed to parse response from '{endpoint}' as JSON: {exc}") from exc def add_note(client: Connect, args: dict) -> CommandResults: """Add notes to assets.""" note: str = args["note"] asset_type: str = args["type"] internal_axon_id_arr: list = args["ids"] success_count: int = 0 if isinstance(internal_axon_id_arr, str): internal_axon_id_arr = argToList(internal_axon_id_arr, separator=",") payload: dict = { "meta": None, "data": { "attributes": { "note": note, }, "type": "notes_schema", }, } for id in internal_axon_id_arr: response = make_api_call(endpoint=f"api/{asset_type}/{id}/notes", payload=payload) if response and response.status_code == 200: success_count += 1 readable_output = f"{success_count} {asset_type}(s) updated." return CommandResults( outputs_prefix="Axonius.asset.updates", readable_output=readable_output, outputs=success_count, raw_response=success_count, ) def get_tags(client: Connect, args: dict) -> CommandResults: # noqa: F821, F405 """Get assets with their defined fields returned by a saved query.""" api_obj = client.devices if args["type"] == "devices" else client.users tags = api_obj.labels.get() return CommandResults( outputs_prefix=f"Axonius.tags.{args['type']}", readable_output=",".join(tags), outputs=tags, raw_response=tags, ) def update_tags(client: Connect, args: dict, method_name: str) -> CommandResults: # noqa: F821, F405 tag_name: str = args["tag_name"] internal_axon_id_arr: list = args["ids"] if isinstance(internal_axon_id_arr, str): internal_axon_id_arr = argToList(internal_axon_id_arr, separator=",") api_obj = client.devices if args["type"] == "devices" else client.users api_name = api_obj.__class__.__name__ if method_name == "add": res = api_obj.labels.add(rows=internal_axon_id_arr, labels=[tag_name]) else: res = api_obj.labels.remove(rows=internal_axon_id_arr, labels=[tag_name]) # res is count of rows included in the output, regardless of success. readable_output = f"{res} {api_name}(s) updated." return CommandResults( outputs_prefix=f"Axonius.asset.updates.{args['type']}", readable_output=readable_output, outputs=res, raw_response=res, ) def get_by_sq(api_obj: Union[Users, Devices], args: dict) -> CommandResults: # noqa: F821, F405 """Get assets with their defined fields returned by a saved query.""" name: str = args["saved_query_name"] fields: List[str] = get_csv_arg(key="fields", required=False) max_rows: int = get_int_arg(key="max_results", required=False, default=MAX_ROWS) assets = api_obj.get_by_saved_query(name=name, max_rows=max_rows, fields=fields) return parse_assets(assets=assets, api_obj=api_obj) def get_by_value( api_obj: Union[Users, Devices], args: dict, method_name: str, ) -> CommandResults: # noqa: F821, F405 """Get assets by a value using a api_obj.get_by_{method_name}.""" api_name = api_obj.__class__.__name__ value: str = args["value"] fields: List[str] = get_csv_arg(key="fields", required=False) max_rows: int = get_int_arg(key="max_results", required=False, default=MAX_ROWS) api_method_name = f"get_by_{method_name}" if not hasattr(api_obj, api_method_name): valid = [] for x in dir(api_obj): if not x.startswith("get_by_") or x.endswith("s"): continue valid.append(x.replace("get_by_", "")) valid = ", ".join(valid) raise Exception(f"Invalid get by {method_name} for {api_name}, valid: {valid}") method = getattr(api_obj, api_method_name) assets = method(value=value, max_rows=max_rows, fields=fields) return parse_assets(assets=assets, api_obj=api_obj) def get( api_obj: Union[Users, Devices], args: dict, ) -> CommandResults: """Get assets by a query using a api_obj.get.""" query: str = args["query"] fields: List[str] = get_csv_arg(key="fields", required=False) max_rows: int = get_int_arg(key="max_results", required=False, default=MAX_ROWS) assets = api_obj.get(query=query, max_rows=max_rows, fields=fields) return parse_assets(assets=assets, api_obj=api_obj) def parse_assets( assets: List[dict], api_obj: Union[Users, Devices], outputs_key_field=AXONIUS_ID, extension="", exclude_raw=False, ) -> CommandResults: # noqa: F821, F405 """Parse assets into CommandResults.""" api_name = api_obj.__class__.__name__ aql = api_obj.LAST_GET.get("filter") results = [parse_asset(asset=asset) for asset in assets] readable_output: Optional[str] = None outputs: Union[List[dict], dict] = results if not results: readable_output = f"No {api_name} assets found using AQL: {aql}" if len(results) == 1: outputs = results[0] outputs_prefix = f"Axonius.{api_name}" if extension: outputs_prefix += f".{extension}" raw_response = None if exclude_raw else assets return CommandResults( outputs_prefix=outputs_prefix, outputs_key_field=outputs_key_field, readable_output=readable_output, outputs=outputs, raw_response=raw_response, ) # noqa: F821, F405 # --------------------------------------------------------------------------- # v2 API helpers # --------------------------------------------------------------------------- def _build_v2_page(limit: int, cursor: Optional[str] = None) -> dict: """Build a v2 API page object.""" page: dict = {"limit": limit} if cursor: page["cursor"] = cursor return page # --------------------------------------------------------------------------- # axonius-get-assets # --------------------------------------------------------------------------- def get_assets(args: dict) -> CommandResults: """Fetch assets of any type via POST /api/v2/assets/{asset_type}. Supports all asset types including alert_findings and vulnerability_instances. Returns a single page of results together with a cursor (next_token) for subsequent calls. Note on large payloads: when a response exceeds ~10 MB, XSOAR automatically stores the data as a downloadable file instead of writing it to the context. Use the page_size argument to keep responses within manageable bounds. """ asset_type: str = args.get("asset_type", "devices") query: Optional[str] = args.get("query") or None fields: List[str] = argToList(args.get("fields")) fields_to_exclude: List[str] = argToList(args.get("fields_to_exclude")) page_size: int = arg_to_number(args.get("page_size")) or V2_PAGE_SIZE_DEFAULT limit: int = arg_to_number(args.get("limit")) or page_size next_token: Optional[str] = args.get("next_token") or None include_metadata: bool = argToBoolean(args.get("include_metadata", False)) include_details: bool = argToBoolean(args.get("include_details", False)) use_cache_entry: bool = argToBoolean(args.get("use_cache_entry", False)) payload: dict = {"page": _build_v2_page(limit=page_size, cursor=next_token)} if query: payload["query"] = query if fields: payload["fields"] = fields if fields_to_exclude: payload["fields_to_exclude"] = fields_to_exclude if include_metadata: payload["include_metadata"] = True if include_details: payload["include_details"] = True if use_cache_entry: payload["use_cache_entry"] = True endpoint = f"api/v2/assets/{asset_type}" response = make_api_call(endpoint=endpoint, payload=payload, method="POST") data = _handle_api_response(response=response, endpoint=endpoint) assets: List[dict] = data.get("assets") or [] assets = assets[:limit] meta: dict = data.get("meta") or {} next_cursor: Optional[str] = meta.get("next_page") page_meta: dict = meta.get("page") or {} total_count: Optional[int] = page_meta.get("totalResources") if not assets: readable_output = f"No {asset_type} assets found." else: readable_output = tableToMarkdown( f"Axonius Assets — {asset_type} ({len(assets)} returned)", assets, removeNull=True, ) outputs: dict = { "asset_type": asset_type, "assets": assets, "count": len(assets), } if total_count is not None: outputs["total_count"] = total_count if next_cursor: outputs["next_token"] = next_cursor return CommandResults( outputs_prefix="Axonius.Assets", outputs_key_field="asset_type", readable_output=readable_output, outputs=outputs, raw_response=data, ) # --------------------------------------------------------------------------- # axonius-get-asset-types # --------------------------------------------------------------------------- def get_asset_types() -> CommandResults: """Return available asset types via GET /api/v2/assets/asset_types.""" endpoint = "api/v2/assets/asset_types" response = make_api_call(endpoint=endpoint, method="GET") data = _handle_api_response(response=response, endpoint=endpoint) raw_types: list = data.get("asset_types") or [] asset_types: List[dict] = [t if isinstance(t, dict) else {"asset_type": t} for t in raw_types] readable_output = tableToMarkdown("Axonius Asset Types", asset_types, removeNull=True) return CommandResults( outputs_prefix="Axonius.AssetTypes", outputs_key_field="asset_type", readable_output=readable_output, outputs=asset_types, raw_response=data, ) # --------------------------------------------------------------------------- # Custom Data Management # --------------------------------------------------------------------------- def get_custom_data(args: dict) -> CommandResults: """List custom data entries via GET /api/v2/custom_data_management.""" page: int = arg_to_number(args.get("page")) or 1 page_size: int = arg_to_number(args.get("page_size")) or 50 limit: int = arg_to_number(args.get("limit")) or page_size offset: int = (page - 1) * page_size endpoint = "api/v2/custom_data_management" response = make_api_call( endpoint=endpoint, method="GET", query_params={"limit": min(page_size, limit), "offset": offset}, ) data = _handle_api_response(response=response, endpoint=endpoint) entries: list = (data.get("custom_fields") or [])[:limit] readable_output = tableToMarkdown( "Axonius Custom Data", entries, removeNull=True, ) return CommandResults( outputs_prefix="Axonius.CustomData", outputs_key_field="id", readable_output=readable_output, outputs=entries, raw_response=data, ) def create_custom_data(args: dict) -> CommandResults: """Create a custom data entry via POST /api/v2/custom_data_management.""" payload_str: Optional[str] = args.get("payload") if not payload_str: raise DemistoException("The 'payload' argument is required for axonius-create-custom-data.") try: payload: dict = json.loads(payload_str) except (ValueError, TypeError) as exc: raise DemistoException(f"Invalid JSON in 'payload' argument: {exc}") from exc endpoint = "api/v2/custom_data_management" response = make_api_call(endpoint=endpoint, payload=payload, method="POST") data = _handle_api_response(response=response, endpoint=endpoint) return CommandResults( outputs_prefix="Axonius.CustomData", readable_output="Custom data entry created successfully.", outputs=data, raw_response=data, ) def delete_custom_data(args: dict) -> CommandResults: """Delete a custom data entry via DELETE /api/v2/custom_data_management/{id}.""" entry_id: str = args.get("id", "") if not entry_id: raise DemistoException("The 'id' argument is required for axonius-delete-custom-data.") endpoint = f"api/v2/custom_data_management/{entry_id}" response = make_api_call(endpoint=endpoint, method="DELETE") _handle_api_response(response=response, endpoint=endpoint) return CommandResults( outputs_prefix="Axonius.CustomData", readable_output=f"Custom data entry '{entry_id}' deleted successfully.", outputs={"id": entry_id, "deleted": True}, ) # --------------------------------------------------------------------------- # Enforcements # --------------------------------------------------------------------------- def get_enforcements(args: dict) -> CommandResults: """List enforcements via GET /api/v2/enforcements.""" page: int = arg_to_number(args.get("page")) or 1 page_size: int = arg_to_number(args.get("page_size")) or 50 limit: int = arg_to_number(args.get("limit")) or page_size offset: int = (page - 1) * page_size endpoint = "api/v2/enforcements" response = make_api_call( endpoint=endpoint, method="GET", query_params={"limit": min(page_size, limit), "offset": offset}, ) data = _handle_api_response(response=response, endpoint=endpoint) enforcements: list = (data.get("enforcements") or [])[:limit] readable_output = tableToMarkdown( "Axonius Enforcements", enforcements, removeNull=True, ) return CommandResults( outputs_prefix="Axonius.Enforcements", outputs_key_field="uuid", readable_output=readable_output, outputs=enforcements, raw_response=data, ) def run_enforcement(args: dict) -> CommandResults: """Trigger an enforcement run via POST /api/v2/enforcements/{id}/run.""" enforcement_id: str = args.get("enforcement_id", "") if not enforcement_id: raise DemistoException("The 'enforcement_id' argument is required for axonius-run-enforcement.") endpoint = f"api/v2/enforcements/{enforcement_id}/run" response = make_api_call(endpoint=endpoint, method="POST") data = _handle_api_response(response=response, endpoint=endpoint) return CommandResults( outputs_prefix="Axonius.Enforcements", readable_output=f"Enforcement '{enforcement_id}' triggered successfully.", outputs={"enforcement_id": enforcement_id, "triggered": True, "response": data}, raw_response=data, ) # --------------------------------------------------------------------------- # Queries # --------------------------------------------------------------------------- def get_queries(args: dict) -> CommandResults: """List saved queries via GET /api/v2/queries.""" asset_type: Optional[str] = args.get("asset_type") or None page: int = arg_to_number(args.get("page")) or 1 page_size: int = arg_to_number(args.get("page_size")) or 50 limit: int = arg_to_number(args.get("limit")) or page_size offset: int = (page - 1) * page_size endpoint = "api/v2/queries" qp: dict = {"limit": min(page_size, limit), "offset": offset} if asset_type: qp["asset_type"] = asset_type response = make_api_call(endpoint=endpoint, method="GET", query_params=qp) data = _handle_api_response(response=response, endpoint=endpoint) queries: list = (data.get("queries") or [])[:limit] readable_output = tableToMarkdown( "Axonius Queries", queries, removeNull=True, ) return CommandResults( outputs_prefix="Axonius.Queries", outputs_key_field="uuid", readable_output=readable_output, outputs=queries, raw_response=data, ) def create_query(args: dict) -> CommandResults: """Create a saved query via POST /api/v2/queries.""" name: str = args.get("name", "") query: str = args.get("query", "") asset_type: str = args.get("asset_type", "devices") description: Optional[str] = args.get("description") or None if not name: raise DemistoException("The 'name' argument is required for axonius-create-query.") if not query: raise DemistoException("The 'query' argument is required for axonius-create-query.") payload: dict = {"name": name, "query": query, "asset_type": asset_type} if description: payload["description"] = description endpoint = "api/v2/queries" response = make_api_call(endpoint=endpoint, payload=payload, method="POST") data = _handle_api_response(response=response, endpoint=endpoint) return CommandResults( outputs_prefix="Axonius.Queries", outputs_key_field="uuid", readable_output=f"Query '{name}' created successfully.", outputs=data, raw_response=data, ) def delete_query(args: dict) -> CommandResults: """Delete a saved query via DELETE /api/v2/queries/{query_id}.""" query_id: str = args.get("query_id", "") if not query_id: raise DemistoException("The 'query_id' argument is required for axonius-delete-query.") endpoint = f"api/v2/queries/{query_id}" response = make_api_call(endpoint=endpoint, method="DELETE") _handle_api_response(response=response, endpoint=endpoint) return CommandResults( outputs_prefix="Axonius.Queries", readable_output=f"Query '{query_id}' deleted successfully.", outputs={"query_id": query_id, "deleted": True}, ) # --------------------------------------------------------------------------- # Grouped Vulnerabilities # --------------------------------------------------------------------------- def _fetch_all_pages(asset_type: str, query: Optional[str] = None, page_size: int = V2_PAGE_SIZE_ALL_PAGES) -> List[dict]: """Fetch all pages of an asset type from the v2 API. Args: asset_type: Axonius asset type (e.g. 'vulnerability_instances'). query: Optional AQL filter string. page_size: Number of records per page request. Returns: Flat list of all asset records across all pages. """ all_assets: List[dict] = [] cursor: Optional[str] = None endpoint = f"api/v2/assets/{asset_type}" for _ in range(MAX_PAGES): payload: dict = {"page": _build_v2_page(limit=page_size, cursor=cursor)} if query: payload["query"] = query response = make_api_call(endpoint=endpoint, payload=payload, method="POST") data = _handle_api_response(response=response, endpoint=endpoint) page_assets: List[dict] = data.get("assets") or [] all_assets.extend(page_assets) meta: dict = data.get("meta") or {} cursor = meta.get("next_page") if not cursor or not page_assets: break else: if cursor: demisto.debug( f"_fetch_all_pages: reached MAX_PAGES ({MAX_PAGES}) for '{asset_type}'; " f"stopping pagination early with {len(all_assets)} records collected." ) return all_assets def _flatten_instance(instance: dict) -> dict: """Flatten single-element lists in a vulnerability instance dict.""" flattened: dict = {} for key, value in instance.items(): if isinstance(value, list) and len(value) == 1: flattened[key] = value[0] else: flattened[key] = value return flattened def _safe_float(value: Any) -> Optional[float]: """Convert value to float, returning None on failure.""" try: return float(value) except (TypeError, ValueError): return None def get_grouped_vulnerabilities(args: dict) -> CommandResults: """Fetch all vulnerability instances and group them by CVE ID. Fetches all pages of /v2/assets/vulnerability_instances, flattens each instance, groups by cve_id, counts affected hosts, averages CVSS scores, and returns the Top N CVEs sorted by affected_hosts_count descending. """ query: Optional[str] = args.get("query") or None team_name: Optional[str] = args.get("team_name") or None urgent: Optional[str] = args.get("urgent") or None top_n: int = arg_to_number(args.get("top_n")) or 10 page_size: int = arg_to_number(args.get("page_size")) or V2_PAGE_SIZE_ALL_PAGES # Build composite query filter query_parts: List[str] = [] if query: query_parts.append(query) if team_name: query_parts.append(f'(specific_data.data.team_name == "{team_name}")') if urgent is not None: urgent_bool = "true" if argToBoolean(urgent) else "false" query_parts.append(f"(specific_data.data.urgent == {urgent_bool})") final_query = " and ".join(query_parts) if query_parts else None instances = _fetch_all_pages(asset_type="vulnerability_instances", query=final_query, page_size=page_size) if not instances: return CommandResults( outputs_prefix="Axonius.GroupedVulnerabilities", outputs_key_field="cve_id", readable_output="No vulnerability instances found.", outputs=[], ) # Group by CVE ID grouped: dict = {} for raw in instances: inst = _flatten_instance(raw) cve_id = inst.get("cve_id") or inst.get("specific_data.data.cve_id") if not cve_id: continue if cve_id not in grouped: grouped[cve_id] = {"affected_hosts_count": 0, "cvss_scores": []} grouped[cve_id]["affected_hosts_count"] += 1 cvss = _safe_float(inst.get("cvss_score") or inst.get("specific_data.data.cvss_score")) if cvss is not None: grouped[cve_id]["cvss_scores"].append(cvss) # Build sorted output results: List[dict] = [] for cve_id, group_data in grouped.items(): scores = group_data["cvss_scores"] avg_cvss = round(sum(scores) / len(scores), 2) if scores else None results.append( { "cve_id": cve_id, "affected_hosts_count": group_data["affected_hosts_count"], "average_cvss_score": avg_cvss, } ) results.sort(key=lambda x: x["affected_hosts_count"], reverse=True) top_results = results[:top_n] readable_output = tableToMarkdown( f"Top {top_n} CVEs by Affected Hosts", top_results, removeNull=True, ) return CommandResults( outputs_prefix="Axonius.GroupedVulnerabilities", outputs_key_field="cve_id", readable_output=readable_output, outputs=top_results, raw_response=top_results, ) def run_command(client: Connect, args: dict, command: str): results: Union[CommandResults, str, None] = None if command == "test-module": results = test_module(client=client) elif command == "axonius-get-devices-by-savedquery": results = get_by_sq(api_obj=client.devices, args=args) elif command == "axonius-get-users-by-savedquery": results = get_by_sq(api_obj=client.users, args=args) elif command == "axonius-get-devices-by-aql": results = get(api_obj=client.devices, args=args) elif command == "axonius-get-users-by-aql": results = get(api_obj=client.users, args=args) elif command == "axonius-get-users-by-mail": results = get_by_value(api_obj=client.users, args=args, method_name="mail") elif command == "axonius-get-users-by-mail-regex": results = get_by_value(api_obj=client.users, args=args, method_name="mail_regex") elif command == "axonius-get-users-by-username": results = get_by_value(api_obj=client.users, args=args, method_name="username") elif command == "axonius-get-users-by-username-regex": results = get_by_value(api_obj=client.users, args=args, method_name="username_regex") elif command == "axonius-get-devices-by-hostname": results = get_by_value(api_obj=client.devices, args=args, method_name="hostname") elif command == "axonius-get-devices-by-hostname-regex": results = get_by_value(api_obj=client.devices, args=args, method_name="hostname_regex") elif command == "axonius-get-devices-by-ip": results = get_by_value(api_obj=client.devices, args=args, method_name="ip") elif command == "axonius-get-devices-by-ip-regex": results = get_by_value(api_obj=client.devices, args=args, method_name="ip_regex") elif command == "axonius-get-devices-by-mac": results = get_by_value(api_obj=client.devices, args=args, method_name="mac") elif command == "axonius-get-devices-by-mac-regex": results = get_by_value(api_obj=client.devices, args=args, method_name="mac_regex") elif command == "axonius-get-saved-queries": results = get_saved_queries(client=client, args=args) elif command == "axonius-get-tags": results = get_tags(client=client, args=args) elif command == "axonius-add-note": results = add_note(client=client, args=args) elif command == "axonius-add-tag": results = update_tags(client=client, args=args, method_name="add") elif command == "axonius-remove-tag": results = update_tags(client=client, args=args, method_name="remove") # v2 API commands elif command == "axonius-get-assets": results = get_assets(args=args) elif command == "axonius-get-asset-types": results = get_asset_types() elif command == "axonius-get-custom-data": results = get_custom_data(args=args) elif command == "axonius-create-custom-data": results = create_custom_data(args=args) elif command == "axonius-delete-custom-data": results = delete_custom_data(args=args) elif command == "axonius-get-enforcements": results = get_enforcements(args=args) elif command == "axonius-run-enforcement": results = run_enforcement(args=args) elif command == "axonius-get-queries": results = get_queries(args=args) elif command == "axonius-create-query": results = create_query(args=args) elif command == "axonius-delete-query": results = delete_query(args=args) elif command == "axonius-get-grouped-vulnerabilities": results = get_grouped_vulnerabilities(args=args) return results def main(): """PARSE AND VALIDATE INTEGRATION PARAMS.""" params: dict = demisto.params() command: str = demisto.command() url: str = params["ax_url"] key: str = params.get("credentials", {}).get("identifier") secret: str = params.get("credentials", {}).get("password") certverify: bool = not params.get("insecure", False) proxies: dict = handle_proxy() # noqa: F821, F405 demisto.debug(f"Attempting to connect via proxy with: {proxies}") demisto.debug(f"Command being called is {command}") args: dict = demisto.args() try: client = Connect( url=url, key=key, secret=secret, certverify=certverify, certwarn=False, proxy=proxies.get("https") or proxies.get("http"), ) return_results(run_command(client, args, command)) # noqa: F821, F405 except Exception as exc: demisto.error(traceback.format_exc()) msg: List[str] = [f"Failed to execute {command} command", "Error:", str(exc)] return_error("\n".join(msg)) # noqa: F821, F405 if __name__ in ("__main__", "__builtin__", "builtins"): main()