STD-026: Network Device Interaction

All interactions with network devices — CLI and API — follow the capture-first pattern: every command produces a local record, every change has a verify-before and verify-after, and credentials never persist in output. This standard applies to IOS-XE, NX-OS, ASA, FMC, ISE, and any device managed via SSH, RESTCONF, or REST API.

Principles

  1. Capture everything locally. Every SSH session and API call produces a file on the workstation. No command runs without a local record. The operator’s terminal is the source of truth, not the device’s logs.

  2. Verify-before / change / verify-after. The same show or API GET that validates the current state runs before and after every change. Output is captured to the same file for side-by-side comparison.

  3. Credentials never persist in captures. Output files are auto-redacted on write or immediately after capture. Plaintext secrets in show running-config are redacted to <REDACTED> before the file is stored or committed.

  4. Commands live in files, not memory. Audit checks, config patches, and API payloads are stored as reusable files — not typed from memory, not pasted from chat. The file is the runbook.

  5. API and CLI are complementary, not redundant. CLI captures configuration state. APIs capture operational state (sessions, endpoints, posture, auth history). Use both — correlate across them.

Capture Methods

Method Command Use Case Output

SSH + tee

ssh -tt <host> 2>&1 | tee /tmp/<name>.txt

Interactive CLI sessions — audit, config changes

Full session: prompts + commands + output

wlc-push.sh

bash wlc-push.sh <command-file>

Automated CLI push via pexpect — audit scripts, patches

Timestamped file, auto-redacted credentials

API script + tee

bash <script.sh> table | tee /tmp/<name>.txt

ISE MnT, ERS, DataConnect, RESTCONF

Structured output: JSON, table, or raw

API script + file redirect

bash <script.sh> > /tmp/<name>.json 2>&1

Bulk API enumeration — dump to file for jq processing

Full JSON response

IOS-XE tee to flash

show run | tee flash:<name>.txt

On-device baseline before changes

Config snapshot on device flash

IOS-XE redirect to flash

show run | redirect flash:<name>.txt

Silent baseline (no terminal display)

Config snapshot on device flash

CLI Interaction Pattern

Audit (read-only)

Command files are stored at data/d000/infra/<device>-api-reference/scripts/cli/ as .txt files containing pure IOS-XE exec commands — no comments, no banners. Paste-safe.

bash $(find data/d000/infra -name 'wlc-push.sh') wlc-audit.txt --dry-run
bash $(find data/d000/infra -name 'wlc-push.sh') wlc-audit.txt

Config Change (patch)

Patch files are stored at scripts/cli/patches/ and follow this structure:

term len 0
show <verify-before command>
configure terminal
<change commands>
end
show <verify-after command>
term len 24

Rules:

  • No write memory in patch files — operator decides when to persist after reviewing output

  • show before and after every change block — verify-before/change/verify-after in one file

  • show wireless client summary before and after any policy profile change — confirm client survival

  • shutdown / no shutdown on policy profiles bounces associated clients — document impact

  • term len 0 at top, term len 24** at bottom — unpaged output for capture

Post-Change Diff (on-device)

show archive config differences flash:<baseline>.txt system:running-config

API Interaction Pattern

ISE MnT (Monitoring)

bash $(find data/d000/infra/ise-api-reference/scripts/mnt -name 'active-sessions.sh') table | tee /tmp/ise-sessions.txt
bash $(find data/d000/infra/ise-api-reference/scripts/mnt -name 'session-detail.sh') <MAC> | tee /tmp/ise-detail.json
bash $(find data/d000/infra/ise-api-reference/scripts/mnt -name 'auth-history.sh') <MAC> table | tee /tmp/ise-auth.txt

ISE ERS (Configuration)

bash $(find data/d000/infra/ise-api-reference/scripts/ers -name '<script>.sh') | tee /tmp/ise-ers.json

ISE DataConnect (SQL)

dc-run-sql $(find data/d000/infra -name '<query>.sql') | tee /tmp/dc-result.txt

WLC RESTCONF

bash $(find data/d000/infra/wlc-api-reference/scripts/restconf -name '<script>.sh') | tee /tmp/wlc-restconf.json

JSON Payloads

API payloads are always written to /tmp files — never inline:

jq -n '{name: "value"}' > /tmp/payload.json
curl -X POST -d @/tmp/payload.json ...

IOS-XE Regex Reference

IOS-XE show output modifiers support regex — not glob. Key differences from bash:

Regex Meaning Example

.

Any single character

radius.server matches radius server

.*

Any characters (zero or more)

r.*s s.*r matches radius server

*

Zero or more of preceding character

NOT a wildcard — r* means zero or more `r’s

^

Start of line

^aaa matches lines starting with aaa

$

End of line

Unreliable on IOS-XE — trailing whitespace breaks $ anchors

|

Alternation (OR)

aaa|radius matches lines starting with either

()

Grouping

^(Gi|Te|Vl).*is up matches multiple interface types

[0-9]

Character class

session-timeout.[0-9] matches timeout with a digit

[^abc]

Negated class

( 0 .*[A-Za-z]) matches Type 0 plaintext credentials

Credential Redaction

Automatic (wlc-push.sh)

The push script auto-redacts key 0, key 7, password 0, secret 0, ascii 0, server-key 7 in output files.

Manual (post-capture)

sed -i 's/\(key 7\|key 0\|password 0\|secret 0\|ascii 0\|server-key 7\|server-key 0\) [^ ]*/\1 <REDACTED>/g' /tmp/<file>.txt

Plaintext Scan

Run on-device to verify no Type 0 credentials remain:

show running-config | include ( 0 .*[A-Za-z])

Directory Structure

data/d000/infra/
├── ise-api-reference/
│   └── scripts/
│       ├── lib/ise-common.sh        # Shared: mnt(), ers(), mnt_json()
│       ├── mnt/                      # MnT API: sessions, auth, posture
│       ├── ers/                      # ERS API: endpoints, groups, devices
│       └── dc/                       # DataConnect: SQL queries
├── wlc-api-reference/
│   └── scripts/
│       ├── lib/wlc-common.sh        # Shared: wlc(), wlc_rpc(), wlc_patch()
│       ├── cli/                      # IOS-XE commands
│       │   ├── wlc-audit.txt        # 28-check audit
│       │   ├── wlc-push.sh          # Automated push via pexpect
│       │   └── patches/             # Config change files
│       └── restconf/                 # RESTCONF API scripts
└── claroty-api-reference/
    └── scripts/                      # Claroty xDome API

Credential Loading

All API scripts expect environment variables loaded via dsource:

dsource d000 dev/network/ise          # ISE MnT/ERS
dsource d000 dev/network/wlc          # WLC RESTCONF

CLI scripts (wlc-push.sh) pull credentials from gopass at runtime — never from environment.

Checklist — Before Any Network Device Interaction

  • Credentials loaded (dsource or gopass)

  • Capture method chosen (tee, wlc-push.sh, redirect)

  • Output path set (/tmp/<device>-<action>-<date>.txt)

  • For changes: patch file created with verify-before/change/verify-after

  • For changes: no write memory in patch file — persist manually after review

  • For changes: client impact assessed (show wireless client summary)

  • Post-capture: credentials redacted from output file