Skip to main content
PacketMentor logo
Open menu
← All posts
aisecuritynetopscompliancechatgptgenai

Don't paste that config into ChatGPT — safe GenAI for netops

A senior network engineer's field guide to using LLMs for NetOps without leaking configs, keys or topology. What actually leaks in a show run, the compliance exposure, a working sanitizer script, prompt patterns that work, and enterprise + self-hosted options compared.

Pasting a broken switch config into ChatGPT is the fastest way to find a syntax error. It’s also the fastest way to violate your company’s data policy and — depending on which regulator owns your industry — potentially end your career.

That’s not a scare line. AI is now a routine part of the NetOps workflow: quick triage, config template drafting, log analysis, exam-question sanity checks. It’s also, in the default consumer configuration, a live data-exfiltration pipe running out of your terminal directly into somebody else’s training corpus and legal jurisdiction. The good news is the workflow is fixable with an evening’s work. The bad news is most teams haven’t done it yet.

This is the field guide I wish existed when the first engineer on my team pasted a show run into free ChatGPT to ask about an OSPF neighbor stuck in EXSTART.

What actually leaks in a “harmless” show run

The interesting question isn’t whether a config is sensitive — every senior engineer will nod along and say “of course.” The interesting question is what specifically leaks when you paste even a small snippet. Let’s be concrete. A single-page show run on a mid-sized enterprise router typically exposes:

  • Real routable IPs. Public /29s and /28s that map directly to your NAT edge, VPN concentrators, SD-WAN hubs. An attacker who knows your public v4 space has a target list.
  • SNMP community strings. snmp-server community <str> RW sitting in plain text. Read-write on your entire fleet.
  • AAA shared secrets. radius-server host 10.10.10.5 key <secret>, tacacs-server key <secret> — the keys that gate every admin login.
  • IPsec pre-shared keys. crypto isakmp key <psk> address <peer> — the shared secret protecting your site-to-site tunnel. Present in the same file as the peer IP.
  • Routing-protocol authentication keys. OSPF ip ospf authentication-key, EIGRP authentication-key, BGP neighbor <peer> password <str>.
  • Wireless PSKs and RADIUS keys. On any switch stack that terminates a WLC or embedded AP.
  • Management-plane ACLs. Your jumphost subnet, your NMS’s IP, your Splunk collector. A rough map of “kill this box and admins can’t reach anything.”
  • Internal VLAN and subnet map. Segmentation is a control. Publishing a show vlan brief + show ip route connected publishes your segmentation.
  • BGP topology. Peer IPs, ASNs, MD5 passwords, route-reflector clients. Anyone with your BGP topology can model your blast radius.
  • Certificate and CA data. crypto pki trustpoint blocks, enrollment URLs, key sizes.
  • Hostnames. hostname DC1-AGG-SW01 tells an attacker exactly where the box sits in your data center.

None of this is theoretically sensitive. It’s operationally sensitive. Any one line is enough to move an adversary from “external” to “informed external,” which is the pivot that turns a two-week compromise into a two-hour one.

The threat model, precisely

The vague version — “LLMs might train on your data” — is true but doesn’t help you argue with anyone. Here’s the precise version:

1. Consumer/free tier LLMs retain and can train on your prompts. OpenAI’s default consumer terms allow prompt data to be used for model improvement unless you opt out. Anthropic, Google, Meta — same posture on their free/consumer tiers. Your input has become part of the vendor’s training corpus by the time you close the tab.

2. Enterprise tiers have zero-retention or short-retention agreements, but the prompt still crosses the internet. ChatGPT Enterprise, Claude for Enterprise, Azure OpenAI, AWS Bedrock all offer contractual data-handling that keeps your prompts out of model training. That is a real reduction in exposure. It does not eliminate exposure — the prompt is still processed on someone else’s compute, subject to their operational logs, their subpoena posture, and their breach exposure.

3. Sidecar leakage is often bigger than direct leakage. Browser extensions with clipboard access, screen-recording tools, session-replay analytics on the LLM’s own UI, IDE plugins that stream keystrokes for “AI autocomplete,” clipboard-history managers, corporate DLP tools that store what you copied — all of these can persist prompt data locally in ways your security team has no visibility into.

4. Compliance frameworks treat this as a data-classification failure. Concretely:

  • HIPAA — a config isn’t PHI per se, but if any endpoint IP maps to an EHR system or a covered entity’s subnet, the segmentation map itself becomes “reasonably identifiable information” under the Privacy Rule’s minimum-necessary standard. HHS OCR has settled cases on much thinner grounds.
  • PCI DSS 4.0 — anything that describes the cardholder data environment (CDE), including the ACLs and routing that enforce its segmentation, is in scope. Publishing your segmentation to a third-party model is a Req 7 access-control failure.
  • SOC2 — auditors will fail a Confidentiality control if you can’t demonstrate that operational configs are classified and handled appropriately. “We paste them into ChatGPT” is not appropriate handling.
  • NIST 800-53 SC-8 / SC-13 — data in transit protection and use of validated crypto modules. Public LLMs are neither an authorized system nor a validated module.
  • CJIS / FedRAMP / ITAR — hard prohibitions on unclassified handling of anything remotely operational. If your org touches any of these, the answer is not “sanitize better,” it’s “self-hosted only, full stop.”

Every one of those frameworks accepts the enterprise-tier answer if it’s contracted and documented. None accept “we told people to be careful.”

The sanitization layer — a working script

The single most useful thing you can do this week: put a sanitizer between engineers and the paste buffer. Here’s a working Python 3 script that scrubs the most common sensitive fields from a Cisco IOS config. Save it as sanitize-config.py, drop it in your ~/bin, alias it to sc, and pipe.

#!/usr/bin/env python3
"""
sanitize-config.py — scrub a Cisco IOS / NX-OS / IOS-XE config of the
fields that shouldn't cross the boundary into a public LLM.

Not a substitute for review — but reduces the average-case leak from
"complete topology" to "generic template with a shape."

Usage:
  cat show-run.txt | ./sanitize-config.py > safe-to-paste.txt
  pbpaste | ./sanitize-config.py | pbcopy    # macOS clipboard round-trip
"""
import re
import sys
import ipaddress

# --- IP handling -------------------------------------------------------------

# RFC 5737 documentation prefixes — the only IPv4 space that is
# permanently guaranteed not to belong to anyone in production.
DOC_PREFIXES = ["192.0.2.", "198.51.100.", "203.0.113."]

# Stable per-run mapping so the same real IP always maps to the same
# fake IP within a single sanitizer run — preserves relationships
# (routes still point to the "same" next-hop) without leaking values.
_ip_map = {}
_next_idx = [1]  # /24 host counter within the current doc prefix

def _fake_ip(real: str) -> str:
    if real in _ip_map:
        return _ip_map[real]
    prefix = DOC_PREFIXES[len(_ip_map) % len(DOC_PREFIXES)]
    fake = prefix + str(_next_idx[0] % 254 + 1)
    _next_idx[0] += 1
    _ip_map[real] = fake
    return fake

def _replace_ip(match: re.Match) -> str:
    raw = match.group(0)
    try:
        addr = ipaddress.ip_address(raw)
    except ValueError:
        return raw
    # Keep loopback / link-local / multicast / broadcast as-is — they aren't
    # exfiltration risks and preserving them helps the LLM answer usefully.
    if addr.is_loopback or addr.is_link_local or addr.is_multicast or addr.is_reserved:
        return raw
    if raw in ("0.0.0.0", "255.255.255.255"):
        return raw
    return _fake_ip(raw)

IPV4_RE = re.compile(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")

# --- Sensitive-line patterns -------------------------------------------------
# Anything matching these gets the *value* portion redacted, not the whole
# line — so the LLM still sees the shape of your config.

REDACT_PATTERNS = [
    # SNMP communities
    (re.compile(r"(snmp-server\s+community\s+)(\S+)", re.I),      r"\1<COMMUNITY>"),
    # RADIUS / TACACS+ keys
    (re.compile(r"(\bkey\s+\d?\s*)(\S+)", re.I),                  r"\1<KEY>"),
    (re.compile(r"(radius-server\s+.*?\bkey\s+)(\S+)", re.I),     r"\1<KEY>"),
    (re.compile(r"(tacacs-server\s+.*?\bkey\s+)(\S+)", re.I),     r"\1<KEY>"),
    # IPsec / ISAKMP pre-shared keys
    (re.compile(r"(crypto\s+isakmp\s+key\s+)(\S+)", re.I),        r"\1<PSK>"),
    (re.compile(r"(pre-shared-key.*?\s)(\S+)$", re.I | re.M),     r"\1<PSK>"),
    # OSPF / EIGRP / BGP auth
    (re.compile(r"(ip\s+ospf\s+authentication-key\s+\d?\s*)(\S+)", re.I),         r"\1<KEY>"),
    (re.compile(r"(ip\s+ospf\s+message-digest-key\s+\d+\s+md5\s+)(\S+)", re.I),   r"\1<KEY>"),
    (re.compile(r"(neighbor\s+\S+\s+password\s+\d?\s*)(\S+)", re.I),              r"\1<BGP-PWD>"),
    # Local users, enable passwords, line passwords
    (re.compile(r"(username\s+\S+\s+(?:secret|password)\s+\d?\s*)(\S+)", re.I),   r"\1<SECRET>"),
    (re.compile(r"(enable\s+(?:secret|password)\s+\d?\s*)(\S+)", re.I),           r"\1<SECRET>"),
    (re.compile(r"^(\s*password\s+\d?\s*)(\S+)", re.I | re.M),                    r"\1<SECRET>"),
    # Certificate + key material — nuke the whole hex block
    (re.compile(r"(certificate\s+\w+\s+[\dA-Fa-f]+\n)([\dA-Fa-f\s]+?)(\s*quit)", re.M), r"\1  <CERT-DATA>\n\3"),
    # Wireless PSKs
    (re.compile(r"(wpa-psk\s+(?:ascii|hex)\s+\d?\s*)(\S+)", re.I),                r"\1<WPA-PSK>"),
]

# Hostnames — rename to something generic so device role doesn't leak
_seen_hostnames = {}
def _rename_hostname(match: re.Match) -> str:
    real = match.group(2)
    if real not in _seen_hostnames:
        _seen_hostnames[real] = f"RTR-{len(_seen_hostnames) + 1:02d}"
    return f"{match.group(1)}{_seen_hostnames[real]}"

HOSTNAME_RE = re.compile(r"^(hostname\s+)(\S+)", re.I | re.M)

# --- Main --------------------------------------------------------------------

def sanitize(text: str) -> str:
    # Order matters: run REDACT_PATTERNS *before* IP substitution so we
    # don't accidentally rewrite an IP that lives inside a redacted key.
    for pat, repl in REDACT_PATTERNS:
        text = pat.sub(repl, text)
    text = HOSTNAME_RE.sub(_rename_hostname, text)
    text = IPV4_RE.sub(_replace_ip, text)
    # MAC addresses — replace with the documentation OUI (00:00:5E)
    text = re.sub(
        r"\b([0-9A-Fa-f]{2}[:.-]){5}[0-9A-Fa-f]{2}\b",
        "00:00:5e:00:53:00",
        text,
    )
    text = re.sub(
        r"\b([0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4}\b",
        "0000.5e00.5300",
        text,
    )
    return text

if __name__ == "__main__":
    sys.stdout.write(sanitize(sys.stdin.read()))

Two design choices worth calling out:

  • Consistent mapping within a run. If 10.1.10.5 appears three times in the input (once as an interface IP, once as an OSPF neighbor, once as a static route next-hop), all three get mapped to the same fake IP. This preserves relationships, which is what an LLM needs to give you a useful answer. Randomizing every occurrence breaks the topology and produces useless output.
  • Redact the value, keep the shape. snmp-server community MySecret RW becomes snmp-server community <COMMUNITY> RW. The LLM still knows this line is a read-write SNMP community declaration — it just doesn’t know the string.

Ship it as a team-wide tool. Bookmark it in a shared repo. Alias it as sc in the standard shell profile. That single step converts your average leak from “complete topology” to “template with the shape.”

Prompt patterns that work

Sanitization solves half the problem. The other half is asking better questions in the first place. The rule is: ask for a template, not a diff. Templates are generic by design. Diffs require your specifics.

Instead of (leaks a lot)Try (leaks nothing)
“Fix this ACL: permit tcp host 10.10.5.7 host 172.16.42.19 eq 443 …""Cisco IOS extended ACL template that permits HTTPS from a management subnet to a web-tier subnet and logs all denies — with the standard 3-line comment header we should include."
"My OSPF neighbor is stuck at EXSTART. Here’s my running-config: …""OSPF neighbor stuck at EXSTART on a point-to-point Ethernet link — top 5 causes ranked by frequency, the show command that confirms each, and the fix for each."
"Debug this VLAN trunk config” (paste follows)“802.1Q trunk between two Catalyst 9300s in the same VTP domain isn’t passing VLAN 30 tagged traffic — walk me through the 6-step diagnostic sequence with exact show commands."
"Analyze this firewall log” (paste follows)“Give me the FortiGate log-field cheat sheet for a Deny event on a policy with srcintf, dstintf, srcip, dstip, service, action=deny — what each field means and what pattern indicates a policy mismatch vs a UTM block.”

The pattern: your specifics stay on your desk; the LLM sees the shape of the problem. You then apply the answer against the real numbers yourself, which is the part you were being paid to do anyway.

Enterprise and self-hosted options — the honest matrix

The right answer depends on your risk tolerance, budget, and whether you have a GPU cluster. There is no universal winner.

OptionData retentionWhere it runsRough costRight for
ChatGPT EnterpriseZero training, ~30-day operational logsOpenAI cloud (US)~$60/user/mo minMid-large orgs, general use
Claude for EnterpriseZero training, similar retentionAnthropic cloud (US)Similar tierMid-large orgs, prefer Claude quality
Azure OpenAIIn your Azure tenant, region-pinnedAzure cloud (regional)Az consumptionRegulated (HIPAA BAA available), Azure-centric shops
AWS BedrockIn your AWS account, region-pinnedAWS cloud (regional)Bedrock consumptionAWS-centric, multi-model
Google Vertex AI (Gemini Enterprise)In your GCP projectGCP cloud (regional)GCP consumptionGCP-centric
Self-hosted Llama 3.1 70B on OllamaZero externalYour own GPU (single A100 or 2× 4090)Hardware capexFull sovereignty, ITAR/FedRAMP, air-gapped labs
vLLM + Mistral Large / Qwen2.5Zero externalYour own cluster (multi-GPU)Hardware capexHigh-throughput internal team use
Cisco AI AssistantCisco cloud, contract-boundCisco cloudIncluded with certain SKUsCisco-heavy shops willing to be Cisco-only

Two honest observations:

Self-hosted is more accessible than it used to be. A single workstation with an RTX 4090 (24GB) will run Llama 3.1 8B or a 4-bit-quantized 70B at usable NetOps speeds. Two 4090s comfortably run a 70B at full precision. For a lot of teams, that’s a $4–8k capex that eliminates the entire compliance question. Ollama on a single Linux box behind your firewall, exposed via a small web UI, is a two-day project. It won’t match frontier-model quality for open-ended writing, but for “read this log and tell me what stands out” or “explain this OSPF LSA output,” it’s more than adequate.

Cloud enterprise is the pragmatic answer for most. For a 50-person NetOps team, negotiating an enterprise ChatGPT or Azure OpenAI contract is one afternoon of paperwork and one legal review. You get a data processing agreement (DPA), zero-training commitment, audit logging, and the ability to point at a contract when the auditor asks. That is worth an order of magnitude more than “we put up a policy.”

The pitch to management

If you’re the engineer trying to move your team off free ChatGPT, the argument that lands is not “AI is dangerous.” It’s:

“We have a control gap that appears in every current compliance framework, and the fix costs less per month than one hour of an outside auditor.”

Concretely, per user per month:

  • ChatGPT Enterprise: ~$60
  • Claude for Enterprise: comparable
  • Azure OpenAI at typical NetOps volumes: often under $30 with pooled quota

Compare to the cost of a single incident:

  • HIPAA — OCR settlements over the last five years have ranged from $50k to $16M, plus mandatory corrective action plans that consume six-figure engineering time.
  • PCI DSS — non-compliance status raises transaction rates and can trigger merchant status review; a single card-brand fine can hit $500k.
  • SOC2 — audit failure typically delays or kills enterprise sales in progress. The revenue exposure often dwarfs the annual license cost by 100×.
  • Reputational — one news story about a leaked config from your company is career-defining. Not in a good way.

Put it in a one-pager. Attach it to a ticket. Send it up.

What to do this week

  1. Ship the sanitizer to the team’s shared tools repo. Alias it, document it, get one engineer to demo it in the next standup.
  2. Publish a one-page GenAI policy. It doesn’t have to be long. What’s allowed, what’s forbidden, which channel is approved. See any of the SANS Institute policy templates as a starting shape.
  3. Do an honest audit. Ask the team, no-blame, what they’ve pasted into a public LLM in the last 30 days. You’ll be surprised. Change the numbers going forward, don’t shame the past.
  4. Approve one enterprise-safe channel. Pick the vendor that fits your existing cloud (Azure OpenAI for M365 shops, Bedrock for AWS shops, ChatGPT Enterprise or Claude for the multi-cloud). Get one contract signed.
  5. For the most sensitive fleets, plan self-hosted. A single-GPU Ollama box is a two-day proof of concept. If it works for one team, it can work for the whole org.

The question worth asking your team

Does your IT department have an official policy on sanitizing data before using GenAI, or is it currently the wild west? If you don’t know the answer, you have your answer.

The engineers who lead on this in 2026 are going to look, in retrospect, the way the engineers who insisted on HTTPS-everywhere looked around 2015: obviously right, and a couple of years too early to get credit for it. Be one of them.


If you liked this and want the sanitizer script, prompt-pattern library, and a one-page GenAI policy template pre-filled with your industry’s compliance framework, drop your email in the roadmap — everything ships in the next monthly note.

Get posts like this by email.

One short, opinionated tutorial per week. Unsubscribe in one click.

Personal reply from a senior network engineer. No third-party tracking. Unsubscribe any time.