Skip to main content

Cato Networks

Pull

Synopsis​

Director reads Cato Networks' GraphQL API with an API key. Each thing it reads is a dataset assigned to the device, seven of them — see Cato Networks Datasets:

  • Logs: the events feed (security, connectivity, and system events), the audit feed (what administrators changed), and the XDR stories (Cato XDR's incidents).
  • Metrics: the site metrics (each site's and link's traffic, loss, jitter, and round trip) and the application usage (traffic and flows by application, or by what the dataset groups by).
  • Inventories: the sites and their Sockets, and the remote users connected at the poll.

The device is built on the Codeless Connector Framework (CCF) poller, which can already read Cato from connector JSON an operator pastes into a ccf device. The difference is who writes the connectors. A Cato Networks device never shows one: the device holds the API's address and key, each dataset what it reads and how, and the platform writes the connectors and sends them to the Director with its configuration.

A ccf device configured for Cato keeps working as it is. The two share no checkpoints, so moving from one to the other starts every feed afresh.

note

The Cato Networks device needs Director 2.3.1 or later. With no Director or cluster at that version selected, the wizard shows Cato Networks devices are unavailable on directors or clusters below version 2.3.1 and the device cannot be created.

Before It Collects​

In the Cato Management Application:

  1. Create an API key with view permission under Administration > API & Integrations > API Keys.
  2. Turn on Administration > API & Integrations > Events Integration > Enable integration with Cato events. Cato says to allow about 30 minutes before the events feed has anything to return. With it off, the feed answers with a null feed and its dataset reports an error.

The account IDs the datasets name are under Administration > Account > General Info. The XDR stories need Cato XDR on the account; without it, the dataset reads none.

Schema​

- id: <numeric>
name: <string>
description: <string>
type: cato_networks
tags: <string[]>
pipelines: <pipeline[]>
status: <boolean>
properties:
api_url: <string>
api_key: <string>
ccf_config: <string>
tls:
insecure_skip_verify: <boolean>

Configuration​

The following fields are used to define the device:

Device​

FieldRequiredDefaultDescription
idY-Unique numeric identifier
nameY-Device name
descriptionN-Optional description
typeY-Must be cato_networks
tagsN-Optional tags
pipelinesN-Optional pre-processor pipelines
statusNtrueEnable/disable the device

Connection​

FieldRequiredDefaultDescription
api_urlY-Cato's API host for the account's region: https://api.catonetworks.com/api/v1/graphql2 (the default region), https://api.us1.catonetworks.com/api/v1/graphql2 (US1), or https://api.in1.catonetworks.com/api/v1/graphql2 (India)
api_keyY-The API key, sent as x-api-key. A secret: withheld when the device is read back, and ${ENV_VAR} and $secret{...} references are resolved on the Director.
tls.insecure_skip_verifyNfalsetrue accepts the API's certificate without verifying it
ccf_configN-Written by the platform. Set it by hand only on a Director run from a configuration file (see A Director with a Configuration File).

Datasets​

What the device reads is decided by the datasets and profiles assigned to it. For the dataset types, their properties, and how each is read, see Cato Networks Datasets.

A device with no dataset assigned polls nothing and says so in its connection state.

Rate Limits​

Read each account from one device. Cato limits how often each query may be called a minute, counted per query and per account: every API key that reads the account shares the count, whoever holds it.

QueryCato's limit a minuteDatasets
eventsFeed100Events
auditFeed5Audit
accountMetrics15Site metrics
accountSnapshot30Sites, connected users
Every other query120XDR stories, application usage

The device's defaults stay under each limit. Anything else that reads the same account — another device, a SIEM's own connector, a script — shares the budget and can push the device over it, which shows as HTTP 429 responses and an audit feed that falls behind.

How It Runs​

  • The platform writes the connectors. When it builds a Director's configuration, the platform gives the device one connector per dataset assigned to it, or one per account for a dataset read per account (see Read Per Account). The API key never enters what the platform builds: the Director fills it in from the device.
  • A connector that cannot run is left out. A dataset with no account, or with a setting the Director cannot read, is left out with a warning in the Director's log, and the others run.
  • Changes restart the collector. Editing a dataset, or assigning or removing one, restarts the device's collector with the new connectors. Each connector resumes from its checkpoint.
  • Checkpoints are per device, dataset, and connector, kept in the Director cluster's replicated store. A dataset assigned in place of another starts from its own first poll.

A Director with a Configuration File​

A Director run from a configuration file has no platform to write the connectors. Write the ccf_config the platform would send under the device's properties, one connector per dataset, each with a dataset block beside its properties giving the definition id its records carry, its interval, and its own account_ids. See Examples.

Records​

Each record is written to the custom log table with its dataset's definition id, as Cato returns it. A pipeline normalizes it. For each dataset's record shape, see Cato Networks Datasets.

Troubleshooting​

What you seeWhy
Connected, "No dataset is assigned"Assign a dataset to the device.
dataset N (connector "CatoAuditFeed") is left out: ... unresolved placeholders: account_ids|listThe dataset names no account. A dataset read per account says account_id.
The XDR stories dataset writes nothingThe account has no Cato XDR, or no story changed in the window.
Application usage writes far more than expectedIts Group by dimensions multiply the rows: drop src_site_name or user_name.
dataset N ... reads what dataset M already reads; it is left outTwo datasets of one type reached the device. Remove one.
A dataset read per account has no connector on the Director's device pageThe Director is older than 2.3.1. The platform's log says a dataset is left out of its device's configuration. Upgrade the Director.
names the pipeline P, which was not shipped to this directorThe dataset's pipeline did not reach the Director; the device's pipeline takes the records.
The events feed reports an error with HTTP 200Events Integration is off in Cato (see Before It Collects), or the key cannot read an account (errorString).
HTTP 429, or the audit feed falls behindSomething else reads the same account, with whatever key: another device, a tool, a script. Read each account from one device.

Console​

In the console, go to Fleet Management > Devices > Cato Networks and click Add new device. The wizard's steps are:

  1. General settings, as on every device.
  2. Connection settings: API URL and API key; under TLS Settings, whether to skip certificate verification.
  3. The datasets or profile the device reads. A device receives datasets or a profile, never both.
  4. Review and create.

Examples​

Events Feed from a Configuration File​

A Director with no platform reading two accounts' events feed every minute: the ccf_config is the connector the platform would send, with its dataset block, and {{api_url}} and {{api_key}} are filled in from the device...

devices:
- id: 471203887
name: cato-networks
type: cato_networks
status: true
properties:
api_url: "https://api.catonetworks.com/api/v1/graphql2"
api_key: "${CATO_API_KEY}"
ccf_config: |
[
{
"name": "CatoEventsFeed",
"kind": "RestApiPoller",
"dataset": {
"definitionId": 29100,
"interval": 60,
"placeholders": { "account_ids": "1234, 5678" }
},
"properties": {
"auth": {
"type": "APIKey",
"ApiKey": "{{api_key}}",
"ApiKeyName": "x-api-key",
"ApiKeyIdentifier": ""
},
"request": {
"apiEndpoint": "{{api_url}}",
"httpMethod": "POST",
"isPostPayloadJson": true,
"headers": { "Accept": "application/json" },
"queryParametersTemplate": {
"query": "query EventsFeed($accountIDs: [ID!] $marker: String) { eventsFeed(accountIDs: $accountIDs marker: $marker) { fetchedCount marker accounts { errorString records { fieldsMap } } } }",
"variables": { "accountIDs": ["{{account_ids|list}}"] }
},
"rateLimitQPS": 1.5,
"retryCount": 3,
"timeoutInSeconds": 60
},
"response": {
"format": "json",
"eventsJsonPaths": ["$.data.eventsFeed.accounts[*].records[*].fieldsMap"],
"requiredJsonPaths": ["$.data.eventsFeed"],
"errorJsonPaths": ["$.errors", "$.data.eventsFeed.accounts[*].errorString"]
},
"paging": {
"pagingType": "PersistentToken",
"nextPageParaName": "$.variables.marker",
"nextPageTokenJsonPath": "$.data.eventsFeed.marker",
"hasNextFlagJsonPath": "$.data.eventsFeed.fetchedCount",
"hasNextFlagOperator": "GreaterThanOrEqual",
"hasNextFlagValue": 3000
}
}
}
]