# Configuration reference

> Every setting in the Continuum Local agent's config.json, with its type, default and limits, plus secret references, environment variables, logging and the check command.

The agent reads one JSON file, `config.json`, when it starts. The file is the
agent's security policy: it decides which integrations exist, which hosts each
may reach and which networks may be swept. The agent never writes to it, and a
change takes effect when the agent restarts.

| Install | Location |
| --- | --- |
| `.deb`, `.rpm` | `/etc/continuum-local/config.json` |
| `.msi` | `C:\ProgramData\Continuum Local\config.json` |
| Container | `/etc/continuum-local/config.json`, mounted |
| Helm chart | the `config.json` key of the Secret named in `existingSecret` |
| `.mjs` bundle | the path you pass; without one, `CONTINUUM_LOCAL_CONFIG`, then `./config.json` |

Keys that start with `//` are comments. The Continuum Local panel in Blueprintr
prints the block for each integration, keyed by its ID, ready to paste under
`integrations` (see [Registering an agent](/foliums/blueprintr-user-guide/continuum/local-agent#registering-an-agent)).

## How the agent reads the file

- A value of the wrong type stops the start with a message that gives the key.
  Nothing is guessed: `"true"` in quotes is refused where `true` is meant.
- An unknown key at the top level, inside an integration or inside
  `remoteCredentialScope` is logged as a warning, with the key it probably
  meant, and the agent starts. Inside `discovery`, an unknown key is ignored
  without a warning, except inside `collectors`, where it stops the start.
- `null` counts as not set for top-level, integration and
  `remoteCredentialScope` keys.
- A syntax error is reported by line and column only. The agent never prints
  the text around it, which could be a credential.

```json
{
  "apexUrl": "https://blueprintr.io",
  "displayName": "DC1 agent",
  "enrollmentToken": "env:CONTINUUM_LOCAL_TOKEN",
  "integrations": {
    "<integration ID from the Continuum Local panel>": {
      "provider": "solarwinds",
      "allowedHosts": ["orion.corp.example"],
      "caFile": "/etc/continuum-local/corp-root-ca.pem",
      "credential": {
        "username": "svc-blueprintr",
        "password": "env:SOLARWINDS_PASSWORD"
      }
    }
  }
}
```

## Agent settings

| Key | Type | Default | Meaning and limits |
| --- | --- | --- | --- |
| `apexUrl` | string | required | Your Blueprintr URL, `https://blueprintr.io`. It must be `https://`, with no user name, password, query string or fragment. |
| `displayName` | string | required | Any text that is not empty. Blueprintr shows the name you gave the agent in the Continuum Local panel, not this one. |
| `enrollmentToken` | string or secret reference | none | The single-use token Blueprintr showed when you added the agent. Needed only until the agent has enrolled: remove it afterwards. A different token re-enrols the agent in place. The placeholder from `config.example.json` stops the start. |
| `integrations` | object | `{}` | The integrations this agent serves, keyed by integration ID. See [Integration settings](#integration-settings). An ID that still starts with `REPLACE_WITH`, from the example file, stops the start. |
| `discovery` | object | none | Network sweeps over SNMP. Without it the agent refuses every sweep and SNMP probe. See [Discovery](#discovery). |
| `allowRemoteCredentials` | boolean | `false` | Accept integrations and credentials sent from Blueprintr. Needs `useGateway` on. See [Credentials](/foliums/blueprintr-user-guide/continuum/local-agent#credentials). |
| `remoteCredentialScope` | object | none | Where integrations sent from Blueprintr may connect. See [remoteCredentialScope](#remotecredentialscope). |
| `useGateway` | boolean | `true` | Use the gateway Blueprintr advertises. `false` turns it off, and configuration from Blueprintr with it. |
| `gatewayUrl` | string | none | Pin a gateway instead of the advertised one. Same rules as `apexUrl`. The agent warns at every start when it is not on `apexUrl`'s host or a subdomain of it, because the agent presents its credential there. Ignored while `useGateway` is `false`. |
| `proxy` | string or secret reference | `HTTPS_PROXY`, `https_proxy`, then `HTTP_PROXY` | Proxy for traffic to Blueprintr only: `http://` or `https://`, a host, an optional port and an optional `user:password@`. A path, a query string or another scheme, such as SOCKS, stops the start. |
| `noProxy` | string or list of strings | `NO_PROXY`, then `no_proxy` | Hosts that bypass the proxy, comma-separated or as a JSON list. |
| `extraCaFile` | file path | none | PEM certificates trusted for Blueprintr traffic only, typically a TLS-inspecting proxy's root. |
| `trustSystemCa` | boolean | `true` | Trust the operating system's certificate store as well as the roots built into Node.js, for Blueprintr and for integrations with no `caFile`. |
| `maxConcurrentJobs` | whole number | `4` | Relay and probe jobs run at once, from 1 to 16. At most one sweep runs alongside them. |
| `pollWaitMs` | number | `20000` | Milliseconds a poll asks Blueprintr to wait for work while the gateway WebSocket is not connected. Values outside 1000 to 60000 are clamped to that range, and the agent never asks for more than 25 seconds. |
| `logLevel` | string | `CONTINUUM_LOCAL_LOG_LEVEL`, else `info` | `debug`, `info`, `warn` or `error`, in any letter case. |
| `statePath` | file path | see [Where state is kept](#where-state-is-kept) | The file the enrolled identity is written to. A directory stops the start. |

A value outside what the table allows stops the start, except `pollWaitMs`,
which is clamped. A relative file path resolves against the directory
`config.json` is in.

A file given as `extraCaFile` or `caFile` must contain at least one PEM
certificate. An unreadable file, or one with none, stops the start, and a DER
file is refused with the `openssl` command that converts it. An expired
certificate, or a private key in the same file, is logged as a warning.

## Integration settings

Each entry under `integrations`:

| Key | Type | Default | Meaning and limits |
| --- | --- | --- | --- |
| `provider` | string | required | `solarwinds`, `zabbix`, `prtg`, `checkmk`, `icinga2`, `opmanager`, `whatsupgold`, `netbox`, `infoblox` or `veeam`. It must match the connector the integration uses in Blueprintr, or every request is refused with `unknown_integration`. |
| `allowedHosts` | list of strings | required | The host names or IP addresses this integration may reach, as they appear in its URL in Blueprintr, compared without regard to letter case. At least one. |
| `credential` | object | none | The credential parts the connector needs, by name. Each value is a string or a secret reference. Never sent to Blueprintr. |
| `credentialFile` | file path | none | A JSON object of credential parts, for example written by your secret manager. Its values are used as written, never as secret references. A part set here and in `credential` takes this file's value, with a warning. |
| `caFile` | file path | none | PEM certificates this integration trusts instead of every other root: your internal authority's certificate, or a self-signed appliance's own. |
| `allowInsecureTls` | boolean | `false` | Accept any certificate from this integration's hosts. Logged as a warning at every start. Use `caFile` where you can. |
| `allowPlaintextHttp` | boolean | `false` | Allow `http://` for this integration, which sends the credential unencrypted. Logged as a warning at every start. |
| `allowWriteOperations` | boolean | `false` | Lift the read-only guard for this integration. Logged as a warning at every start. Blueprintr can never set it, and the agent's header checks still apply. See [Read-only by default](/foliums/blueprintr-user-guide/continuum/local-agent#read-only-by-default). |

An `allowedHosts` entry that contains a wildcard, a scheme, a user name, a path
or a port stops the start. Any port on a listed host is allowed. Write IPv4
addresses in plain dotted-decimal form: `010.0.20.5` and `10.1` are refused,
because resolvers read them differently. IPv6 addresses may be written with or
without brackets.

| Provider | Credential parts |
| --- | --- |
| `solarwinds`, `checkmk`, `icinga2`, `whatsupgold`, `infoblox`, `veeam` | `username`, `password` |
| `zabbix`, `prtg`, `opmanager`, `netbox` | `token` |

A part the connector needs but cannot find fails the request with
`credential_missing`, and the message gives the part's name.

## remoteCredentialScope

This block limits integrations sent from Blueprintr, and has no effect while
`allowRemoteCredentials` is off. A host in such an integration must match at
least one entry.

| Key | Type | Meaning and limits |
| --- | --- | --- |
| `hosts` | list of strings | Host names allowed exactly, with the same rules as `allowedHosts`. |
| `domainSuffixes` | list of strings | Domains whose hosts are allowed, such as `monitoring.corp.example`, written without a leading dot or wildcard. A single label is refused unless it is private by convention: `internal`, `local`, `localdomain`, `lan`, `corp`, `home`, `intranet`, `private` or `test`. An IP address is refused: put it in `cidrs`. |
| `cidrs` | list of strings | IPv4 or IPv6 ranges. They cover hosts written as IP addresses and the addresses a host name resolves to, checked again at every connection. A range with bits set below its prefix is refused with the corrected range, and `/0` is refused. A range broader than /8 for IPv4 or /16 for IPv6 is logged as a warning at every start. |
| `allowTlsOverrides` | boolean, default `false` | Let Blueprintr set `allowInsecureTls` or `caFile` on an integration it sends. Logged as a warning at every start when on. |

With or without a scope, loopback, link-local (including the cloud metadata
address 169.254.169.254) and unspecified addresses, and `localhost` names, are
refused for integrations sent from Blueprintr unless a `cidrs` entry covers
them. With `allowRemoteCredentials` on and no scope, the agent warns at every
start that such an integration may reach any host that is not loopback or
link-local. A scope with no entries refuses every one.

## Discovery

| Key | Type | Default | Meaning and limits |
| --- | --- | --- | --- |
| `cidrs` | list of IPv4 ranges | none | The ranges a sweep may cover. A bare address is a /32. A range larger than `maxSweepPrefix` allows stops the start. With none, the agent refuses every sweep. |
| `exclude` | list of IPv4 addresses or ranges | `[]` | Never probed by a sweep. |
| `credentialSets` | list | required | At least one. See [Credential sets](#credential-sets). |
| `credentialTrial` | `"parallel"` or `"sequential"` | `"parallel"` | `parallel` tries every set that applies to a host at once: a dead address costs one timeout, and every applicable community reaches every host. `sequential` tries them one at a time in the order written and stops at the first that answers: fewer communities reach each host, and a dead address costs one timeout per set. |
| `collectors` | object | every collector planned for the device's class | `{ "allow": [...] }` runs only the named collectors, `{ "deny": [...] }` runs all but them, and both together mean allow minus deny. Names: `interfaces`, `addresses`, `entity`, `lldp`, `cdp`, `bridge`, `vlans`, `fdb`, `arp`, `routes`, `health`, `hostResources`, `vmware`, `printer`, `ups`. |
| `collectContact` | boolean | `true` | `false` never requests `sysContact`, which often identifies a person. |
| `concurrency` | number | `16` | Devices profiled at once, 1 to 256. |
| `packetsPerSecond` | number | `50` | SNMP packets a second, 1 to 5000, shared by every sweep and probe the agent runs. |
| `timeoutMs` | number | `1500` | Milliseconds per request, 100 to 30000. |
| `retries` | number | `1` | Retries per request, 0 to 5. |
| `maxSweepPrefix` | number | `22` | The largest range allowed in `cidrs`, as a prefix length, 16 to 32. |
| `maxHosts` | number | `65534` | Addresses probed in one sweep, 1 to 65534. Addresses past it are skipped. |
| `deviceBudgetMs` | number | `60000` | Milliseconds per device, every collector included, 5000 to 600000. |
| `port` | number | `161` | The SNMP port, 1 to 65535. |
| `maxRowsPerTable` | number | `20000` | Rows read from one table on one device, 100 to 200000. |
| `maxVlanWalks` | number | `64` | VLANs walked one by one on switches that keep their bridge tables per VLAN, 0 to 4094. |

A number outside its range, or a collector name that does not exist, stops the
start. Denying `arp` or `fdb`, or setting `collectContact` to `false`, also
limits what Blueprintr can request from a device directly: raw requests then
return only the objects the permitted collectors read.

A sweep probes only addresses inside `cidrs` and outside `exclude`. An SNMP
probe of one device may also reach a host in its integration's `allowedHosts`,
whatever `cidrs` and `exclude` say, on the port the probe gives, with the
credential sets that apply to that host. A set without its own `cidrs` applies
to every host, host names included.

### Credential sets

| Key | Meaning and limits |
| --- | --- |
| `name` | Required, and different for each set. |
| `version` | `"1"`, `"2c"` or `"3"`. Default `"2c"`. |
| `community` | Required for versions 1 and 2c. May be a secret reference. |
| `user` | Required for version 3. |
| `securityLevel` | `noAuthNoPriv`, `authNoPriv` or `authPriv`. Left out, it follows the passphrases given: `authPriv` with a `privPassphrase`, `authNoPriv` with only an `authPassphrase`, otherwise `noAuthNoPriv`. |
| `authProtocol` | `md5`, `sha`, `sha224`, `sha256`, `sha384` or `sha512`. Required for `authNoPriv` and `authPriv`. |
| `authPassphrase` | At least 8 characters. Required for `authNoPriv` and `authPriv`. May be a secret reference. |
| `privProtocol` | `des`, `aes128`, `aes192` or `aes256`, or `aes192b` and `aes256b` for devices that use the Blumenthal key extension. Required for `authPriv`. |
| `privPassphrase` | At least 8 characters. Required for `authPriv`. May be a secret reference. |
| `contextName` | Optional SNMPv3 context. |
| `cidrs` | IPv4 ranges, each inside `discovery.cidrs`. The set is tried only against addresses inside them. An empty list, or a range outside `discovery.cidrs`, stops the start. |

## Secret references

A credential part, an SNMP community or passphrase, `enrollmentToken` and
`proxy` can each be written as a reference instead of the value.

| Written as | Means |
| --- | --- |
| `"env:NAME"` | The value of environment variable `NAME`. A variable that is unset or empty stops the start. |
| `"file:/absolute/path"` | The file's contents, with one trailing newline removed. The path must be absolute, and the file a regular, non-empty file of at most 64 KiB. |
| `"literal:..."` | The text after `literal:`, for a value that starts with `env:` or `file:`. |

References are resolved once, at start, so rotating a secret takes a restart.
A reference that cannot be resolved stops the start with a message that says
where it sat, never the value. Values in a `credentialFile` are never treated
as references.

Set the variables where the service reads them: `/etc/continuum-local/environment`
for the Linux packages, the container's environment, or `extraEnv` for the
Helm chart. On Windows, use `file:` references: environment variables added to
the service are replaced by every upgrade.

## Environment variables

| Variable | Meaning |
| --- | --- |
| `CONTINUUM_LOCAL_CONFIG` | The config path when none is given on the command line. The container sets it to `/etc/continuum-local/config.json`. |
| `CONTINUUM_LOCAL_STATE_DIR` | The state directory when the config has no `statePath`. The systemd unit, the Windows service, the container and the Helm chart set it. |
| `CONTINUUM_LOCAL_LOG_LEVEL` | The log level when the config has no `logLevel`. A value that is not a level means `info`. |
| `HTTPS_PROXY`, `https_proxy`, `HTTP_PROXY` | The proxy for Blueprintr traffic when the config sets none, read in that order. |
| `NO_PROXY`, `no_proxy` | Hosts that bypass the proxy when the config sets no `noProxy`. |
| `NODE_EXTRA_CA_CERTS` | Extra roots, read by Node.js at start and trusted for every connection, your on-premise systems included, except an integration with its own `caFile`. For a proxy's root, use `extraCaFile`. |

## Where state is kept

The state directory contains the agent's enrolled identity,
`agent-state.json`, and with `allowRemoteCredentials`, one file per
integration sent from Blueprintr under `remote-integrations`. The agent creates
the directory with mode 0700 and each file with mode 0600, and checks that it
can write there before it spends an enrolment token.

Without a `statePath`, the agent uses the first of these that applies:

1. `CONTINUUM_LOCAL_STATE_DIR`.
2. `STATE_DIRECTORY`, which systemd sets for the unit.
3. On Windows, `%ProgramData%\Continuum Local\state`.
4. On Linux, `/var/lib/continuum-local`, when the config is
   `/etc/continuum-local/config.json`.
5. The directory `config.json` is in.

## File permissions

- `config.json` can contain credentials. On the Linux packages it is owned by
  `root`, group `continuum-local`, with mode 0640, and every install or upgrade
  sets it back to that. Keep it that way: the service runs as
  `continuum-local`, so it cannot read a root-owned file with mode 0600. Mode
  0600 suits a file owned by the account the agent runs as, such as the `.mjs`
  bundle under a service account. The agent warns at every start when the file
  is readable by every user, or writable by anyone but its owner, and checks
  each `credentialFile` the same way.
- On Windows the agent skips that check. The installer restricts
  `C:\ProgramData\Continuum Local` so the service can read `config.json` but
  not change it, and can write only to `state` and `logs`.
- `/etc/continuum-local/environment` is owned by `root` with mode 0600.
  systemd reads it as root, so the service account never needs to.
- `continuum-local check` warns when the state file is readable by other
  users.

## What Blueprintr receives from this file

On every poll, the agent reports its version, protocol version, platform and
capabilities, including whether it accepts configuration from Blueprintr, the
IDs of its integrations and the ranges in `discovery.cidrs`. At enrolment it
also sends `displayName`, which Blueprintr does not keep. Blueprintr uses the
report to send the agent only work it can do and to offer its ranges when you
start a sweep. Host names, credentials, certificates and every other setting
stay on the agent.

Blueprintr keeps the latest report on the agent's record until the agent is
deleted. People who can manage Continuum integrations for the organisation or
team can see all of it, and Blueprintr staff who run the service see the
version, platform, protocol version and capabilities.

## Logging

The agent writes one JSON object per line, with `ts`, `level` and `message`
and any other fields: `info` and `debug` to standard output, `warn` and
`error` to standard error. Before a line is written, each credential value the
agent loaded is masked in its plain, JSON-escaped and URL-encoded forms. A
value shorter than four characters is not masked.

`logLevel` sets which lines are written. Security warnings are written at
every level. They cover write operations permitted, certificate checking off,
`http://` allowed, configuration from Blueprintr with no scope or with TLS
overrides allowed, a very broad scope range, a pinned gateway off your
Blueprintr domain, a config or credential file others can read or change, a
certificate file that also contains a private key, and each integration sent
from Blueprintr that uses a TLS override.

Where each install writes its log is in
[Troubleshooting](/foliums/blueprintr-user-guide/continuum/local-agent/troubleshooting#logs).

## The check command

```
continuum-local check [config.json] [--port N | --port ID=N]... [--timeout MS]
```

`check` tests the path the agent will take and prints what to change when
something fails. It reads the config from the argument, else
`CONTINUUM_LOCAL_CONFIG`, else `./config.json`. It prints no secret and sends
nothing beyond TLS handshakes, so it cannot enrol, spend a token or claim
work.

| Section | What it tests |
| --- | --- |
| Configuration | The file loads, with a summary: integrations, discovery on or off, configuration from Blueprintr on or off, and jobs at once. Every warning and notice the agent would log at start follows. |
| State | The state directory is writable, and the agent is enrolled or has an `enrollmentToken`. |
| Trust | The certificate roots in use: Node.js's defaults, `NODE_EXTRA_CA_CERTS`, the system store, `extraCaFile` and each integration's `caFile`. |
| Blueprintr | The proxy in use, then DNS, TCP and a verified TLS handshake with Blueprintr, and with the gateway when one is known. |
| Integrations | DNS and a verified TLS handshake, direct and never through the proxy, with every host in every `allowedHosts`, eight at a time. |

Each line starts with `ok`, `WARN`, `FAIL` or `--` for information, and the
report ends with a `Result:` line. `check` exits with 0 when everything
required passed and 1 otherwise. The gateway is not required: an agent that
cannot reach it polls.

| Option | Meaning |
| --- | --- |
| `--port N` | The port to try on every integration host. Default 443. |
| `--port ID=N` | The port for one integration, by ID, such as `--port <ID>=17774` for SolarWinds Orion. Repeat it for others. |
| `--timeout MS` | Milliseconds allowed for each connection attempt, 100 to 120000. Default 10000. |

On the Linux packages, run `sudo continuum-local check /etc/continuum-local/config.json`.
Run as root, the command reads `/etc/continuum-local/environment` the way
systemd does, then runs as the `continuum-local` user, so it sees the same
proxy, certificate roots and file permissions as the service.

`continuum-local --version` prints the agent version, the protocol version,
the Node.js version and the platform.
