Skip to content

vHaaS Agent

The vHaaS Agent (vhaas-agent) is the software you install on a machine to connect your hardware setup to the vHaaS web service. Once installed, it registers the machine with vHaaS and keeps it online through a secure, outbound-only connection — no inbound ports are opened.

Renamed from vehaas-agent

The command, its configuration directory, its environment variables and its service were renamed from vehaas to vhaas. This page documents the current names. The previous ones are still accepted so existing scripts and automation keep working, and using one logs a deprecation warning to standard error telling you the replacement. Two names deliberately keep their original spelling: the Chocolatey package ID and the rabbitmq.vhost default — both are noted where they appear.

Requirements

  • Operating system — Windows or Linux. The agent ships as a Chocolatey package for Windows and as .deb / .rpm packages for Linux (amd64 and arm64).
  • TPM 2.0 — the agent binds its identity to the host's TPM. Devices without a hardware TPM (for example a Raspberry Pi used as a bench device) need an additional software-TPM package; see vHaaS Agent Setup.
  • Privilegessetup and the service require administrator rights on Windows and sudo on Linux.
  • Outbound network access — see Network requirements. No inbound ports are opened.

What is a TPM?

A TPM (Trusted Platform Module) is a security chip built into most modern PCs and laptops. It can generate and store private keys internally and never releases them — you can ask it to sign something, but you cannot read the key back out.

That is why the agent uses it: the machine's vHaaS identity is a key pair created inside the TPM, so the identity cannot be copied to another machine even by someone with full access to the disk. See Registration and identity.

Most business-class machines from roughly 2016 onward have one, and it is required for Windows 11. A virtual machine may expose a vTPM from its hypervisor, which works the same way. Small bench devices such as a Raspberry Pi usually have no TPM at all and need the software-TPM package instead.

Commands

All commands accept --config-file (-c) and the --config-<key> overrides described under Configuration. Errors go to standard error, and each failure class has a distinct exit code.

setup

Registers the machine with vHaaS. Run once per machine, as administrator or with sudo.

setup initializes the TPM, sends the resulting public keys to the vHaaS proxy, writes the returned virtual-machine ID into the configuration file as rabbitmq.client-id, configures the Cloudflare tunnel when the machine was provisioned with one, then switches the agent service to automatic start and starts it.

Flag Short Description
--registration-token -r One-time registration token (vhaas_reg_...). Also read from VHAAS_REGISTRATION_TOKEN.
--non-interactive -N Never prompt. Fails immediately if no token was supplied, instead of waiting for input.
--force -F Re-initialize the TPM even if it already holds valid state, and ignore a persisted registration.
--url -u Override vhaas-proxy.url and write it back to the configuration file. Use this to supply the proxy URL on a machine that has no configuration yet.
--config-file -c Path to the configuration file.

Without --registration-token and without --non-interactive, setup prompts for the token. After a successful run it asks whether to reboot (up to three attempts); --non-interactive skips that prompt.

The registration token is single-use and expires after one hour

A token can be redeemed once. If it expires or is consumed, obtain a new one — see Re-registering a machine.

run

Runs the agent in the foreground. The installed service does this for you; run it manually only to debug.

Flag Short Description
--context-mode -M system (default) or user.
--config-file -c Path to the configuration file.

On Windows the agent runs in both modes: the vhaas-agent service runs run --context-mode system, and a second, per-user process runs run --context-mode user. Auto-update and the metrics exporter run only in system mode.

The per-user process starts when a user signs in, from an autostart entry the installer writes to HKCU\Software\Microsoft\Windows\CurrentVersion\Run (value name vhaas-agent-user). It runs with that user's permissions and inside their desktop session, which is what lets it handle interactive work such as desktop notifications.

This is a per-user autostart entry, not a logon script

It uses the same Run-key mechanism any desktop application uses to start itself at sign-in. No Windows logon script, Group Policy object, or Active Directory configuration is involved, and there is nothing to deploy centrally — installing the agent is enough.

run requires rabbitmq.client-id, rabbitmq.url, and vhaas-proxy.url. If any is missing it exits with code 30 before connecting.

version

Prints the agent version. Takes no flags.

$ vhaas-agent version
VHaaS Agent Version: 1.4.2

config show

Prints the effective configuration — configuration file, environment variables, flags, and defaults merged — in the configuration file's own key layout, so the output can be pasted back into config.yaml.

Secrets are printed in clear text

config show prints tunnel.token unredacted. Do not paste its output into tickets or chat.

config set

Persists configuration values without re-registering or touching the TPM. Only the --config-<key> flags you pass explicitly are written; environment variables and defaults are not. Requires --config-file.

vhaas-agent config set --config-file /usr/local/etc/vhaas-agent/config.yaml \
    --config-vhaas-proxy-url https://vhaas.vector.cloud

Comments and key order in the file are not preserved. Changes take effect after a service restart; the command prints the restart command for your platform.

doctor

Runs health checks and prints a status table. This is the first thing to run when something is wrong — see Troubleshooting.

Flag Description
--lines Number of log lines to include. Default 50.
--json Emit the report as JSON instead of a table.
--verbose Include raw detail: TLS certificate information, full log lines, raw service output, and the redacted configuration.
--config-file Path to the configuration file.

doctor exits 50 if any check fails, so it can gate a scripted health check.

Configuration

File location

/usr/local/etc/vhaas-agent/config.yaml

C:\ProgramData\vhaas-agent\config.yaml

The file is written with 0600 permissions because it holds the Cloudflare connector token.

Where settings come from

Each setting is resolved from the first source that provides it:

  1. Command-line flag--config-<key>, for example --config-logging-level debug
  2. Environment variableVHAAS_CONFIG_<KEY>, uppercase with underscores, for example VHAAS_CONFIG_LOGGING_LEVEL
  3. Configuration file
  4. Built-in default

Nested keys flatten with hyphens: logging.level becomes --config-logging-level and VHAAS_CONFIG_LOGGING_LEVEL.

A missing configuration file is not an error

If the file does not exist, the agent falls back to environment variables, flags, and defaults. A setup or run that seems to ignore your file is often reading a different path — check with vhaas-agent config show.

Configuration keys

Key Default Description
rabbitmq.url — (required) MQTT broker WebSocket URL. Must be ws:// or wss:// with a host, for example wss://vhaas.vector.cloud/mqtt.
rabbitmq.client-id — (written by setup) The virtual-machine ID. Required by run.
rabbitmq.vhost vehaas_agents RabbitMQ virtual host. The default keeps its original spelling because it names a virtual host provisioned on the broker — do not change it.
rabbitmq.tls-skip-verify false Skip TLS certificate verification. Development only.
vhaas-proxy.url — (required) vHaaS proxy base URL. Must be http:// or https:// with a host.
vhaas-proxy.tls-skip-verify false Skip TLS certificate verification. Development only.
tunnel.token "" Cloudflare connector token, written by setup. Secret.
logging.level info One of debug, info, warn, error.
logging.format json json or text.
logging.dir /var/log/vhaas-agent (Linux), C:\ProgramData\vhaas-agent (Windows) Log directory.
logging.add-source false Include source locations in log entries.
autoupdate.enabled true Enable automatic updates.
autoupdate.check-interval 300 Seconds between update checks.
autoupdate.package-manager auto-detected apt, dnf, or choco.
tpm.url "" TPM simulator URL, for example tcp://127.0.0.1:2321. Empty means use the hardware TPM.
metrics-exporter.enabled false Enable the metrics exporter.
metrics-exporter.mode assembly assembly or cluster.
metrics-exporter.profile "" Path to a local profile JSON. Used in file mode.
metrics-exporter.profile-source file file or pull. pull fetches the assembly profile from vHaaS and follows re-assignment automatically.
metrics-exporter.profile-refresh-seconds 900 Profile re-pull interval in pull mode.
metrics-exporter.url "" Listen URL. Overridden at runtime by the agent's loopback bridge.

The installed configuration file overrides some built-in defaults

The shipped config.yaml explicitly sets autoupdate.enabled: false, metrics-exporter.enabled: true, and metrics-exporter.profile-source: pull, which differ from the built-in defaults above. Run vhaas-agent config show to see what is actually in effect.

Deprecated keys

These keys still function and log a deprecation warning to standard error, but will be removed in a future release. When both the deprecated key and its replacement are set, the replacement takes precedence.

Deprecated Replacement
rabbitmq.broker-url rabbitmq.url
vhaas-proxy.host + vhaas-proxy.port vhaas-proxy.url
tpm.host + tpm.port tpm.url
metrics-exporter.endpoint metrics-exporter.url

Network requirements

The agent needs outbound access only. No inbound ports are opened.

Purpose Protocol / port If blocked
Registration, status, metrics, and the MQTT control channel TCP 443 to the vHaaS platform, including MQTT over WebSocket The machine cannot register and never appears online.
Cloudflare tunnel carrying remote-desktop sessions UDP/TCP 7844 — see Cloudflare's Tunnel with firewall guide The machine shows online but sessions fail to open.
DNS resolution UDP/TCP 53 Registration fails with a host-resolution error.
Clock synchronization NTP UDP 123 A skewed clock breaks TLS and registration.

Using an HTTP proxy

The agent honors the standard HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables for both its HTTPS calls to the vHaaS proxy and its MQTT-over-WebSocket connection.

Automatic updates are the exception: they invoke the system package manager, which uses its own proxy configuration (apt.conf, dnf.conf, or the Chocolatey configuration) rather than these variables.

Registration and identity

The machine's identity is bound to its TPM. During setup the agent generates TPM-resident keys and sends the public keys to vHaaS, which stores them on the virtual-machine record. Every later connection is signed with those keys, so the identity cannot be copied to another host.

Registration tokens are single-use and valid for one hour. On success setup writes the returned virtual-machine ID into the configuration file as rabbitmq.client-id; the service uses it on every subsequent start.

Re-running setup on an already-registered machine does not register again. It first confirms the stored identity is still accepted, then reuses it. If vHaaS rejects it — because the virtual machine was deleted or re-enrolled — setup fails with exit code 22 rather than leaving the agent unable to connect.

Re-registering a machine

Registration is not idempotent: a second registration for a machine that already has keys is rejected with exit code 11. To move a machine to a fresh identity:

  1. An administrator clears the stored public keys on the virtual-machine record in vHaaS.
  2. Obtain a new registration token — the previous one is consumed.
  3. Re-run setup with --force:
sudo vhaas-agent setup --force --registration-token vhaas_reg_...

--force re-initializes the TPM and ignores any persisted registration. Without step 1 it still fails with exit code 11.

Service and logs

The agent runs as a system service and starts on boot. The package installs the service in a stopped, manual-start state, because it cannot run before setup has initialized the TPM; setup switches it to automatic start and starts it.

Managing the service

The service is named vhaas.

systemctl is-active vhaas
sudo systemctl restart vhaas
sudo journalctl -u vhaas -n 50

The service is named vhaas-agent and is displayed as VHaaS Agent Service.

Get-Service vhaas-agent
Restart-Service vhaas-agent

A second, per-user agent process starts at logon and handles the interactive session context. Restarting the service does not restart it; log off and back on instead.

Log files

/var/log/vhaas-agent

C:\ProgramData\vhaas-agent

Control the output with logging.level (debug, info, warn, error), logging.format (json or text), and logging.dir. vhaas-agent doctor tails the log for you — use --lines to change how much.

Updating

The agent can update itself from the package repository it was installed from.

Key Default Meaning
autoupdate.enabled true — but the installed config.yaml sets false Whether to check at all.
autoupdate.check-interval 300 Seconds between checks.
autoupdate.package-manager auto-detected apt, dnf, or choco.

Behavior worth knowing:

  • The first check happens one full interval after the agent starts, not at startup.
  • Checks run only in the system context — the per-user Windows process never updates.
  • The update command is launched detached, so the agent does not wait for it and a slow update never blocks the control channel.
  • A failed check is logged and the loop continues; it never stops the agent.

To update manually:

sudo apt-get update && sudo apt-get install --only-upgrade vector-vhaas-agent
choco upgrade vector-vehaas-agent -y

The Chocolatey package ID is still vector-vehaas-agent

This is deliberate, not a leftover. Chocolatey has no mechanism for one package to supersede another under a new ID, so renaming it would leave every existing installation with no upgrade path. The Linux packages, which do support this, are named vector-vhaas-agent.

An upgrade preserves the machine's identity — the configuration file and TPM state are retained across it.

Uninstalling

Uninstalling removes the agent's identity. The machine must be registered again afterwards.

sudo apt-get purge -y vector-vhaas-agent

Use dnf remove on RHEL-family systems. Add vhaas-agent-swtpm if the software-TPM package was installed. cloudflared is left in place — remove it separately if nothing else needs it.

choco uninstall vector-vehaas-agent -y

The installer removes the program directory, the C:\ProgramData\vhaas-agent configuration directory, the PATH entry, and the cloudflared service registration.

During removal the agent evicts the TPM key handles that setup created, so a later reinstall starts from a clean slate. This runs automatically; there is no command to invoke. An upgrade deliberately does not evict them, which is what preserves the identity.

After uninstalling, delete the virtual-machine entry in vHaaS, or have an administrator clear its keys if you intend to re-register the same machine — see Re-registering a machine.

Troubleshooting

Start with doctor

sudo vhaas-agent doctor

doctor prints one row per check. Read it top to bottom — a failure in an early row usually explains every failure below it.

Row What it means
Agent service / Cloudflared Whether each service is running. Cloudflared is only required when the machine uses a tunnel; for a direct VM an unhealthy cloudflared is reported as a warning.
Config / Setup / Tunnel mode Whether the configuration file loaded, whether setup has completed (a virtual-machine ID is present), and whether a tunnel token is configured.
Backend (HTTPS) DNS, TCP, TLS, and HTTP reachability of vhaas-proxy.url, broken out so you can see which layer fails.
RabbitMQ The same breakdown for the MQTT WebSocket, ending in the WebSocket upgrade.
TPM Whether the TPM can be opened and its state read.
Logs How many log lines were found, and where.

skipped does not mean healthy

A connectivity check reports skipped when the setting it needs is absent from the configuration — the backend check when vhaas-proxy.url is unset, the RabbitMQ check when rabbitmq.url is unset. It is never skipped because a service is merely down. A skipped row means fix your configuration, not that the check passed.

Add --verbose for TLS certificate detail and full log lines, or --json to parse the report in a script. doctor exits 50 when any check fails.

Symptoms

Symptom Likely cause Resolution
setup fails, exit 10 (HTTP 401) The registration token is invalid, expired, or already used. Tokens last one hour and work once. Obtain a new token from the virtual-machine dialog in vHaaS and re-run setup.
setup fails, exit 11 (HTTP 409) The machine already has registered keys. Registration is not idempotent. See Re-registering a machine. --force alone is not enough — an administrator must clear the stored keys first.
setup fails, exit 12 (HTTP 422) vHaaS rejected the TPM public keys. Re-run setup --force to re-initialize the TPM, then try again.
setup fails, exit 13 (HTTP 503) The registration service is temporarily unavailable. Retry. This is the only registration failure worth retrying automatically.
setup fails, exit 22 The stored identity was rejected — the virtual machine was deleted or re-enrolled in vHaaS. Have an administrator clear the keys, then re-register with a new token and --force.
setup fails, exit 41 Registration succeeded but the configuration could not be written, so the identity was lost locally. Fix the cause (path, permissions), obtain a new token, and re-run setup --force. A plain re-run fails with 11.
setup fails, exit 42 Registered and persisted, but the Cloudflare tunnel could not be configured — usually cloudflared is missing. Install cloudflared, then re-run setup normally. The stored identity is reused, so there is no 11.
run or the service fails, exit 30 A required setting is missing: rabbitmq.client-id, rabbitmq.url, or vhaas-proxy.url. Run vhaas-agent config show to see what is in effect. A missing client-id means setup has not completed.
Service is inactive and will not start The service is installed stopped and manual-start; setup normally flips it. If setup warned that it could not start the service, it was never enabled. sudo systemctl enable --now vhaas on Linux, Start-Service vhaas-agent on Windows, then check the logs.
Machine shows online, but sessions will not open The Cloudflare tunnel is blocked outbound while the control channel on 443 still works. Allow UDP/TCP 7844 — see Network requirements. Confirm with the Cloudflared row in doctor.
A configuration change had no effect The value is overridden by an environment variable or a flag, the service was not restarted, or a different file is being read. vhaas-agent config show prints the effective values. Restart the service after changing the file.
The agent is not updating itself The installed config.yaml ships with autoupdate.enabled: false; the first check is also one interval late, and the per-user Windows process never updates. Enable it with config set and restart the service, or update manually — see Updating.
doctor shows TPM fail No TPM 2.0 on the host, or its state is unreadable. Confirm the host has a TPM 2.0. Bench devices need the software-TPM package.

Exit codes

When you script the agent — for example from an Ansible playbook — vhaas-agent returns a distinct exit code for each class of failure, so your automation can branch on the return code (rc) instead of parsing the error text. These codes are a stable contract and do not change meaning across releases. Error messages are written to standard error.

Code Meaning
0 Success.
1 Generic or unexpected error.
10 Registration token is invalid, expired, or already used.
11 The virtual machine is already registered.
12 The TPM public keys were rejected.
13 The registration service is temporarily unavailable — safe to retry.
20 TPM error (open, initialize, verify, or read keys).
21 Registration token missing while running non-interactively.
22 Cached identity rejected — the VM was deleted or re-enrolled.
30 Required configuration is missing (proxy or broker settings for run/setup; config set without a config-file path). Nothing has happened yet — fix the configuration and retry.
40 config set could not write the configuration file.
41 setup registered the VM but could not persist the configuration (write failed or no config-file path). Do not simply re-run setup — it is rejected as already registered. Recover by fixing the cause, obtaining a new registration token for the VM (the old one is consumed), and re-running setup --force.
42 setup registered the VM and persisted the configuration, but could not set up the Cloudflare tunnel (cloudflared is not installed, or the service install failed). Safe to retry: re-run setup normally — the saved identity is reused, so there is no already-registered rejection. Once cloudflared is available, the re-run completes.
50 One or more doctor health checks failed.
80 Usage error — a bad flag or unknown command.

Automating with Ansible

Retry only on code 13 (service temporarily unavailable). Treat other non-zero codes as hard failures that should alert an operator rather than retry — for example 10 (invalid token), 41 (registered but not persisted), or 42 (registered but the tunnel could not be set up; once cloudflared is fixed, a plain setup re-run recovers).

- name: Register the vHaaS agent
  ansible.builtin.command:
    cmd: >-
      vhaas-agent setup --non-interactive
      --registration-token "{{ vhaas_registration_token }}"
      --config-file /etc/vhaas/config.yaml
      --config-vhaas-proxy-url "{{ vhaas_proxy_url }}"
      --config-rabbitmq-url "{{ vhaas_broker_url }}"
  register: vhaas_setup
  retries: 5
  delay: 30
  # Retry only while the registration service is unavailable (rc 13).
  until: vhaas_setup.rc != 13
  # Any non-zero rc is a failure — including a 13 that persists after all
  # retries (a real outage). Inspect vhaas_setup.rc to alert per code,
  # e.g. 10 (invalid token), 41 (registered but not persisted), or
  # 42 (registered but tunnel not set up; a plain re-run recovers).
  failed_when: vhaas_setup.rc != 0