NetBox — Integration Setup
NetBox is your record of what you own: devices, virtual machines, sites and address space. CMDash reads it with a read-only token and uses it three ways:
- every deployed device and virtual machine joins the reconciled host inventory, so a server that no EDR, scanner or MDM reports shows up as a coverage gap instead of not existing at all;
- every device and virtual machine is added to the asset register;
- each sync records an inventory summary for the integration's dashboard widget: counts by object type and status, sites, IP addresses, and the devices that need attention.
Prerequisites
- A NetBox instance (3.x or 4.x) reachable from CMDash over HTTPS
- A NetBox administrator who can create a user and an object permission
- CMDash Essentials tier or above
CMDash connects to the address you give it from the CMDash service, so on the
hosted service an instance with no inbound path from CMDash (private network
only) cannot be connected: addresses in private, loopback and link-local
ranges are refused. On a self-hosted install (on-prem or customer-cloud), the operator can allow the private range the instance is on with INTEGRATION_ALLOWED_PRIVATE_CIDRS (see docs/security/integration-private-egress.md); the hosted service never reaches private addresses.
Step 1: Create a read-only user
Give CMDash its own NetBox user so its access is visible and revocable on its own.
- In NetBox, go to Admin → Authentication → Users and click Add.
- Name it
cmdash. It does not need staff or superuser status. - Go to Admin → Authentication → Permissions and click Add.
- Name it
CMDash read-only, tick Enabled, and under Actions tick Can view only. - Under Object types, select:
- DCIM › Device
- DCIM › Site
- Virtualization › Virtual machine
- IPAM › IP address
- Under Assignment, add the
cmdashuser, then Save.
Least privilege: CMDash only ever issues
GETrequests. It never creates, changes or deletes anything in NetBox, so do not grant add, change or delete actions. Without the virtual machine or IP address permission the sync still runs: it reads devices and says on the connection what it could not count.
Step 2: Create an API token
- Log in to NetBox as the
cmdashuser (or, as an administrator, go to Admin → Authentication → API Tokens and pick that user). - Open API Tokens and click Add a token.
- Leave Write enabled unticked.
- Optionally set an expiry date, and restrict Allowed IPs to CMDash's egress addresses if your network policy asks for it.
- Click Create and copy the token. It is shown once.
Both token formats work: a classic 40-character token is sent as
Authorization: Token <token>, and a NetBox 4.5+ token that starts with
nbt_ is sent as Authorization: Bearer <token>. CMDash picks the scheme
from the token itself.
Step 3: Connect in CMDash
- Navigate to Integrations in your CMDash dashboard.
- Find NetBox (under Asset inventory & CMDB) and click Connect.
- Enter:
- NetBox URL — the address you open NetBox at, for example
https://netbox.example.com. A path prefix such ashttps://tools.example.com/netboxis kept; a trailing/apiis ignored. - API Token — the token from Step 2, stored encrypted as this connection's access token.
- Sites (optional) — site slugs, comma separated, to limit the sync
to those sites, for example
dc1, dc2. - Tenants (optional) — tenant slugs, comma separated.
- Import assets — Yes (default) adds devices and VMs to the asset register; No keeps them in the host inventory and the summary only.
- NetBox URL — the address you open NetBox at, for example
- Click Save & Test Connection. The test reads
/api/status/for the NetBox version and one device to prove the token works.
What Syncs
| Data | NetBox API | Behaviour on failure |
|---|---|---|
| Devices — name, status, role, site, tenant, platform, primary IP, tags, serial, model, last updated | GET /api/dcim/devices/ | Fails the sync — this is the core dataset |
| Virtual machines — name, status, role, site, cluster, tenant, platform, primary IP, tags, last updated | GET /api/virtualization/virtual-machines/ | Recorded on the connection; devices still sync |
| Sites — name, status | GET /api/dcim/sites/ | Recorded on the connection; the site count shows as unknown |
| IP addresses — count only | GET /api/ipam/ip-addresses/?limit=1 | Recorded on the connection; the IP count shows as unknown |
What lands where
- Host inventory: every named device and VM whose status is not
plannedorinventory(kit that is not deployed is not a host). The primary IP is kept as a last-resort matching hint. NetBox runs no agent, so a NetBox host counts toward the inventory a coverage percentage is measured against and never toward EDR, scanning or MDM coverage itself. - Asset register: every named device and VM except
plannedones, with a description built from the model or cluster, role, site, serial and status. An asset that already exists by name is left as it is. Criticality comes from a NetBox tag namedcritical,high,mediumorlow(the highest wins); untagged assets are Medium. It is set when the asset is created; after that the tier is yours to change in CMDash. - Inventory summary (for the dashboard widget): device, VM and site counts
by status, the IP address count, and an attention list of devices that
are
failed,offlineordecommissioning, have no primary IP, have no role, have no tenant, or have no name. "No tenant" is raised only when your instance uses tenants at all, and "no primary IP" is not raised for planned, inventory or decommissioning devices.
What is never read
- Nothing is written to NetBox.
- Config contexts, secrets, custom scripts, reports, journal entries, change
logs and cabling are not read. Device and VM lists are requested with
exclude=config_context. - Individual IP addresses, prefixes and VLANs are not read — only the count.
Troubleshooting
- 401 Unauthorized: the token is wrong, expired, or was deleted.
- 403 Forbidden: the
cmdashuser's permission is missing DCIM › Device (the sync fails) or another object type (the sync runs and the connection lists what it could not read). - "must use https://": enter the HTTPS address. CMDash does not send an API token over plain HTTP.
- "did not return JSON": the URL reaches a login page, a proxy or another application rather than NetBox. Use the address you open NetBox at in a browser.
- "is not a NetBox slug": the Sites and Tenants settings take
slugs (
dc-east), not display names (DC East). - Fewer devices than expected: a Sites or Tenants filter is set, or
the
cmdashuser's permission has object constraints.
Rate Limits & Sync Behavior
| Setting | Value |
|---|---|
| Sync frequency | Every 4 hours by default (syncInterval is configurable per connection) |
| Pagination | limit/offset, 500 rows per page, at most 50 pages (25,000 rows) per object type; reaching the ceiling marks the run partial |
| Rate limit handling | Shared token-bucket limiter at 120 requests per minute per workspace, so a small NetBox VM is never loaded |
| Circuit breaker | Repeated failures open the breaker and the sync is skipped rather than hammering a struggling instance |
| Failed sync retry | Job queue retries 3 times with exponential backoff (starting at 30s) — see docs/developers/dead-letter.md |
Credential Rotation
- In NetBox, create a new token for the
cmdashuser (Step 2). - In CMDash: Settings → Integrations → NetBox → Edit, enter the new API Token and Save.
- Delete the old token in NetBox.
The NetBox URL cannot be changed while a token is stored, so a credential is never sent to an address it was not issued for. To move to a new address, reconnect and enter the new URL and its token together.
Known Limitations
- No risk register. NetBox does not hold risks, so CMDash creates none from it; the attention list is the signal to act on.
- Inventory, not protection. A NetBox device record says a machine exists. It does not say the machine is patched, encrypted or monitored, and CMDash never reads it that way.
- The IP count is instance-wide under a site filter. NetBox does not filter IP addresses by site; a tenant filter does apply to it.
- Record age, not check-in age. A host's "last seen" time is NetBox's
last_updated— when the record was last edited, not when the machine was last online.