Skip to main content

Connector configuration

The connector reads /etc/vesper/connector.yaml. The installer writes a working default. Most installs never need to touch it.

The default configuration​

# Vesper Connector configuration.
# Targets default to localhost. The connector runs on the Wazuh node.
# Credentials are LEFT BLANK on purpose: the connector auto-discovers them from
# the local Wazuh install. Indexer creds come from the filebeat keystore, and
# Wazuh API creds from the dashboard config or .kibana. Set them here only to
# override.
# Nothing read here ever leaves this machine.
connect_url: "wss://connect.vesper.wazuh.com"
indexer:
url: "https://localhost:9200"
insecure_skip_verify: true
wazuh_api:
url: "https://localhost:55000"
insecure_skip_verify: true
exec:
enabled: false
upgrade:
enabled: true
download_host: "dl.vesper.wazuh.com"
heartbeat_seconds: 30
request_timeout_seconds: 30

Every key it accepts is listed in the key reference at the foot of this page. A key the file leaves out falls back to its default, so a short file is not an incomplete one.

Credentials: auto-discovered, never uploaded​

The indexer and Wazuh API credential fields are intentionally blank. On start, the connector discovers them from the local Wazuh install itself. Set explicit values only to override discovery, for example when the indexer is not local to this node.

Whatever the source, credentials are used on the box to call localhost services and are never sent to Vesper. They live in this file, on your machine, and nowhere else. Vesper stores no password for your Wazuh: if you ever need to change one, you change it here and restart the connector, and there is nothing to update on our side.

Where it looks, per Wazuh major​

Wazuh 5.0 moved both stores, so the connector reads different places depending on what it finds installed. It detects the major from the host itself, not from the API, so it still knows which to look for when no credential works yet.

Wazuh 4.xWazuh 5.x
Wazuh APIthe dashboard's wazuh.yml, then the .kibana indexwazuh_core.hosts in /etc/wazuh-dashboard/opensearch_dashboards.yml
Indexerthe filebeat keystoreno automatic source, as described below

On Wazuh 5.x there is no filebeat, so there is no keystore to read and the indexer credential has to be set by hand. The connector says so at startup rather than reporting a failure, because on 5.x the missing keystore is the expected state and not a fault:

indexer creds: none discovered (Wazuh 5 has no filebeat keystore) — set
indexer.username/password in the config to enable indexer reads

Set it like any other override, and restart the connector:

indexer:
url: "https://localhost:9200"
insecure_skip_verify: true
username: "admin"
password: "…"

Until it is set the indexer refuses every read with 401 Unauthorized, and both majors behave the same way once the credential is there. Only the indexer tools are affected: the alert searches and the index health read report that credential as the reason and the console repeats it beside the indexer row, while everything that goes through the Wazuh API keeps working. The agent is told as much, so it does not read a refused indexer as a broken estate.

When nothing is discovered: "Invalid credentials" on every read​

If the connector shows as online and every read still comes back 401 Unauthorized: Invalid credentials, this is why, and it is the one failure that looks like a broken connector when the connector is fine.

Discovery needs the credential to be written down somewhere on this host, which means it needs the dashboard installed here. On a manager-only node, or when the manager is remote, nothing local knows the API password and the connector cannot invent one. Since v1.16.1 the installer detects this case and asks for the credential on the terminal, see distributed nodes. A connector installed before that, or installed without a terminal, logs a single line at startup naming the file to edit:

wazuh api creds: none discovered — set wazuh_api.username/password in
/etc/vesper/connector.yaml (nothing on this host advertises them)

Set the two fields, restart the connector, and the reads start working:

wazuh_api:
url: "https://localhost:55000"
insecure_skip_verify: true
username: "wazuh-wui"
password: "…"

Until then the console shows the detected Wazuh version next to the connector's status, with a note pointing at this file. Reads answer 401 Invalid credentials and nothing is changed on the host.

Setting them by hand​

Both targets take the same two fields. The indexer's are the ones a Wazuh 5.x host has to fill in, for the reason above:

indexer:
url: "https://localhost:9200"
insecure_skip_verify: true
username: "admin"
password: "…"

Set both fields, or neither. The connector decides whether to discover a target by looking at its username alone. A username with the password left blank therefore switches discovery off and authenticates with no password, so every read fails. Half-filling one target is worse than leaving it alone.

The installer writes this file 0640 and owned by root, so a password put here is not readable by other accounts on the host. It still goes no further than the host: the connector uses it to call localhost and returns only the response.

A node installed through Wazuh Fleet has no such file. Its Wazuh login is typed in Vesper instead, from the Set Wazuh credentials button on that host's node. Vesper sends it to the node and does not store it. The node keeps it only while it stays in that environment: a host that leaves one and is added again asks for the login again. The indexer login and the Wazuh API login are each optional, and a host may have neither. See the install guide's Wazuh Fleet section for that path.

Pointing discovery somewhere else​

Three keys move where discovery looks, for an install that keeps these files outside their usual place. Leave a key blank to read the default on the right.

KeyDefault it replaces
indexer.keystore_path/var/lib/filebeat/filebeat.keystore
dashboard_config/usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml
dashboard_opensearch_yml/etc/wazuh-dashboard/opensearch_dashboards.yml

The last two are separate keys rather than one overridable path because the 4.x and 5.x files have different shapes. Moving where one is read from must not quietly redirect the reader for the other.

What the connector discovers about its node​

Besides credentials, the connector reads what kind of Wazuh node its host is, from the configuration files already on the disk and without any credential. It re-reads them on every heartbeat, so a worker promoted to master or a component added to a host is reflected in the console without a restart.

Node kindWhat the host runsWhat is read
aiomanager, indexer and dashboard togethereverything below
manager-mastera manager whose cluster block is enabled with type masterthe cluster block of the manager configuration: cluster name, node name and node type
manager-workera manager whose cluster block is enabled with type workerthe same block
managera manager with the cluster disabled or with no cluster blockthe same block, when present
indexeran indexer nodecluster.name and node.name from the indexer configuration
dashboarda dashboard nodewhich indexer hosts and which Wazuh API hosts the dashboard points at, addresses only
agentonly a Wazuh agentnothing beyond the agent being installed
barenothing is installed on the host yetnothing
mixedany other combination, such as indexer and dashboard on one hostthe blocks of the components present
unknowna connector from before agent and bare existed, which cannot tell them apartnothing

The kind cannot be set by hand, in this file or in the console. What the connector finds is what is reported. An agent co-installed on a server node does not change that node's kind: the agent only decides the kind when it is alone. A host where nothing is installed yet reports bare, and the agent is told not to look for a layout there. A node that reports unknown gets the same caution: the agent does not assume any layout for it.

On a manager node the connector also reports the cluster membership as Wazuh lists it: every manager node with its name, type, version and address. It reads it through the Wazuh API when a credential is available, and from the manager's own cluster_control -l when none is, on both majors, so the list is reported even while the API credential is what is broken. On an indexer node it reports the indexer nodes from _cat/nodes. Membership is collected every five minutes rather than on every heartbeat. Only names, types, versions and addresses are sent. No credential and no cluster key ever leaves the host.

The heartbeat also tells apart a target that is unreachable from one that is not on this node. A worker has no indexer and an indexer node has no Wazuh API, so on those hosts the connector does not probe localhost for the missing component and reports it as absent rather than as down. A target whose url in this file points at another host is always probed, whatever is installed locally.

exec: the fix capability​

exec.enabled, false by default, lets the agent run shell commands on the host, which is what turns a diagnosis into a fix. It is the only switch that lets the agent change anything on the host. With it off, the agent reads and diagnoses in every mode, including Auto, and changes nothing. It is arbitrary remote execution by design, so it is off unless the connector was installed with --enable-exec. On a Wazuh Fleet node it is turned on as shell commands on a Wazuh Fleet node describes. Even then every command is:

  • gated by Vesper on whether an admin started the conversation,
  • gated by the environment's mode ceiling, which is Read only, Manual or Auto,
  • subject to human approval in Manual mode, and in every mode when it deletes Wazuh data, keys or packages,
  • screened by a catastrophic-command denylist inside Vesper, which the host enforces again here as a last resort.

Read commands are the exception to the second rule. A command Vesper classifies as read-only runs immediately in every mode, including Read only. A network read such as curl, ping or dig counts as read-only only toward a local or private address. See the agent's modes for exactly which commands qualify.

Enabling exec also installs a systemd drop-in at /etc/systemd/system/vesper-connector.service.d/exec.conf that strips most of the unit's hardening, including the read-only filesystem, because a fix that edits /var/ossec or restarts a service cannot work under it. Delete that drop-in and set exec.enabled: false to return the connector to its hardened, read-only state. Install the connector lists exactly which protections the drop-in removes and which survive.

What the agent may read on this node without a shell​

The connector answers five read requests from the agent that need no shell and no approval: read a file, read the end of a log, list a directory, report a service's state with the last lines of its journal, and run a component's own configuration check. They work with exec.enabled set to false, so a conversation started with Look into it can read the configuration file that a broken manager's API cannot parse for it.

What can be read is fixed in the connector binary. It is not a setting in this file and it cannot be widened from the console or by Vesper. Only the directories of the Wazuh components are readable, and the secret files inside them are refused by name.

ComponentReadable directories
Manager 4.x/var/ossec/etc/, its rules/, decoders/ and shared/, /var/ossec/logs/, /var/ossec/ruleset/, /var/ossec/integrations/
Manager 5.x/var/wazuh-manager/etc/, /var/wazuh-manager/logs/
Agent/var/ossec/etc/, /var/ossec/logs/
Indexer/etc/wazuh-indexer/ and its certs/, /var/log/wazuh-indexer/
Dashboard/etc/wazuh-dashboard/ and its certs/, /usr/share/wazuh-dashboard/data/wazuh/config/, /var/log/wazuh-dashboard/
Filebeat/etc/filebeat/ and its certs/, /var/log/filebeat/

Nothing outside those directories can be reached. A manager's queue/, var/, stats/ and bin/ are outside them. A symbolic link is followed before the check, so a link inside a readable directory that points outside it is refused too.

These files are never read, wherever they sit: client.keys, sslmanager.key, authd.pass, the API's security/ configuration directory, private keys named *-key.pem or *.key, and any *.keystore, *.p12 or *.jks file.

Secrets inside a readable file are removed on the host before anything leaves it. In ossec.conf and the other Wazuh XML files, the cluster key, every password, API keys and hook URLs are replaced with [redacted]. In the YAML files, the value of any key named after a password, passphrase, key or secret is replaced the same way. Every read, logs included, also has credential-shaped values such as password=, token:, bearer tokens and PEM blocks replaced. The marker stays in place so the reader knows a value was there.

The service state and configuration checks accept only the five Wazuh units: wazuh-manager, wazuh-indexer, wazuh-dashboard, filebeat and wazuh-agent. The state check runs systemctl show and reads the journal. It never starts, stops or restarts a service. The configuration check runs the component's own validator, such as wazuh-analysisd -t and wazuh-remoted -t on a manager or filebeat test config and filebeat test output for Filebeat, and parses the XML or YAML configuration file to name the malformed line.

A connector older than these reads answers that it does not support them. The agent says so in the conversation and continues with the tools it has. Upgrading the connector enables them.

upgrade: the host's veto over a new binary​

upgrade.enabled, true by default, decides whether this host accepts a new binary from Vesper at all. It is not the same decision as the console's, and the two are allowed to disagree. The console decides whether Vesper asks, by an admin pressing Upgrade now or by the environment's auto upgrade toggle. This key decides whether the host says yes, and it is the one that wins: set it to false and the connector logs and ignores every directive, whatever anybody presses.

That is deliberate. The person who owns the machine and the person who owns the Vesper workspace are not always the same person, and this binary runs as root.

upgrade.download_host is the only host an upgrade artifact may be fetched from, which bounds what the control plane can do: Vesper chooses which version, never where the bytes come from. The installer writes the host it downloaded from, so a connector installed from an internal mirror goes on upgrading from that mirror rather than refusing every directive. Blank falls back to dl.vesper.wazuh.com.

What an upgrade does on the host, and how to undo one, is in Connector lifecycle.

Every key in the file​

The whole surface, in the order the file is usually written. Anything left out takes the default in this table.

KeyDefaultMeaning
connect_urlwss://connect.vesper.wazuh.comThe outbound session endpoint.
enroll_urlderived from connect_urlWhere enrollment sends its request. Blank means connect_url with wss swapped for https and /enroll appended, which is right unless you run a mirror.
data_dir/var/lib/vesper-connectorWhere the connector keeps the identity it enrolled with. Deleting it costs the connector its certificate, so re-enrolling is the only way back, and the node comes back as a new node in the console.
indexer.urlhttps://localhost:9200The Wazuh indexer to read from.
indexer.username, indexer.passwordblankBasic auth for the indexer. Blank means discover them; see Credentials.
indexer.insecure_skip_verifytrueAccept the indexer's certificate without verifying it, which is the default because Wazuh ships a self-signed one.
indexer.keystore_paththe filebeat keystoreWhere the indexer credential is discovered from on Wazuh 4.x.
wazuh_api.urlhttps://localhost:55000The Wazuh manager API to read from.
wazuh_api.username, wazuh_api.passwordblankThe account the connector authenticates with. Blank means discover them.
wazuh_api.insecure_skip_verifytrueAs for the indexer.
dashboard_configthe dashboard's wazuh.ymlWhere API credentials are discovered from on Wazuh 4.x.
dashboard_opensearch_ymlthe dashboard's opensearch_dashboards.ymlThe same, on Wazuh 5.x.
active_response.enablednoneRetired. Ignored if present. Files written by older installers still carry it.
exec.enabledfalsePermits running shell commands on the host.
upgrade.enabledtruePermits Vesper to replace this binary.
upgrade.download_hostdl.vesper.wazuh.comThe only host an upgrade artifact may come from.
heartbeat_seconds30How often the connector reports in. Drives the online and offline status.
request_timeout_seconds30Per-request timeout against the local indexer and API.

connect_url is the one line the installer fills in rather than hardcodes. It wrote the key from the --connect value, which every install command the console issued carried. A connector installed by hand without that flag has no connect_url line at all, which is not a fault. The connector falls back to the built-in default above whenever the key is missing.

After editing the file, restart the service:

sudo systemctl restart vesper-connector