Connectors

Connectors — what each one needs

One page per question an operator actually has before connecting a source: what to grant on the source side, which product variant is supported, whether the connector reaches your internal network, and what a specific failure is telling you.

Why this page exists It did not until 2026-08-18. The documentation index had 16 sections and none about connectors, while the product ships 16 connectors — so the only way to find the required permissions was to read our source code, which is what the first pilot client did, at the cost of about an hour (their D-25). The same facts are served by GET /connectors/catalog, so the form, this page and the API cannot drift apart.

First: can the connector reach the source?

Cerynix blocks outbound requests to non-public addresses by default. That default is right for a multi-tenant service and was wrong as the only option for on-prem, where the integration targets are supposed to be on your network. Set the ranges you integrate with:

.env — then restart the api
CONNECTOR_ALLOWED_CIDRS=10.20.0.0/16,192.168.213.0/24

Without it, a connector pointed at an internal address fails with destination resolves to a non-public address. Scope it to what you actually integrate with rather than 0.0.0.0/0. It applies to connectors only — webhooks and OIDC discovery keep the strict public-only policy — and loopback, link-local (including the 169.254.169.254 metadata endpoint), unspecified and multicast stay blocked whatever you list. Each permitted internal destination is recorded on the connector run (summary.internal_egress_allowed), so the exception is auditable rather than invisible.

All connectors at a glance

ConnectorReachesGrant on the sourceImports
entra_id — Microsoft Entra IDMicrosoft cloudUser.Read.All, Device.Read.All, AuditLog.Read.AllDevices as assets; identity + MFA posture
intune — Microsoft IntuneMicrosoft cloudDeviceManagementManagedDevices.Read.AllManaged devices as assets
defender — Microsoft DefenderMicrosoft cloudSecurityEvents.Read.All, SecurityAlert.Read.AllAlerts as findings; secure score
fortigateyour networkRead-only REST API admin + API tokenDevice posture as findings
fortianalyzeryour networkJSON-RPC user with read accessLog-derived findings
forticlient_emsyour networkRead-only API accountEndpoints as assets
zabbixyour networkAPI user with read accessHosts as assets; problems as findings
splunkyour networkSearch-capable tokenSearch results as findings
vmware — vCenteryour networkRead-only vCenter accountVMs as assets
jiracloud or your networkCloud: email + API token · Server/DC: username + passwordIssues as findings
tenable — Tenable / Qualyscloud or your networkAccess key + secret key (read)Vulnerabilities as findings
action1cloudAPI client (read)Patch status as findings
trend_vision_onecloud or your networkAPI key with read scopeDetections as findings
http_json — Generic HTTP/JSONyour network (usually)Read access to the endpoint you configureWhatever you map
csv_asset_import / json_asset_importnothing — file upload—Assets

Every connector marked your network needs CONNECTOR_ALLOWED_CIDRS. The three Microsoft ones talk to fixed cloud hosts and work with no egress configuration at all.

Microsoft Entra ID

App-only (client credentials) against Microsoft Graph. Register an application, grant the three application permissions below, and grant admin consent — delegated permissions will not work for an unattended sync.

PermissionUsed forWithout it
User.Read.AllDirectory users, enabled/guest classificationSync fails
Device.Read.AllDevice inventory imported as assetsSync fails
AuditLog.Read.AllMFA registration reportSync succeeds; MFA coverage is omitted with mfa_note explaining why

Configuration: tenant_id — your tenant's domain (contoso.onmicrosoft.com) or its directory GUID; client_id — the application (client) id; secret — a client secret. A frequent mistake is pasting the client id into the tenant field, which Azure answers with AADSTS90002: Tenant not found.

Press "Test connection" first It performs one $top=1 read against each resource the sync uses and reports them individually, so a missing permission is named before you run a full sync. Until 1.0.2 it only read /organization — which needs none of these scopes — so it could return a green tick and the sync would then fail with 403.

What the numbers mean. MFA coverage is measured over enabled member accounts matched to the registration report by directory id; disabled accounts and guests are excluded, and accounts the report does not cover are reported separately as mfa_users_not_in_report rather than being absorbed into the percentage. Devices are identified by their directory object id, so two machines sharing a hostname stay two assets and a renamed machine stays one.

People, service accounts and exceptions. Open MFA coverage and accounts on the connector card. Each account has a type — person, service, shared or directory sync — suggested from its name and licence (the reason is shown, for example name starts with svc-) and editable; a type you set is kept across syncs. Coverage is shown for people and for all accounts, both computed from the same list, so the card and the percentage never describe different populations. A gap you accept can be recorded as an exception with a rationale, an owner and a review date; after that date it shows as expired and the account needs action again. Select uncovered people and Create tasks in one step (owner and due date required; tasks point at ISO/IEC 27001 A.8.5 and A.5.17). Attach snapshot as evidence freezes today's coverage as a system-generated file (SHA-256 recorded) on A.8.5 and A.5.17; it starts as a draft and goes through normal evidence review.

Assets that disappear. Every sync records when each device was first and last reported. A device its source has not reported for 14 days (change it with Edit settings → Mark assets stale after) is marked stale, and each run summary says how many assets were seen, new, newly stale and back from stale. A source that returns nothing at all is never treated as "everything vanished".

Intune & Defender

Same app-registration pattern as Entra ID, different application permissions: DeviceManagementManagedDevices.Read.All for Intune; SecurityEvents.Read.All and SecurityAlert.Read.All for Defender. Admin consent is required for both. They can share one app registration or use separate ones — separate is easier to revoke.

FortiGate, FortiAnalyzer, FortiClient EMS

All three live on your network, so start with CONNECTOR_ALLOWED_CIDRS.

  • FortiGate: create a REST API administrator with a read-only profile and generate its API token. Restrict the admin's trusted hosts to the Cerynix server's address — the token is bearer credentials.
  • FortiAnalyzer: a JSON-RPC user with read access. Its JSON-RPC surface differs between firmware versions; if a sync fails on an otherwise valid account, send us the firmware version and the raw response (redacted) — that is the fastest path to a fix, and we would rather hear it than have you work around it.
  • FortiClient EMS: a read-only API account.

Zabbix & Splunk

  • Zabbix: an API user with read permission on the host groups you want imported. Point base_url at the frontend (https://zbx.example.internal); the connector posts to /api_jsonrpc.php.
  • Splunk: a token whose role may run searches. Point base_url at the management interface (commonly :8089), not the web UI port.

Certificate signed by your own CA (a corporate CA, or Splunk's default self-signed chain). TLS verification stays on; you add the CA so Cerynix trusts it. Put the CA certificate (PEM, one or more .crt / .pem files) in ./certs/ca/ in the install directory:

on the Cerynix host
cp corporate-root-ca.crt /opt/cerynix/certs/ca/
chmod 644 /opt/cerynix/certs/ca/*.crt

The directory is mounted read-only into the API and the worker, is created by the installer and is never touched by ./install.sh --update, so it survives updates. It is read on every connection, so there is nothing to restart; run Test connection again. The CAs are added to the public ones — a server certificate that none of them signed is still rejected. Add the root (and any intermediate) the server's chain ends in; a failed test names the verification reason, for example self-signed certificate in certificate chain. This applies to every connector, not only Splunk.

VMware vCenter

A read-only vCenter account (the built-in Read-only role is enough for VM inventory). Point base_url at the vCenter appliance. If its certificate is internally issued, the connector still validates TLS — install your CA in the trust store rather than disabling verification.

Jira — Cloud and Server / Data Center

Jira CloudJira Server / Data Center
Account fieldemailusername
SecretAPI tokenAccount password
REST version3 (auto)2 (auto)
ReachesAtlassian cloudyour network

Set email or username. REST API version is Auto-detect by default: Cerynix starts with the version that fits the credential and, when the instance answers 404 (Server has no /rest/api/3 at all), retries with the other one and remembers which worked, so a Server instance configured with the Cloud-shaped email field still connects, over v2. Choose 2 or 3 in the form (api_version) to pin it. The fields read from each issue (summary, priority, status) are plain strings in both versions. Optional jql selects which issues become findings; the default is statusCategory != Done ORDER BY created DESC.

Tenable / Qualys, Action1, Trend Vision One

Connection settings can be changed later with Edit settings on the card. Changing where a connector connects (URL, base URL or tenant) asks for the credential again, so the stored one is never sent to a new address; every change is audited with before and after values.

  • Tenable / Qualys: an access key and secret key with read scope. The hosted service needs no egress configuration; Tenable.sc / Qualys on-prem does.
  • Action1: a read-only API client. Set the API base URL for your region (EU tenants: https://app.eu.action1.com/api/3.0) and the Organization ID (Action1 → Settings → Organization ID). Action1 lists endpoints per organization; the unscoped list answers 403. If you leave the Organization ID empty and the credentials can see exactly one organization, Cerynix uses it; otherwise the test fails with organization id is required. Test connection reads the first page of that organization's endpoints, so a wrong id shows up there and not at the first sync. Cloud only.
  • Trend Vision One: an API key with read scope, from the region your tenant lives in — a key from another region authenticates against nothing. Choose the matching regional API host in the form (for example api.eu.xdr.trendmicro.com). Use the API address, not the console/portal address (portal.….xdr.trendmicro.com): the portal answers with an HTML page, and the failure message then shows the HTTP status, content type and the first bytes of that page. Each sync reads all pages of Workbench alerts since the last successful run (first run: the last 30 days) and creates one finding per alert, with the host, detection model, severity, time and a Workbench link. A host named in an alert also marks the asset with the same host name as EDR active (exact, case-insensitive match on the asset's host name, name or FQDN; pc01 does not match pc01.corp.example). Large histories: alerts are read oldest first, up to max_pages pages (default 50) of page_size alerts (default 200) per run. If a run stops at that limit its log says History is not complete yet with the time it reached and how many more runs to expect; the next run continues from there rather than starting over, so repeated runs finish the history. If Trend returns smaller pages than requested, the page limit is scaled so a run still covers the same number of alerts.

Generic HTTP/JSON and file import

Generic HTTP/JSON reads any endpoint returning a JSON array of objects and maps fields onto assets. It is the fastest way to bring in a source we do not support natively — and if you build one, tell us what you mapped; that is how a native connector gets prioritised.

CSV / JSON import touch no network at all: you upload the file. Best first step if you want the inventory populated before wiring any credentials.

Reading a failure

MessageWhat it meansDo
destination resolves to a non-public addressThe target is on your network and internal egress is not enabledSet CONNECTOR_ALLOWED_CIDRS
AADSTS90002: Tenant … not foundThe tenant field does not hold a tenant — most often a client id pasted one field upUse the tenant domain or directory GUID
Authorization_RequestDenied / HTTP 403The credential is valid; a permission is missingRun Test connection — it names the resource that failed
HTTP 404 on a Jira sync with a pinned versionREST v3 pinned against Jira Server (or v2 against Cloud)Set REST API version to Auto-detect
connect timeout after 20s connecting to host:443, resolved to 10.x.x.xThe address was resolved and allowed but nothing answered — usually a firewall dropping traffic from the Cerynix host, or a wrong portFrom the Cerynix host: curl -vk https://host:443/; open the firewall for the Cerynix server's address
connection refused by host:portThe host answered, nothing listens on that portCheck the port (Splunk management is :8089)
DNS resolution failed: cannot resolve host nameThe Cerynix containers cannot resolve the nameCheck the name; use the DNS server of the host or an IP address
TLS error: certificate verification failed … (self-signed certificate in certificate chain)The server's certificate was issued by a CA Cerynix does not trustAdd your CA to ./certs/ca/
read timeout after 20sConnected, but the server did not answer in timeCheck the load on the source; try a narrower query
organization id is required (Action1)Action1 inventory is organization-scopedFill in Organization ID
mfa_note in the run summaryThe MFA report was unavailable; the rest of the sync succeededGrant AuditLog.Read.All

Connector errors carry the provider's own error code, description and trace id where the provider returns one — up to 1.0.1 we discarded them and reported only the HTTP status, which cost the first pilot client an hour on a wrong tenant id that Azure had named in the response body (their D-23).

Each connector card shows one current state — the newest of Test connection and Run sync. An older failure of the other kind is kept under Earlier failure, collapsed and dated, so it can never sit above a newer result. A failure without an HTTP answer names the phase (DNS, connect, TLS, read), the host:port, the address it resolved to and the timeout in force, so the message tells a firewall drop from a wrong name or a certificate problem.

Still stuck? Send the run's log and summary (Integrations → the connector → the run) to support@cerynix.com. Redact what you must — the message text and status code are usually enough.