Validate AI-generated network device configs before they touch a device. Catches wrong subnet masks, duplicate addresses, bad routes, and dangerous lines, then generates the rollback -- offline, no device required.
Keywords: network automation, Cisco IOS, config validation, AI generated config, LLM network configuration, subnet mask, network engineer, NetDevOps, config linter, rollback, ACL, Claude Code skill, pre-change validation.
Cisco DevNet's guidance for engineers using LLMs is blunt: models produce configurations that are syntactically and semantically plausible but disconnected from reality, with wrong subnet masks or non-existent CLI commands, and you must analyze the output before applying it to a device. The safe pattern everyone converges on is context, plus validation, plus a human approval gate, with a saved rollback.
netguard-config is the validation-and-rollback half you can run with no device and no network access. Point it at a proposed config; it tells you what is wrong and how to back it out.
- IP addressing math: invalid subnet masks, an address that is actually the network or broadcast address of its subnet, and duplicate addresses across interfaces.
- Static routes: malformed destinations, masks, or next-hops.
- Dangerous lines: any-to-any permits, default SNMP communities, read-write SNMP, cleartext or weak or default passwords, telnet on the vty lines, insecure HTTP management.
- Unrecognized commands: an advisory hint that a top-level command may be hallucinated (verify against the target platform).
- findings with severity (errors and high-severity dangers gate),
- a generated rollback (the
noforms that back the change out, with a safe apply order), - a proof-carrying-ops
receipt: a config with an error produces a receipt
pco verifyquarantines.
No dependencies. Python 3.10+.
git clone https://github.com/aharwelik/netguard-config
cd netguard-configpython -m netguard check examples/config.bad.txt --rollbackSample (abridged):
netguard-config: BAD-RTR
lines=19 interfaces=4 findings=11 gating=8
[HIGH] danger (line 3, BAD-RTR:global)
enable password cisco
cleartext enable password (use enable secret)
[ERROR] ip-address (line 8, BAD-RTR:interface:GigabitEthernet0/0)
ip address 10.0.0.0 255.255.255.0
10.0.0.0 is the network address of 10.0.0.0/24, cannot assign to an interface
[ERROR] duplicate-ip (...)
10.0.0.1 already assigned on GigabitEthernet0/2
Exit code is 1 when any gating finding (error or high) is present, 0 when
clean. Verify a config as a change receipt:
python -m netguard check proposed.txt --receipt | python -m pco verify -mkdir -p ~/.claude/skills/netguard-config
cp skill/SKILL.md ~/.claude/skills/netguard-config/SKILL.mdThen ask Claude to "validate this router config before I apply it."
This implements two invariants from the proof-carrying-ops model. Identity
Normalization: every line is attributed to a canonical identity
(device:interface:NAME or device:global), which is what makes duplicate-IP
detection and blast-radius attribution exact. Reversibility: the tool
generates a rollback for the proposed change and certifies, in the receipt, that
a config with an addressing error or a gating danger is not safe to apply.
A heuristic linter with a curated command and danger set; not a full IOS parser or device simulator. It reduces the risk of applying a bad AI-generated config; it does not replace lab validation (pyATS) or human approval. The example configs use documentation-range addresses and placeholder secrets.
Standard library only (ipaddress, re), tested on Python 3.10 through 3.13,
no-emoji guard in CI.
Anthony Harwelik -- aharwelik@gmail.com -- https://github.com/aharwelik
MIT. See LICENSE.