Skip to main content
Cloud

Validation Engines

NetBox Validation uses three engines that evaluate different aspects of infrastructure compliance. All three produce the same output and feed into the same findings, compliance scoring, and dashboard.

Intent Engine

The intent engine evaluates NetBox data to verify compliance with organizational policies. No device connectivity or external services required. 42 built-in checks cover addressing, redundancy, topology, standards, completeness, and security intent.

How It Works

Each intent check receives a device object and parameters, queries related NetBox data (interfaces, IPs, cables, VRFs, etc.), and returns pass/fail results. Checks run against the NetBox data model, which means they automatically respect branch context -- when validating a branch, NetBox returns the branch-overlay data.

Built-in Checks by Category

CategoryChecksExamples
Addressing8no_duplicate_ips, loopback_has_host_route, ip_vrf_consistency
Redundancy7min_cabled_uplinks, min_bgp_sessions, redundant_power
Topology8leaf_spine_connectivity, symmetric_cabling, mtu_consistency_across_link
Standards6bgp_asn_range_consistent, interface_naming_consistent, vlan_id_range_by_site
Completeness8config_context_required_keys, asset_documentation_complete, ntp_syslog_configured
Security Intent5no_plaintext_secrets_in_context, management_vrf_enforced, restricted_prefix_usage

See Check Reference for the complete list with parameters.

Parameters and Config Context

Most checks accept parameters to customize thresholds. Parameters merge with the check's defaults -- you only need to specify what you want to override:

{
"check_name": "min_cabled_uplinks",
"parameters": {"min_uplinks": 4}
}

Several checks derive expected values from NetBox's Config Context feature. This lets you define per-site, per-role, or per-device expectations without hardcoding them in rule parameters:

{
"ntp_servers": ["10.1.1.1", "10.1.1.2"],
"dns_servers": ["10.1.1.3"],
"bgp": {
"asn": 65001,
"neighbors": [
{"ip": "10.0.0.1", "asn": 65000}
]
}
}

Checks that use config context: min_bgp_sessions, config_context_required_keys, bgp_asn_range_consistent, no_forbidden_values_in_context, required_context_structure, no_plaintext_secrets_in_context.

Declarative Checks (No Code)

Declarative checks define validation rules entirely via rule parameters using a query + assert pattern. No code required. Set check_name to _declarative and put the logic in parameters:

{
"check_name": "_declarative",
"parameters": {
"query": {
"model": "dcim.interface",
"scope": "device",
"filters": {"enabled": true}
},
"assert": {
"method": "count",
"operator": "gte",
"value": 3
},
"fail_message": "Device has fewer than 3 active interfaces"
}
}

Query fields:

FieldDescription
modelNetBox model in app.model format (e.g., dcim.interface, ipam.prefix)
scopedevice (objects related to current device), site (same site), or global
filtersFilter kwargs applied to the queryset

Supported models: dcim.interface, dcim.cable, dcim.device, dcim.powerport, dcim.consoleport, dcim.rearport, dcim.frontport, dcim.inventoryitem, dcim.devicebay, dcim.site, dcim.rack, ipam.ipaddress, ipam.prefix, ipam.vlan, ipam.vrf, circuits.circuit, circuits.circuittermination, circuits.provider, tenancy.tenant, tenancy.contact

Assertion methods:

MethodOperates OnExample
countQuerySet count{"method": "count", "operator": "gte", "value": 2}
existsBoolean existence{"method": "exists", "operator": "eq", "value": true}
field_valueField on each object{"method": "field_value", "field": "status", "operator": "eq", "value": "active"}
field_uniqueNo duplicate values{"method": "field_unique", "field": "name"}
aggregate_sumSum of a numeric field{"method": "aggregate_sum", "field": "speed", "operator": "gte", "value": 20000}
aggregate_maxMax of a numeric field{"method": "aggregate_max", "field": "mtu", "operator": "lte", "value": 9216}
related_existsRelated object exists{"method": "related_exists", "field": "primary_ip4"}

Operators: eq, neq, gt, gte, lt, lte, in_list, not_in_list, regex, contains

Example -- every active device at site has a rack assignment:

{
"check_name": "_declarative",
"parameters": {
"query": {"model": "dcim.device", "scope": "site", "filters": {"status": "active"}},
"assert": {"method": "field_value", "field": "rack_id", "operator": "neq", "value": null},
"fail_message": "Active devices must be racked"
}
}

Limitations: Declarative checks cannot do multi-hop graph traversal, complex conditional logic, aggregation across multiple models, or branch-vs-main comparison. Use built-in checks for these.


Config Engine

Available to Premium tier customers. Enabled by default for Premium deployments.

The config engine performs offline structural analysis of rendered device configurations. It is currently powered by Batfish, an open-source network configuration analysis tool. Intent checks verify that NetBox data is compliant; config analysis verifies that the configs generated from that data are structurally sound.

The config engine requires that you use NetBox Config Templates to render device configurations. It analyzes configs rendered from these templates -- it cannot currently analyze configs from other sources. See the NetBox Config Templates documentation for details on setting up templates.

The config engine's network operating system (NOS) support is aligned with Batfish's. Batfish supports a wide range of platforms including Arista EOS, Cisco IOS/IOS-XR/NX-OS, Juniper JunOS, Palo Alto PAN-OS, and others. See the Batfish documentation for the full list of supported platforms.

How It Works

  1. NetBox Validation renders configs from each device's Config Template (Provisioning > Config Templates in NetBox)
  2. Configs are sent to the config analysis engine for parsing and structural analysis
  3. The engine builds a network model and runs structural checks
  4. Results flow into the same findings/compliance pipeline as intent checks

Enabling Config Analysis

The config engine is enabled by default for Premium tier customers. To use it:

  1. Set enable_config_engine: true on each policy that should run config checks
  2. Add rules with engine: "config"
  3. Assign Config Templates to devices (via device, Platform, or DeviceRole) in NetBox

Config Templates

Config Templates use Jinja2 to render device configurations from NetBox data:

hostname {{ device.name }}
!
{% set cc = device.get_config_context() %}
{% if cc.ntp_servers is defined %}{% for ntp in cc.ntp_servers %}ntp server {{ ntp }}
{% endfor %}{% endif %}
!
{% for iface in device.interfaces.all() %}{% set ips = iface.ip_addresses.all() %}{% if ips %}
interface {{ iface.name }}
ip address `{{ ips | first }}`
!
{% endif %}{% endfor %}

Templates have access to the full device object: device.name, device.interfaces.all(), device.get_config_context(), device.platform.name, device.role.name, etc.

Test rendering via API: POST /api/dcim/devices/{id}/render-config/

See the NetBox Config Templates documentation for complete setup instructions.

Differential Analysis (Branches)

When validating a branch, the config engine renders configs from both main and the branch, then performs differential analysis:

  • Lost reachability -- paths that existed before no longer work
  • Broken BGP sessions -- previously compatible sessions become incompatible
  • Routing regressions -- routes that existed before are no longer reachable

Two checks are branch-specific: differential_reachability and routing_changes. These only produce meaningful results when run against a branch.

35 Built-in Config Checks

CategoryChecksFocus
Parse Quality4Config parse status, warnings, undefined references, unused structures
Routing Protocols11BGP sessions, OSPF compatibility, routing loops, multipath consistency, BGP attributes
IP & Topology5Duplicate IPs, IP ownership conflicts, L3 topology, MTU, HSRP/VRRP
ACL & Security7ACL reachability, traffic blocking assertions, prefix filters, auth config
Overlay3VXLAN VNI, EVPN L3 VNI consistency, SNMP communities
Reachability3Source-dest reachability, traceroute, route table completeness
Differential2Lost/new reachability, route changes between main and branch

See Check Reference for the complete list.

If Config Analysis Is Not Available

Config rules produce skip results with a message explaining that the config engine is not available. Intent and graph checks work independently -- there is no config engine dependency for core validation.


Graph Engine

Available to Premium tier customers. Enabled by default for Premium deployments.

The graph engine builds an in-memory infrastructure dependency graph from NetBox's data models and runs resilience checks that evaluate cross-device physical dependencies. It answers questions like "what happens if this power feed fails?" and "which devices share a single point of failure?"

Enabling the Graph Engine

The graph engine is enabled by default for Premium tier customers. To use it, set enable_graph_engine: true on each policy that should run graph checks.

Three of the 16 graph checks also require the config analysis engine for routing-layer analysis (routing_convergence_impact, bgp_session_criticality, forwarding_path_redundancy). These operate independently of per-policy enable_config_engine -- they just need the config engine available at the deployment level.

What the Graph Engine Builds

  1. Power chains -- traces from device power ports through PDUs to power feeds and panels
  2. Network adjacency -- maps cabled interface connections between devices
  3. Circuit paths -- resolves circuit terminations to devices
  4. Physical hierarchy -- maps devices to racks and sites
  5. Failure domains -- identifies shared dependencies (feeds, panels, racks, upstream devices, circuit providers)

The engine widens scope automatically -- it collects all active devices at the scoped sites, not just the policy-targeted devices, to trace complete dependency chains.

16 Graph Checks

Power checks (6)

CategoryChecksFocus
Power6Path completeness, redundancy, feed capacity, three-phase balance, feed/panel blast radius

Topology and infrastructure checks (7)

CategoryChecksFocus
Topology2Device and cable single points of failure
Infrastructure5Site connectivity, circuit diversity, rack failure impact, shared failure domains, concurrent maintainability

Config-engine-enhanced checks (3)

CategoryChecksFocus
Reachability3Routing convergence impact, BGP session criticality, forwarding path redundancy

See Check Reference for complete parameters.

Understanding Graph Results

Graph checks produce two types of results:

  • Per-device results (e.g., power_path_complete): one result per device, similar to intent checks
  • Per-failure-point results (e.g., blast radius, SPOF): one result per feed/panel/rack/cable, with the failure point name in the device field and structured metadata in extra

Blast Radius and Severity Escalation

Blast radius findings group results by failure point and automatically escalate severity based on impact:

Unprotected DevicesEscalation
1--2No change
3--5medium -> high
6--10high -> critical
10+Always critical

The finding detail page shows a blast radius card with protected and unprotected device tables.

Combining Engines

Graph checks coexist with intent and config checks in the same policy:

name: Full Resilience Audit
enable_config_engine: true
enable_graph_engine: true
rules:
- name: No Duplicate IPs
engine: intent
check_name: no_duplicate_ips
severity: critical
- name: BGP Sessions
engine: config
check_name: bgp_sessions
severity: high
- name: Power Path Complete
engine: graph
check_name: power_path_complete
severity: high

Data Quality Requirements

Graph analysis is only as good as the data in NetBox:

  • Power chain tracing requires: power ports on devices, cables from power ports to power feeds (or through PDU outlets), power feeds connected to power panels
  • Network topology requires: cabled interfaces between devices
  • Circuit analysis requires: circuit terminations linked to interfaces or sites
  • Blast radius accuracy depends on all power paths being documented

Troubleshooting

SymptomCauseFix
All devices show "No power ports -- skipped"Devices lack PowerPort componentsAdd PowerPort components to device types, or set skip_if_no_power_ports: false
Blast radius shows 0 affected devicesPower feeds aren't cabled to device power portsCable power ports to power feeds
"No circuits in scope"Circuit terminations don't point to interfacesUse interface-based terminations
Shared failure domain is slowToo many devices (quadratic comparison)Set max_devices parameter or use compare_roles to narrow scope