Agent Configuration Reference

You installed the agent. Here's every knob it actually has.

This page is for the admin who already ran the one-line install from Get started and now needs to tune something — a different enrollment token, an SNMP site-collector target, the update policy, or why a device won't come online. Every field below is read straight out of the agent's own source, not aspirational docs.

Last verified: 2026-07-24 against agent v0.6.0
01 — Where configuration lives

A YAML file, or environment variables — the agent merges both.

The agent loads defaults, then a YAML config file (if one exists at the resolved path), then applies BAYQUS_* environment variables on top (falling back to the legacy ONYX_* name if the BAYQUS_ one isn't set). Env vars always win over the file.

Linux install
The installer never writes a config.yaml — it writes environment variables to /etc/bayqus-agent/agent.env (root-only, mode 600), loaded by systemd as EnvironmentFile= for the bayqus-agent.service unit. Binary lives at /usr/local/bin/bayqus-agent; persisted MQTT credentials at /var/lib/bayqus-agent/creds.json.
Windows install
The installer writes a real config.yaml to %ProgramData%\BayqusAgent\config.yaml, locked down with icacls to SYSTEM and Administrators only (the enrollment token lives inside it). The Windows service is registered with -config "<path>" pointing at that file.
-config
CLI flag, path to the YAML file. Defaults to BAYQUS_CONFIG / ONYX_CONFIG if set, otherwise the literal config.yaml in the process's working directory. Resolved to an absolute path at startup so it still works when a service manager starts the binary from an arbitrary working directory.
-once
Debug flag: enroll, connect, publish a single metrics sample, disconnect, exit. Useful for verifying a config before installing it as a service.
-version
Prints bayqus-agent <version> (schema v<N>) and exits.
yaml · config.yaml (full field reference)
# enrollment
backend_url: "https://api.bayqus.app"   # portal base URL, used for enroll + OTA + pull-config
enrollment_token: "tok_xxx..."        # one-time token from the portal's Site page

# broker
mqtt_host: "mqtt.bayqus.app"
mqtt_port: 8884                            # TLS port (default)
mqtt_ca_file: ""                    # optional custom CA bundle (PEM)
mqtt_insecure: false                       # skip TLS verify — LAB ONLY, never in production
keepalive_secs: 60

# identity
device_type: "server"                  # "server" | "pc"
hostname: ""                         # override; defaults to os.Hostname()
state_dir: "/var/lib/bayqus-agent"     # where creds.json is persisted (0600)

# OTA self-update — see section 05
auto_update: true

# collection cadence
metrics_interval_secs: 60                  # clamped 5..3600; plan can lower this live

# critical service checks (platform-aware; set exactly one strategy per entry)
services:
  - name: "nginx"
    unit: "nginx.service"          # Linux systemd unit
  - name: "sqlserver"
    windows: "MSSQLSERVER"       # Windows service name
  - name: "worker"
    process: "worker-bin"        # cross-platform process-name fallback

# threshold-crossing event alerts (percent, 0..100)
thresholds:
  disk_pct: 90
  cpu_pct: 90
  mem_pct: 90

# SNMP site-collector — see section 04
collector:
  enabled: false
  interval_secs: 60
  pull_secs: 60
  targets: []
Environment variable overrides

Every field above can be set with an env var instead.

Prefix is BAYQUS_; the legacy ONYX_ prefix still works for older installs. BAYQUS_ wins whenever both are set. Only the fields below are exposed as env overrides — everything else (thresholds, services, static SNMP targets) is file-only.

BACKEND_URL
Overrides backend_url.
ENROLLMENT_TOKEN
Overrides enrollment_token. This is how install.sh/install.ps1 actually pass the token — never as a CLI argument, so it never shows up in ps.
MQTT_HOST
Overrides mqtt_host.
DEVICE_TYPE
Overrides device_type.
STATE_DIR
Overrides state_dir.
AUTO_UPDATE
Accepts 0/false/no/off or 1/true/yes/on. Overrides auto_update. See section 05.
COLLECTOR_ENABLED
Same true/false vocabulary as above. Overrides collector.enabled. This is exactly what install.sh --collector and install.ps1's -Collector switch set. See section 04.
GATEWAY
Same true/false vocabulary. Turns this host into a site gateway (local broker + upstream bridge + control-plane proxy + SNMP collector). Set by install.sh --gateway and, on Windows, by $env:BAYQUS_GATEWAY=1. See section 03.
BROKER
Points this agent through a site gateway instead of the cloud — the value is a gateway address (host / host:port) or the literal auto (mDNS LAN discovery). Set by install.sh --broker and, on Windows, by $env:BAYQUS_BROKER. See section 03.
CONFIG
Sets the default -config path when the flag isn't passed explicitly.
ENROLL_PATH
Overrides the enrollment HTTP path (default /api/devices/enroll) — only needed against a non-standard backend deployment.
02 — Enrollment token

A one-time key that's exchanged for a per-device identity.

The enrollment token is what you copy from the portal's Site page into --token (Linux) or $env:BAYQUS_ENROLLMENT_TOKEN (Windows). It is not the credential the agent uses day to day.

First run
On its first start, the agent has no cached credentials, so it POSTs the token (plus hostname, OS, arch and its own version) to backend_url + /api/devices/enroll. The backend answers with a device-scoped MQTT username/password and a backend-owned topic prefix (bayqus/<account>/<site>/<device> — new enrollments get the bayqus/ prefix; only pre-rebrand devices still speak the legacy onyx/ prefix).
After that
Those credentials are written to <state_dir>/creds.json with restrictive permissions (dir 0700, file 0600). Every subsequent start loads them from disk and skips the enrollment call entirely — the original token is never sent again.
Per-device scope
Each device gets its own MQTT user/password pair and its own topic prefix. The broker ACL only lets a device publish/subscribe under its own prefix — one compromised device credential can't be used to impersonate, read, or publish as another device.
Self-healing
If the broker ever rejects the cached credentials (for example the device record was removed from the portal), the agent clears creds.json and re-enrolls automatically — provided enrollment_token is still present in its config/env. Deleting creds.json yourself forces a clean re-enrollment on next start.
03 — Site gateway

Bir host bütün saytı buraxılışa çıxarır — internetsiz maşınlar da daxil.

Bir hostu sayt şlüzünə çevirin: o, yerli MQTT broker işlədir, aşağı-axın (downstream) agentlərin trafikini öz çıxış TLS bağlantısı üzərindən buluda ötürür, idarəetmə müstəvisini (enroll / konfiq / OTA) proksiləyir və SNMP sayt-kollektoru rolunu da özündə birləşdirir. Beləliklə heç bir daxili maşının internetə çıxışına ehtiyac qalmır — hamısı yalnız şlüzü görür.

--gateway
Linux bayrağı (Windows-da $env:BAYQUS_GATEWAY="1" mühit dəyişəni). Bu hostu sayt şlüzü edir: yerli broker (standart :8884), yuxarı-axın körpüsü, idarəetmə proksisi (standart :8080, TLS) və SNMP kollektoru — hamısı bir prosesdə. Standart olaraq sönülüdür.
--broker <addr>|auto
Adi agenti buluda deyil, bir sayt şlüzü üzərindən hesabat verməyə yönəldir — internet çıxışı olmayan tam izolyasiya edilmiş maşınlar üçün (Windows-da $env:BAYQUS_BROKER). Konkret host və ya host:port HƏM backend_url, HƏM də mqtt_host dəyərini həmin şlüzə yönəldir; xüsusi auto dəyəri isə şlüzü LAN-da mDNS ilə aşkarlayır.
--mqtt-ca-file <p>
Aşağı-axın maşınında şlüzün yerli TLS sertifikatına etibar etmək üçün onun CA dəstini (PEM) göstərir. Şlüz idarəetmə proksisini öz sertifikatı ilə TLS üzərindən verir, ona görə enroll tokenləri və verilən mqtt_pass heç vaxt LAN-dan açıq mətnlə keçmir. Yalnız laboratoriya üçün: --mqtt-insecure TLS yoxlamasını tamam söndürür.
Kollektor daxildir
Şlüz elə sayt kollektorudur — SNMP sorğusu avtomatik olaraq aktivdir. Şlüzdə --collector-u ayrıca aktivləşdirmək lazım deyil (bax bölmə 04).
sh · gateway + downstream install
# 1) the site gateway (has internet) — runs broker + bridge + proxy + collector
curl -fsSL https://api.bayqus.app/install.sh | sudo sh -s -- \
  --token <TOKEN> --gateway

# 2) an air-gapped machine — reports THROUGH the gateway, never the cloud
#    concrete address: sets both backend_url + mqtt_host to the gateway host
curl -fsSL https://api.bayqus.app/install.sh | sudo sh -s -- \
  --token <TOKEN> --broker 10.0.0.2 --mqtt-ca-file /etc/bayqus-agent/gateway-ca.crt

#    or let it find the gateway itself over mDNS on the LAN
curl -fsSL https://api.bayqus.app/install.sh | sudo sh -s -- \
  --token <TOKEN> --broker auto

# Windows equivalents are env-driven, e.g.:
#   $env:BAYQUS_GATEWAY="1"        (make this host the gateway)
#   $env:BAYQUS_BROKER="10.0.0.2"  (report through the gateway)
04 — SNMP site collector

One agent instance can also watch the agentless gear around it.

Any host agent can double as a site collector: alongside reporting its own health, it polls nearby switches, routers, printers and UPS units over SNMP and reports them as separate devices — no agent installable on those. Turn it on with install.sh --collector, install.ps1's collector env var, or collector.enabled: true in config.yaml. It's off by default.

Bir şlüz (bölmə 03) kollektoru artıq özündə saxlayır — şlüz elə saytın kollektorudur. Şlüzdə --collector-u ayrıca aktivləşdirməyin; bu köhnəlmiş standalone bayraq yalnız şlüzsüz kollektor quraşdırmaları üçün qalıb.

host

IP or hostname of the target device.

type

One of switch, router, firewall, printer, ups, ap.

device

A stable device id under the account/site, e.g. sw-core-1 — this is the label that shows up in the dashboard.

community

SNMP v2c community string.default: public

version

Only "2c" is supported today; SNMP v3 is on the roadmap, not yet implemented.

port

UDP port to poll.default: 161

yaml · collector section
collector:
  enabled: true
  interval_secs: 60     # SNMP poll cadence for every target
  pull_secs: 60         # how often it re-checks the backend for target changes
  targets:
    - host: "10.0.1.1"
      type: "switch"
      device: "sw-core-1"
      community: "public"
      version: "2c"
      port: 161
    - host: "10.0.1.40"
      type: "printer"
      device: "printer-front-desk"
      community: "public"
Portal-managed targets
The static targets: list above is a fallback only. Once the collector is running, it periodically calls the backend (GET /api/agent/collector-config, authenticated with the same device credentials as everything else) and reconciles whatever target list the portal has for that site — no restart needed. On a host:port conflict, the portal-managed target wins over the static one.
On-demand discovery
The same pull-config response can carry a one-shot LAN discovery scan job (CIDR + community list). The collector runs the sweep in the background and posts candidate devices back to the portal for one-click adoption — each scan id only ever runs once per agent process, even across reconnects.
05 — Update (OTA) policy

Two independent switches decide whether a host self-updates.

The agent asks the backend "should I update?" over the same outbound HTTPS channel it already uses (no inbound port, consistent with everything else). Both of the following have to say yes before a binary swap happens.

1

Host-level: auto_update / BAYQUS_AUTO_UPDATE

Defaults to true. Set it to 0/false/no/off (config file or env) to pin this specific host to whatever binary is currently installed — it will never self-update, no matter what the account policy says. This is the per-machine escape hatch.

2

Account-level: rollout policy (portal-controlled)

Even with auto_update: true locally, the backend only tells the agent to update when the account's tenant-set policy allows it: either the account is on the auto rollout policy, or an admin has explicitly approved the exact version being served for that account. Everything else gets update: false back, even if a newer build exists.

3

Integrity check before install

If both gates pass, the agent downloads the new binary to a temp file next to its current one, hashes it, and compares against the SHA-256 the backend's manifest advertised. Any mismatch aborts the install and deletes the temp file — nothing is swapped in on a bad checksum. Only then does it atomically replace itself and restart.

Cadence
First check ~90 seconds after connecting, then every 30 minutes.
What's on offer
The backend can only ever offer the one agent version that's currently baked into it (agent/VERSION at build time). Bumping that file — and re-releasing — is what actually makes a new build reachable at all; a host with auto_update and account policy both green still can't get a version the backend isn't serving.
Metrics cadence rides along
Every update check response also carries a plan-driven metrics_interval_secs, applied live regardless of whether a binary update happens or auto_update is off — so your reporting cadence still follows your plan even on a host you've pinned from self-updating.
The k8s cluster-agent
None of this applies to the Kubernetes cluster-agent — that's upgraded with kubectl set image against a pinned manifest, never over this OTA path. See Get started for the two install paths.
06 — Troubleshooting

The five things that actually go wrong.

The agent enrolled fine but the device never shows online
Check that outbound TCP 8884 to your mqtt_host isn't blocked by an egress firewall or proxy — that's the only port this needs. Then check the service is actually running: systemctl status bayqus-agent on Linux, Get-Service BayqusAgent on Windows. If it's running but silent, tail the logs (journalctl -u bayqus-agent / the service's stdout log) for connect errors — a wrong mqtt_host or an unreachable backend_url are the usual causes.
Enrollment fails with "enroll failed" or a rejected token
Enrollment tokens are minted per device from the portal's Site page — copy a fresh one rather than reusing an old snippet. If <state_dir>/creds.json already exists from a previous partial install, the agent will try to use those cached credentials instead of re-enrolling; delete that file to force a clean enrollment with the new token. If your backend runs on a non-default path, double check ENROLL_PATH hasn't been overridden to something that no longer exists.
An SNMP target shows unreachable
Confirm the collector host can reach the target over UDP 161 (or your configured port) — SNMP is UDP, so a stateful firewall rule for TCP won't help. Check the community string matches what's configured on the device, and that type is one of the supported values (switch, router, firewall, printer, ups, ap) — an unrecognized type is silently treated as generic. Also confirm the collector itself is actually enabled (collector.enabled: true or --collector at install) — a target list with the collector off just sits unused.
Updates seem stuck — the fleet won't move off an old version
This is almost always policy, not a bug: check auto_update isn't disabled on the host, and check the account's rollout policy in the portal is set to auto (or that the specific version has been explicitly approved). Also confirm the backend actually has a newer agent/VERSION released — the backend can't offer a build it doesn't have baked in, regardless of any local setting.
A reinstall/upgrade fails to overwrite the binary
On Windows, a running service holds a file lock on bayqus-agent.exe; the installer stops and deregisters the existing BayqusAgent service before writing the new binary — if you're scripting your own upgrade path outside the installer, stop the service first. On Linux, re-running install.sh uses systemctl restart (not just enable) specifically so an already-running old process is replaced, not left in place.
Keep going

Related reading

Still stuck on a config question?

Send us the config (redact the token) and what you're seeing in the logs — we'd rather debug it with you than have you guess.

Talk to us Email support