The Vesper agent
Agent is where Vesper stops answering from a corpus and starts reading a real deployment. The agent is connected to a real Wazuh installation through the connector. It reads that deployment's agents, indices and configuration, reasons about what it finds, and, under the gates described below, fixes what is broken.
It does not have to fix anything. Most questions about a live deployment are questions, and a conversation can be started look only, which is what the front door's Look into it button does. The agent still reads everything it can reach and answers. It is simply not given the tool that runs commands. See Look only conversations.
Prerequisites
- An environment registered in the console, with a connector installed and showing Online.
- Enough service credit. Agent runs are metered like questions, on real token cost.
Starting a conversation
- Open Agent and select an environment from the picker. An environment marked offline can still be selected, but tool calls against it fail until its connector reconnects.
- Choose what the message may do, with the Look and Fix toggle under the composer. Look is the default for a conversation started here.
- Ask in plain language. Typical asks, and which toggle each one wants:
- Look. "Which agents are disconnected right now, and since when?"
- Look. "Check the manager's analysisd queue usage over the last hour."
- Fix. "Why is agent 003 not reporting? Diagnose and fix it." The second half of that sentence is a request to act.
- The agent runs a tool-use loop. It plans, calls tools against the environment through the connector, reads the results, and iterates until it can answer or fix.
Follow-ups work, because recent turns are replayed into the next run, so "now fix it" refers to what was just on screen. New chat starts clean.
Written procedures
The agent knows a set of written troubleshooting procedures, maintained and reviewed by Vesper's team, one per symptom. When a question matches one, the agent says which procedure it is following and asks for its checks together before it reasons about what they returned. When none matches, or when the evidence does not fit the procedure, it says so and investigates the way it otherwise would. A procedure narrows the first minutes of a run. It never limits what the run may read or conclude, and evidence from the environment always wins over it. The procedures are Vesper's own material and are not shown or cited in an answer.
Look only conversations
The toggle under the composer, and the Look into it button on the front door, start a run that is look only. It is a property of that run, decided when the message is sent, and it cannot be changed afterwards by anyone.
What it means concretely:
- The agent is built a tool set with the command tool removed. It is not offered a command and refused one. The tool is not there, so it never spends a step proposing something it was never going to be allowed to do.
- It is therefore stricter than the Read only mode in the table above. Read only refuses changes but still runs read and diagnostic shell commands on the host. A look-only run runs none at all: it reads what the Wazuh API and the indexer report through the connector, and nothing touches a shell.
- It can still read the node itself. The connector answers a fixed set of reads with no shell: a file, the end of a log, a directory listing, a service's state with its journal, and a component's own configuration check. Only the Wazuh components' directories are readable and secret files and values never leave the host. Connector configuration lists exactly what can be read.
- Nothing an admin does while the run is going can widen it. The environment's mode is re-read on every command and can be raised mid-run. A look-only run is unaffected either way, because the limit is on the run and not on the machine.
- The run is labelled Look only in the cockpit, and in the Scope column of the console's Runs page, for as long as it is kept. That label is the record of what the conversation was allowed to do, which the environment's current mode cannot show on its own.
- Everything else is the same. The same environment, the same live reads, the same metering: a look-only run calls a model and is billed like any other.
Choosing it needs no particular role. Asking to do less is always allowed, so a member can start a look-only run against an environment in Auto without touching the ceiling everyone else shares.
The toggle is per message, not per conversation. A conversation can look first and fix later, and switching to Fix applies from the next message onward: it does not retroactively widen anything already sent.
How a run ends
A run ends when the agent has the answer, and it says so in a fixed shape: the diagnosis, the cause when it is known, whether it changed anything on the host, whether that change was checked afterwards, the documentation pages the answer rests on, and what is left to do. The reply in the conversation is written as usual. The shape is what lets the run stop as soon as the evidence supports a conclusion instead of reading on until it runs out of steps.
Two of those fields are checked by Vesper rather than taken from the agent.
- A run started as look only never records a fix, because it was never given a way to make one.
- A fix counts as verified only if, after the last change the agent made, at least one read of the host succeeded. When the agent claims a check that the run's own steps do not show, the reply ends with the sentence "Applied, not verified." so the claim is not mistaken for a confirmed one.
Documentation references are kept only when they point to a page on the fixed list. Anything else is dropped. A reply cites the official documentation pages it read as links under the answer, and each line it quotes as evidence links to the step that produced it. A quoted line that Vesper cannot find in that step's result is marked Unverified.
If the agent ends in plain text without that shape, Vesper asks it once to finish properly. If it ends in plain text again, the reply is kept as it is.
How long a run lasts
A run works on one question until it can answer, until it runs out of steps, or until it has been working for ten minutes. The ten minutes are working time, so time the run spends waiting for an admin to approve a command does not count against it.
At ten minutes the run pauses and asks Keep going? in the conversation.
- Keep going gives it another ten minutes. Nothing else changes. The environment, the mode and the conversation's own scope are exactly what they were, and nothing is waiting to run on the host.
- Stop here ends the run with what it has. Everything it found stays in the transcript, and a follow-up question starts a new run that can pick up from there.
- If nobody answers, the request expires after fifteen minutes and the run stops with what it has.
Any member of the workspace can answer it. It is a decision about spending, not about what the agent may do, so it needs no particular role. Approving a command is the one that needs an admin.
A long run is also split into segments behind the scenes, and the transcript notes each one with Continued in a new segment. That is bookkeeping rather than a limit: the conversation, the steps and everything already found carry across untouched.
Modes
Every environment carries a mode, the ceiling for what the agent may do there. Only an admin can change it, from the Agent page or the environment's card.
| Mode | What the agent may do |
|---|---|
| Read only | Inspect and answer. No changing action is ever applied. Read and diagnostic shell commands still run on the host. |
| Manual | A changing action is proposed and waits for an admin's approval. Read commands still run without asking. |
| Auto | A changing action is applied immediately, and is still recorded in the ledger. A destructive command still waits for an admin's approval. |
The mode is enforced by the Vesper API, not by the console, and it is re-read from the database on every command, so a change of mode takes effect at once.
The mode and the conversation's own scope are two separate limits and the lower one wins. A look-only conversation against an environment in Auto changes nothing, and a fixing conversation against an environment in Read only changes nothing either.
In Manual mode a proposed action pauses the run and appears both inline in the chat and in the Changes ledger, where an admin approves or denies it.
A destructive command waits for approval in every mode, Auto included. Vesper classes a command as destructive when no undo restores what it removes:
- any
DELETErequest, or a_delete_by_query, against the Wazuh API, the indexer or another HTTP API, - removing an agent with
manage_agents -r, - uninstalling a Wazuh package or Filebeat,
- deleting files under a Wazuh directory, such as
/var/ossec,/etc/wazuh-indexeror the indexer's data under/var/lib/wazuh-indexer, including a backup Vesper made there, - deleting a key or certificate anywhere on the host.
The same holds when another command runs it. A destructive command written
inside bash -c, sh -c, eval, su -c or sudo, run by find -exec,
docker exec, kubectl exec, watch, flock or systemd-run, fed its files
through xargs, or written as an inline script for Python, Perl, Ruby, Node or
PHP still waits. So do these:
- emptying a file under a Wazuh directory, for example
> /var/ossec/logs/ossec.log, which loses its contents the same way deleting it does, - overwriting or moving a key or certificate, whether by redirection,
cp,mv,dd,teeorrsync, which means replacing a certificate waits too, and so does copying a whole directory of certificates over the old one, - inline code that starts another command, such as Python's
os.system, - a shell or interpreter that reads its program from its input, such as
curl -s URL | sh, because that program is not written on the line, - a
DELETEsent withwgetor HTTPie, - a command Vesper cannot read because it is not written out, such as
bash -c "$CMD".
Such a command pauses the run exactly as a Manual-mode change does. In Read only it is refused, as every change is.
Who can run the agent
Starting a run is open to the whole workspace. Any member can open Agent, pick any environment, including one in Auto mode, and put the agent to work. Runs are metered against the workspace's shared service credit no matter who starts them.
The role decides what the run is allowed to do, not whether it happens.
| Member | Admin | |
|---|---|---|
| Start a run against any environment | Yes | Yes |
| Have the agent inspect that environment | Yes | Yes |
| Have the agent run a command on the host | No | Yes |
| Approve or dismiss a proposed change | No | Yes |
| Change an environment's mode | No | Yes |
A non-admin's run is refused the moment the agent reaches for a command, even a read-only one, and even where the environment is in Auto mode. The refusal comes back into the transcript as an explanation, and the run carries on with what it can still do, which is everything that only reads through the connector.
What Read only actually permits
Read only means no changes, not no execution. When shell access is enabled on the connector, a command the classifier recognizes as read-only runs immediately on the host in every mode, including Read only. Nothing is written and nothing waits for approval, but a command does execute on the machine.
The classifier is deliberately conservative and fails toward treating a command as a change:
- Only a fixed set of read and diagnostic commands qualifies, such as
cat,grep,ps,df,journalctlandsystemctl status. systemctlqualifies only for status-like subcommands.start,stop,restartandreloadare changes, and so are the same subcommands ofwazuh-control.findstops qualifying the moment it carries-deleteor-exec.- Network diagnostics qualify only toward a local or private address, meaning
localhost, a loopback, private or link-local IP address, or a host name with no dot in it. The cloud instance metadata address169.254.169.254and its siblings, and the host namesmetadataandinstance-data, do not count as local, because a read there returns the machine's cloud credentials. This coverscurlGET and HEAD requests,ping,traceroute,dig,nslookup,nc -zandopenssl s_client. Toward any other address they are changes, so in Read only they are refused and in Manual they wait for approval. - Certificate and firewall inspection qualify, such as
openssl x509,iptables -L,nft list rulesetandufw status, as dofilebeat test outputandwazuh-control status. Their changing forms do not. - A loop or a chain of commands qualifies only if every command in it does.
- Anything that redirects into a file, or uses backticks,
$(...)or<(...), is treated as a change, because a mutation can hide inside it. env,awkandsedare classed as changes even though they usually only read, because each one can be made to execute arbitrary code.- Any command not on the list is a change.
A deployment that should never execute anything at all leaves shell access off, which is the default. See connector configuration.
The gates on a change
Five independent gates sit between the agent and a write. Every one of them has to allow it.
- The run is not look only. A look-only run is built a tool set with the command tool removed, so there is nothing to gate: the agent cannot ask. This is the only gate the person asking chooses, and it is checked before the rest. See Look only conversations.
- The operator is an admin. Shell commands are refused unless the conversation was started by an admin, even in an Auto environment, as set out in who can run the agent above.
- The connector allows the capability. Shell execution is off by default
and is opted into per host. A hand-installed connector opts in with
--enable-exec. On a Wazuh Fleet node an admin turns Shell commands on for that host's node in Vesper, and a Wazuh Fleet administrator allows a root shell for Vesper on the host. See shell commands on a Wazuh Fleet node. A shell command is the agent's only write. See the only write channel. - The environment mode allows it, as described above.
- The catastrophic is refused outright. A short denylist of whole-system destructive operations is refused in every mode, including Auto. Vesper checks it before the command is recorded or sent, and the connector checks the same list again on the host itself.
All five run inside Vesper, and the fifth is also enforced on the customer's own machine. Changes and approvals sets out which safeguard lives where.
What the agent can reach
Through the connector the agent talks to the environment's own local surfaces:
- the Wazuh indexer query API, covering alerts, states and statistics, the cluster health, and below it the indexer nodes with their heap and disk, the indices by health, the shards that are not started and the indexer's own explanation of why a shard cannot be placed,
- the Wazuh manager API, for the manager's own version and status, the agent inventory and the detection rules, the manager's log and throughput counters, the manager cluster as the manager sees it, which is the roster of master and workers with each node's connection and sync state, one section at a time of a manager node's running configuration with keys and passwords removed, and the agent counts and enrolment settings of a manager node,
- optionally, a gated shell on the node for diagnose-and-fix work, if the
host allows it. A hand-installed connector allows it with
--enable-exec, and a Wazuh Fleet node with its Shell commands switch and Wazuh Fleet's permission.
All of it rides the connector's single outbound mTLS session. Vesper never connects into the customer's network.
On a distributed Wazuh, a read of the manager is a read of one node. The agent names the node it wants, and the answer says which node it came from, so the configuration or the log of a worker is never mistaken for the master's. Reads of the manager's log, counters, configuration and enrolment settings need the Wazuh 4.x API. On Wazuh 5.x the agent is told the endpoint does not exist and reads what it can another way.
The official documentation
Vesper also reads the official Wazuh documentation at documentation.wazuh.com. That reading happens on Vesper's own infrastructure and never on a monitored host. It does not travel through the connector. The page is fetched by Vesper's own service, so nothing is downloaded to a machine in the environment, nothing is stored there, and no machine there ever requests it.
Vesper reads from a fixed list of pages, one page at a time, at the moment it needs one. Nothing is stored on Vesper's side either, so what it reads is the page as published at that moment, and a reply that uses a page cites its documentation URL so the claim can be checked. Nothing typed in a conversation can send Vesper to an address that is not on that list, and the list changes only when Vesper ships a new version.