From ad617e668b61363597a2e87a6eabe73a07770078 Mon Sep 17 00:00:00 2001 From: MaxBish Date: Wed, 20 May 2026 13:48:57 -0700 Subject: [PATCH 1/3] Add Nexthink inbound custom integration with export workflow --- README.md | 1 + nexthink/README.md | 110 ++++++++ nexthink/config.json | 4 + nexthink/custom-integration-nexthink.star | 294 ++++++++++++++++++++++ 4 files changed, 409 insertions(+) create mode 100644 nexthink/README.md create mode 100644 nexthink/config.json create mode 100644 nexthink/custom-integration-nexthink.star diff --git a/README.md b/README.md index aa76fe7..078e56e 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ If you need help setting up a custom integration, you can create an [issue](http - [Manage Engine Endpoint Central](https://github.com/runZeroInc/runzero-custom-integrations/blob/main/manage-engine-endpoint-central/) - [Moysle](https://github.com/runZeroInc/runzero-custom-integrations/blob/main/moysle/) - [Netskope](https://github.com/runZeroInc/runzero-custom-integrations/blob/main/netskope/) +- [Nexthink](https://github.com/runZeroInc/runzero-custom-integrations/blob/main/nexthink/) - [NinjaOne](https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ninjaone/) - [pfSense](https://github.com/runZeroInc/runzero-custom-integrations/blob/main/pfsense/) - [Proxmox](https://github.com/runZeroInc/runzero-custom-integrations/blob/main/proxmox/) diff --git a/nexthink/README.md b/nexthink/README.md new file mode 100644 index 0000000..abd1f3f --- /dev/null +++ b/nexthink/README.md @@ -0,0 +1,110 @@ +# Custom Integration: Nexthink + +## runZero requirements + +- Superuser access to the runZero Custom Integrations configuration +- Access to create credentials and ingest tasks in runZero + +## Nexthink requirements + +- Nexthink API credentials (Client ID and Client Secret) +- Permissions to run NQL API queries and exports +- A saved NQL API query ID (default in script: `#runzero_integration`) + +## What this integration imports + +The script imports assets from Nexthink using NQL export workflow and maps: + +- `id` from `device.uid` +- `hostnames` from `device.name` +- `os` from `device.operating_system.name` +- `osVersion` derived from `device.operating_system.build` +- `networkInterfaces` from `device.collector.local_ip` +- `customAttributes`: + - `nexthink.first_seen` + - `nexthink.last_seen` + - `nexthink.hardware.manufacturer` + - `nexthink.hardware.model` + - `nexthink.hardware.chassis_serial_number` + - `nexthink.operating_system.build` + - `nexthink.collector.local_ip` + +## Steps + +### 1. Configure Nexthink + +1. Create API credentials in Nexthink for a service account. +2. Ensure the account has permissions to manage/execute NQL API queries. +3. Create a saved NQL API query in Nexthink Content Management. +4. Ensure your NQL query returns these fields: + - `device.uid` + - `device.name` + - `device.operating_system.name` + - `device.operating_system.build` + - `device.collector.local_ip` + - `device.hardware.manufacturer` + - `device.hardware.model` + - `device.hardware.chassis_serial_number` + - `device.first_seen` + - `device.last_seen` + +### 2. Configure the script + +Edit [nexthink/custom-integration-nexthink.star](nexthink/custom-integration-nexthink.star) constants: + +- `AUTH_URL` format: `https://-login..nexthink.cloud` +- `API_URL` format: `https://.api..nexthink.cloud` +- `QUERY_ID` format: `#` +- `SCOPE` usually: `service:integration` + +### 3. Configure runZero credential + +1. In runZero, create a credential of type Custom Integration Script Secrets. +2. Set: + - `access_key` = Nexthink Client ID + - `access_secret` = Nexthink Client Secret + +### 4. Configure runZero custom integration + +1. Create a new custom integration in runZero. +2. Paste the script from [nexthink/custom-integration-nexthink.star](nexthink/custom-integration-nexthink.star). +3. Validate and save. + +### 5. Create an ingest task + +1. Create a custom ingest task. +2. Select the credential and custom integration. +3. Select an explorer. +4. Save and run. + +## Validation checklist + +- Task succeeds without authentication errors. +- Export starts and reaches `COMPLETED`. +- Assets in runZero show `custom_integration:nexthink`. +- Imported assets include expected hostnames, OS, and custom attributes. + +## Troubleshooting + +- `No rows returned from Nexthink export workflow`: + - Verify query fields and data availability in Nexthink. + - Verify `QUERY_ID` matches a saved Nexthink query. +- `Failed to download export results ... Only one auth mechanism allowed`: + - Ensure no `Authorization` header is sent to `resultsFileUrl`. +- Exactly 1,000 rows imported: + - This script already uses export workflow to avoid execute endpoint limits. + +## Preparing a pull request + +1. Ensure these files exist: + - [nexthink/custom-integration-nexthink.star](nexthink/custom-integration-nexthink.star) + - [nexthink/config.json](nexthink/config.json) + - [nexthink/README.md](nexthink/README.md) +2. Verify your branch is `nexthink` and only intended files changed. +3. Run a quick manual validation in runZero with test credentials. +4. Commit with a clear message, for example: + - `Add Nexthink inbound custom integration with export workflow` +5. Open a PR including: + - Summary of mapping + - Validation notes/screenshots + - Any known limitations diff --git a/nexthink/config.json b/nexthink/config.json new file mode 100644 index 0000000..91ff07e --- /dev/null +++ b/nexthink/config.json @@ -0,0 +1,4 @@ +{ + "name": "Nexthink", + "type": "inbound" +} diff --git a/nexthink/custom-integration-nexthink.star b/nexthink/custom-integration-nexthink.star new file mode 100644 index 0000000..b12011b --- /dev/null +++ b/nexthink/custom-integration-nexthink.star @@ -0,0 +1,294 @@ +load('runzero.types', 'ImportAsset', 'NetworkInterface') +load('http', http_post='post', http_get='get') +load('json', json_encode='encode', json_decode='decode') +load('base64', base64_encode='encode') +load('net', 'ip_address') + +AUTH_URL = 'https://-login..nexthink.cloud' +API_URL = 'https://.api..nexthink.cloud' +QUERY_ID = '#runzero_integration' +SCOPE = 'service:integration' + +def _safe_str(value): + if value == None: + return "" + return str(value) + +def _normalize_ipv4_mapped_ip(ip_raw): + if not ip_raw: + return "" + ip_text = str(ip_raw) + if ip_text.startswith("::ffff:"): + return ip_text[7:] + return ip_text + +def _build_os_version(build_value): + if not build_value: + return "" + text = str(build_value).strip() + if text.startswith("[") and text.endswith("]"): + inner = text[1:-1] + parts = [p.strip() for p in inner.split(",")] + if len(parts) >= 2 and parts[0] and parts[1]: + return "{}.{}".format(parts[0], parts[1]) + return text + +def _encode_query_id(query_id): + qid = _safe_str(query_id) + if qid.startswith("#"): + return "%23{}".format(qid[1:]) + return qid + +def _body_to_text(body): + if type(body) == "string": + return body + return str(body) + +def _parse_ip_addrs(ip_raw): + ip4s = [] + ip6s = [] + parsed = None + if ip_raw: + parsed = ip_address(_normalize_ipv4_mapped_ip(ip_raw)) + if parsed and parsed.version == 4: + ip4s.append(parsed) + elif parsed and parsed.version == 6: + ip6s.append(parsed) + return ip4s, ip6s + +def _parse_csv_line(line): + fields = [] + current = "" + in_quotes = False + quote_escaped = False + + for i in range(len(line)): + ch = line[i] + + if quote_escaped: + quote_escaped = False + continue + + if in_quotes: + if ch == '"': + if i + 1 < len(line) and line[i + 1] == '"': + current += '"' + quote_escaped = True + else: + in_quotes = False + else: + current += ch + else: + if ch == '"': + in_quotes = True + elif ch == ',': + fields.append(current) + current = "" + else: + current += ch + + fields.append(current) + return fields + +def parse_csv_rows(csv_text): + lines = csv_text.replace("\r\n", "\n").replace("\r", "\n").split("\n") + if len(lines) == 0 or lines[0] == "": + return [] + + headers = _parse_csv_line(lines[0]) + rows = [] + + for line in lines[1:]: + if not line: + continue + values = _parse_csv_line(line) + row = {} + for idx in range(len(headers)): + key = headers[idx] + if idx < len(values): + row[key] = values[idx] + else: + row[key] = "" + rows.append(row) + + return rows + +def get_token(client_id, client_secret, base_url, scope=None): + token_url = "{}/oauth2/default/v1/token".format(base_url) + auth_str = "{}:{}".format(client_id, client_secret) + encoded_auth = base64_encode(auth_str) + + headers = { + "Authorization": "Basic {}".format(encoded_auth), + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "application/json", + } + + params = {"grant_type": "client_credentials"} + if scope: + params["scope"] = scope + + response = http_post(token_url, headers=headers, params=params) + if response.status_code != 200: + print("Failed to get Nexthink token. Status Code: {}".format(response.status_code)) + print("Failed to get Nexthink token. Response Body: {}".format(response.body)) + return None + + data = json_decode(response.body) + return data.get("access_token") + +def start_nql_export(token, api_url, query_id): + url = "{}/api/v1/nql/export?queryId={}".format(api_url, _encode_query_id(query_id)) + headers = { + "Authorization": "Bearer {}".format(token), + "Accept": "application/json", + } + + response = http_get(url, headers=headers) + if response.status_code == 200: + data = json_decode(response.body) + return data.get("exportId") + if response.status_code == 401: + return "__UNAUTHORIZED__" + + print("Failed to start NQL export. Status Code: {}".format(response.status_code)) + print("Failed to start NQL export. Response Body: {}".format(response.body)) + return None + +def get_export_status(token, api_url, export_id): + url = "{}/api/v1/nql/status/{}".format(api_url, export_id) + headers = { + "Authorization": "Bearer {}".format(token), + "Accept": "application/json", + } + + response = http_get(url, headers=headers) + if response.status_code == 200: + return json_decode(response.body) + if response.status_code == 401: + return {"__unauthorized__": True} + + print("Failed to get export status. Status Code: {}".format(response.status_code)) + print("Failed to get export status. Response Body: {}".format(response.body)) + return None + +def fetch_all_export_rows(token, api_url, query_id, client_id, client_secret, auth_url, scope): + export_id = start_nql_export(token, api_url, query_id) + if export_id == "__UNAUTHORIZED__": + token = get_token(client_id, client_secret, auth_url, scope=scope) + if not token: + return [] + export_id = start_nql_export(token, api_url, query_id) + if not export_id: + return [] + + status_data = None + for _ in range(0, 120): + status_data = get_export_status(token, api_url, export_id) + if not status_data: + return [] + + if status_data.get("__unauthorized__"): + token = get_token(client_id, client_secret, auth_url, scope=scope) + if not token: + return [] + status_data = get_export_status(token, api_url, export_id) + if not status_data or status_data.get("__unauthorized__"): + return [] + + status = _safe_str(status_data.get("status")).upper() + if status == "COMPLETED" or status == "COMPLETE": + break + if status == "FAILED" or status == "CANCELED" or status == "ERROR": + print("NQL export failed with status: {}".format(status)) + return [] + + if not status_data: + print("NQL export status was not available") + return [] + + final_status = _safe_str(status_data.get("status")).upper() + if final_status != "COMPLETED" and final_status != "COMPLETE": + print("NQL export did not complete in time. Last status: {}".format(final_status)) + return [] + + results_file_url = status_data.get("resultsFileUrl") + if not results_file_url: + print("NQL export completed but no resultsFileUrl was returned") + return [] + + # resultsFileUrl is pre-signed. Do not send Authorization headers. + download_response = http_get(results_file_url) + + if download_response.status_code == 406: + download_response = http_get(results_file_url, headers={"Accept": "text/csv"}) + + if download_response.status_code != 200: + print("Failed to download export results. Status Code: {}".format(download_response.status_code)) + print("Failed to download export results. Response Body: {}".format(download_response.body)) + return [] + + csv_text = _body_to_text(download_response.body) + return parse_csv_rows(csv_text) + +def main(**kwargs): + client_id = kwargs.get("access_key") + client_secret = kwargs.get("access_secret") + + if not client_id or not client_secret: + print("Missing credentials! Please configure access_key and access_secret in runZero.") + return [] + + token = get_token(client_id, client_secret, AUTH_URL, scope=SCOPE) + if not token: + return [] + + rows = fetch_all_export_rows(token, API_URL, QUERY_ID, client_id, client_secret, AUTH_URL, SCOPE) + if type(rows) != "list" or len(rows) == 0: + print("No rows returned from Nexthink export workflow") + return [] + + assets = [] + + for row in rows: + asset_id = row.get("device.uid") + if not asset_id: + continue + + hostname = _safe_str(row.get("device.name")) + os_name = _safe_str(row.get("device.operating_system.name")) + os_build_raw = row.get("device.operating_system.build") + os_version = _build_os_version(os_build_raw) + + manufacturer = _safe_str(row.get("device.hardware.manufacturer")) + model = _safe_str(row.get("device.hardware.model")) + serial = _safe_str(row.get("device.hardware.chassis_serial_number")) + first_seen = _safe_str(row.get("device.first_seen")) + last_seen = _safe_str(row.get("device.last_seen")) + + ip4s, ip6s = _parse_ip_addrs(row.get("device.collector.local_ip")) + + net_ifaces = [] + if ip4s or ip6s: + net_ifaces.append(NetworkInterface(ipv4Addresses=ip4s, ipv6Addresses=ip6s)) + + custom_attrs = { + "nexthink.first_seen": first_seen, + "nexthink.last_seen": last_seen, + "nexthink.hardware.manufacturer": manufacturer, + "nexthink.hardware.model": model, + "nexthink.hardware.chassis_serial_number": serial, + "nexthink.operating_system.build": _safe_str(os_build_raw), + "nexthink.collector.local_ip": _safe_str(row.get("device.collector.local_ip")), + } + + assets.append(ImportAsset( + id=str(asset_id), + hostnames=[hostname] if hostname else [], + os=os_name, + osVersion=os_version, + networkInterfaces=net_ifaces, + customAttributes=custom_attrs, + )) + + return assets From 175aed4603706641d1785f43693e7b16822dcc03 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 20 May 2026 20:50:28 +0000 Subject: [PATCH 2/3] Auto: update integrations JSON and README --- docs/integrations.json | 216 +++++++++++++++++++++-------------------- 1 file changed, 111 insertions(+), 105 deletions(-) diff --git a/docs/integrations.json b/docs/integrations.json index 4df7410..f744cf5 100644 --- a/docs/integrations.json +++ b/docs/integrations.json @@ -1,72 +1,78 @@ { - "lastUpdated": "2026-05-12T15:57:44.869693Z", - "totalIntegrations": 36, + "lastUpdated": "2026-05-20T20:50:28.564644Z", + "totalIntegrations": 37, "integrationDetails": [ { - "name": "Scan Passive Assets", - "type": "internal", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/scan-passive-assets/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/scan-passive-assets/custom-integration-scan-passive-assets.star" + "name": "Moysle", + "type": "inbound", + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/moysle/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/moysle/custom-integration-moysle.star" }, { - "name": "Tailscale", + "name": "Automox", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/tailscale/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/tailscale/custom-integration-tailscale.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/automox/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/automox/custom-integration-automox.star" }, { - "name": "Cisco-ISE", + "name": "Netskope", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cisco-ise/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cisco-ise/custom_integration_cisco-ise.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/netskope/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/netskope/custom-integration-netskope.star" }, { - "name": "Halycon", + "name": "Device42", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/halycon/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/halycon/custom-integration-halycon.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/device42/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/device42/custom-integration-device42.star" }, { - "name": "Stairwell", + "name": "Ghost Security", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/stairwell/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/stairwell/custom-integration-stairwell.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ghost/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ghost/custom-integration-ghost.star" }, { - "name": "Lima Charlie", + "name": "Cortex XDR", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/lima-charlie/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/lima-charlie/custom-integration-lima-charlie.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cortex-xdr/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cortex-xdr/custom-integration-cortex-xdr.star" }, { - "name": "Moysle", + "name": "Bitsight", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/moysle/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/moysle/custom-integration-moysle.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/bitsight/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/bitsight/custom-integration-bitsight.star" }, { - "name": "Snow License Manager", + "name": "Carbon Black", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/snow-license-manager/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/snow-license-manager/custom-integration-snow.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/carbon-black/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/carbon-black/custom-integration-carbon-black.star" }, { - "name": "Scale Computing", + "name": "Snipe-IT", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/scale-computing/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/scale-computing/custom-integration-scale-computing.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/snipe-it/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/snipe-it/snipeit.star" }, { - "name": "runZero Task Sync", + "name": "Vunerability Workflow", + "type": "internal", + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/vulnerability-workflow/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/vulnerability-workflow/custom-integration-vulnerability-workflow.star" + }, + { + "name": "Tanium", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/task-sync/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/task-sync/custom-integration-task-sync.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/tanium/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/tanium/custom-integration-tanium.star" }, { - "name": "Device42", + "name": "Digital Ocean", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/device42/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/device42/custom-integration-device42.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/digital-ocean/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/digital-ocean/custom-integration-digital-ocean.star" }, { "name": "Ubiquiti Unifi Network", @@ -75,34 +81,34 @@ "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ubiquiti-unifi-network/custom-integration-ubiquiti-unifi-network.star" }, { - "name": "Solarwinds Information Service", + "name": "JAMF", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/solarwinds-information-service/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/solarwinds-information-service/custom-integration-swis.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/jamf/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/jamf/custom-integration-jamf.star" }, { - "name": "Akamai Guardicore Centra", + "name": "Proxmox", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/akamai-guardicore-centra/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/akamai-guardicore-centra/custom-integration-centra-v3-api.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/proxmox/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/proxmox/custom-integration-proxmox.star" }, { - "name": "Vunerability Workflow", - "type": "internal", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/vulnerability-workflow/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/vulnerability-workflow/custom-integration-vulnerability-workflow.star" + "name": "Cyberint", + "type": "inbound", + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cyberint/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cyberint/custom-integration-cyberint.star" }, { - "name": "Snipe-IT", + "name": "Lima Charlie", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/snipe-it/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/snipe-it/snipeit.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/lima-charlie/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/lima-charlie/custom-integration-lima-charlie.star" }, { - "name": "Audit Log to Webhook", - "type": "outbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/audit-events-to-webhook/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/audit-events-to-webhook/custom-integration-audit-events.star" + "name": "Nexthink", + "type": "inbound", + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/nexthink/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/nexthink/custom-integration-nexthink.star" }, { "name": "Kandji", @@ -110,12 +116,6 @@ "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/kandji/README.md", "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/kandji/custom-integration-kandji.star" }, - { - "name": "Bitsight", - "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/bitsight/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/bitsight/custom-integration-bitsight.star" - }, { "name": "Ivanti Neurons", "type": "inbound", @@ -123,10 +123,16 @@ "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ivanti_neurons/custom-integration-neurons.star" }, { - "name": "Cortex XDR", + "name": "Scale Computing", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cortex-xdr/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cortex-xdr/custom-integration-cortex-xdr.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/scale-computing/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/scale-computing/custom-integration-scale-computing.star" + }, + { + "name": "Extreme Networks CloudIQ", + "type": "inbound", + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/extreme-cloud-iq/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/extreme-cloud-iq/custom-integrations-extreme-cloud-iq.star" }, { "name": "Drata", @@ -135,34 +141,34 @@ "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/drata/custom-integration-drata.star" }, { - "name": "JAMF", + "name": "Snow License Manager", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/jamf/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/jamf/custom-integration-jamf.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/snow-license-manager/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/snow-license-manager/custom-integration-snow.star" }, { - "name": "Sumo Logic", - "type": "outbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/sumo-logic/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/sumo-logic/custom-integration-sumo.star" + "name": "Stairwell", + "type": "inbound", + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/stairwell/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/stairwell/custom-integration-stairwell.star" }, { - "name": "Tanium", + "name": "Akamai Guardicore Centra", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/tanium/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/tanium/custom-integration-tanium.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/akamai-guardicore-centra/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/akamai-guardicore-centra/custom-integration-centra-v4-api.star" }, { - "name": "Cyberint", + "name": "Solarwinds Information Service", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cyberint/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cyberint/custom-integration-cyberint.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/solarwinds-information-service/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/solarwinds-information-service/custom-integration-swis.star" }, { - "name": "Digital Ocean", - "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/digital-ocean/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/digital-ocean/custom-integration-digital-ocean.star" + "name": "Scan Passive Assets", + "type": "internal", + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/scan-passive-assets/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/scan-passive-assets/custom-integration-scan-passive-assets.star" }, { "name": "pfSense", @@ -171,52 +177,52 @@ "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/pfsense/custom-integration-pfsense.star" }, { - "name": "Automox", + "name": "Cisco-ISE", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/automox/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/automox/custom-integration-automox.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cisco-ise/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/cisco-ise/custom_integration_cisco-ise.star" }, { - "name": "Extreme Networks CloudIQ", - "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/extreme-cloud-iq/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/extreme-cloud-iq/custom-integrations-extreme-cloud-iq.star" + "name": "Sumo Logic", + "type": "outbound", + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/sumo-logic/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/sumo-logic/custom-integration-sumo.star" }, { - "name": "Netskope", + "name": "Manage Engine Endpoint Central", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/netskope/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/netskope/custom-integration-netskope.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/manage-engine-endpoint-central/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/manage-engine-endpoint-central/custom-integration-endpoint-central.star" }, { - "name": "NinjaOne", + "name": "Tailscale", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ninjaone/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ninjaone/custom-integration-ninjaone.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/tailscale/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/tailscale/custom-integration-tailscale.star" }, { - "name": "Ghost Security", - "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ghost/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ghost/custom-integration-ghost.star" + "name": "Audit Log to Webhook", + "type": "outbound", + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/audit-events-to-webhook/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/audit-events-to-webhook/custom-integration-audit-events.star" }, { - "name": "Manage Engine Endpoint Central", + "name": "Halycon", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/manage-engine-endpoint-central/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/manage-engine-endpoint-central/custom-integration-endpoint-central.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/halycon/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/halycon/custom-integration-halycon.star" }, { - "name": "Carbon Black", + "name": "runZero Task Sync", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/carbon-black/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/carbon-black/custom-integration-carbon-black.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/task-sync/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/task-sync/custom-integration-task-sync.star" }, { - "name": "Proxmox", + "name": "NinjaOne", "type": "inbound", - "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/proxmox/README.md", - "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/proxmox/custom-integration-proxmox.star" + "readme": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ninjaone/README.md", + "integration": "https://github.com/runZeroInc/runzero-custom-integrations/blob/main/ninjaone/custom-integration-ninjaone.star" } ] } \ No newline at end of file From cb44dd3cfcec3b4b3ca59021fdee17a1c1b4d2af Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 21 May 2026 17:58:30 +0000 Subject: [PATCH 3/3] Auto: update integrations JSON and README --- docs/integrations.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/integrations.json b/docs/integrations.json index 3aea251..64d1dc4 100644 --- a/docs/integrations.json +++ b/docs/integrations.json @@ -1,5 +1,5 @@ { - "lastUpdated": "2026-05-21T17:56:31.364697Z", + "lastUpdated": "2026-05-21T17:58:30.540507Z", "totalIntegrations": 37, "integrationDetails": [ {