Day 86 – Cisco ISE Mastery Training: REST API Automation Overview

[Day 86] Cisco ISE Mastery Training: REST API Automation Overview


Table of Contents

Introduction

“Today you’ll turn Cisco ISE into an automation platform. We’ll use the ERS (External RESTful Services) API and the MnT (Monitoring) A to do real work: auto-onboard endpoints, push ANC quarantine, read live sessions, and integrate with tools like SecureX/CI/CD. By the end, you’ll have Postman, cURL, and Python examples that you can drop into production.”

You will build & validate:

  • ERS enablement, API admin & cert trust
  • Create/Read/Update/Delete (CRUD) for Endpoints & Internal Users
  • ANC automation (apply + clear) via REST
  • Live Session lookups via MnT API
  • A Postman collection + Python requests mini-SDK
  • End-to-end enforcement proof on switch/WLC (CLI + ISE logs)

Problem Statement (what breaks today)

  • NAC tasks (add endpoints, quarantine/unquarantine, bulk changes) are often manual & slow.
  • SOC tools see IPs; ISE acts on MAC/user/session. Humans copy/paste between consoles—error-prone.
  • We need repeatable APIs to integrate ISE with SOC/XDR/ITSM, reduce MTTR, and prove actions with logs.

Solution Overview (what we’ll automate)

  • ERS API (port 9060/TCP/HTTPS): Admin CRUD for ISE objects (Endpoints, Internal Users, ANC, SGTs, etc.).
  • MnT API (port 443/TCP/HTTPS): Query live sessions, RADIUS details, posture status for validation.
  • Security: Mutual TLS trust, least-privilege ERS admin, audit logs, and NTP/DNS hygiene.

We’ll keep to battle-tested APIs: endpoint, internaluser, ancendpoint (apply/clear), and MnT session lookups. These are stable across ISE 2.7–3.x.


Sample Lab Topology (VMware/EVE-NG)

Platform: VMware ESXi/Workstation or EVE-NG

Nodes:

  • ISE 3.2/3.3 (PAN+MnT+PSN; pxGrid optional, ERS enabled)
  • AD DS (for 802.1X users)
  • Catalyst 9300 (17.x) as access switch (802.1X/MAB/CoA)
  • WLC 9800-CL (wireless validation optional)
  • Windows 10/11 test endpoint (802.1X or MAB)
  • Automation Workstation (Postman + Python 3.10+)

Topology Layout:

Pre-req green checks:

  • DNS A/PTR & NTP aligned (AD/ISE/Switch)
  • RADIUS AuthC/AuthZ already working in ISE (wired; wireless optional)
  • ISE ERS enabled; ERS admin user created; test creds verified
  • Firewall permits: 9060/tcp (ERS), 443/tcp (MnT/GUI)

Step-by-Step GUI Configuration Guide (with CLI + API runbooks)

Phase 0 — Health & connectivity (CLI)

ISE CLI

show clock
show ntp
show application status ise | include (Application|pxGrid|Database|AD)
ping <switch/wlc/ip>

Switch CLI (802.1X path alive)

show authentication sessions

Phase 1 — Enable ERS & create API admin (GUI)

  1. Turn on ERS (External RESTful Services)
    GUI: Administration → System → Settings → ERS Settings → check Enable ERS for Read/WriteSave
  2. Create least-privilege ERS admin
    GUI: Administration → System → Admin Access → AdministratorsAdd
    • Username: ers-svc
    • Password: (complex)
    • Roles: ERS Admin (and MnT if you’ll call MnT API with same user)
    • Restrict IP if desired (security best practice)
  3. (Recommended) Bind proper server certificate
    GUI: Administration → System → Certificates → System Certificates
    • Use a CA-signed cert with FQDN/SAN; trust chain installed on Automation WS
  4. Open the API help page (for live reference)
    GUI: Administration → Developer Resources (or ERS API Docs link)

Phase 2 — Postman workspace (quick start)

  1. Create environment variables:
    • ISE_HOST = ise.lab.local
    • ERS_USER = ers-svc
    • ERS_PASS = <password>
    • BASE_ERS = https://{{ISE_HOST}}:9060/ers
    • BASE_MNT = https://{{ISE_HOST}}/admin/API/mnt
  2. Global headers (per request):
    • Accept: application/json
    • Content-Type: application/json

Phase 3 — “Hello API” (ERS + MnT) with cURL & Postman

cURL (ERS API status)

export ISE=ise.lab.local
curl -k -u ers-svc:'<pass>' -H "Accept: application/json" https://$ISE:9060/ers/config/endpoint

Postman: GET {{BASE_ERS}}/config/endpointSend
Expected: JSON with paging block & (possibly empty) endpoint list

cURL (MnT session by MAC)

MAC="AA:BB:CC:DD:EE:FF"
curl -k -u ers-svc:'<pass>' "https://$ISE/admin/API/mnt/Session/MACAddress/$MAC"

Expected: XML/JSON session details (user/ip/SGT) if active

Note: MnT often returns XML; set Accept: application/xml in Postman when using MnT endpoints.


Phase 4 — API Lab 1: Create an Endpoint (ERS)

Goal: Add a MAC to ISE (e.g., for MAB or inventory).

POST {{BASE_ERS}}/config/endpoint
Body (JSON):

{
  "ERSEndPoint": {
    "name": "Lab-Laptop-01",
    "mac": "AA:BB:CC:DD:EE:FF",
    "description": "Added via ERS API",
    "groupId": null,
    "staticGroupAssignment": false,
    "staticProfileAssignment": false
  }
}

Validate (GUI):
Operations → RADIUS → Live Logs (after re-auth), or Context Visibility → Endpoints

Validate (Switch CLI):

show authentication sessions interface Gi1/0/10 details

Look for Endpoint Policy hit using the new endpoint info.


Phase 5 — API Lab 2: ANC Quarantine (apply/clear) (ERS)

Create an ANC policy (if not yet):
GUI: Work Centers → Policy → Policy Elements → Results → ANC PoliciesAdd

  • Name: ANC-QUAR-dACL
  • Type: dACL (deny all except IT mgmt) or SGT quarantine

Apply ANC (ERS)
POST {{BASE_ERS}}/config/ancendpoint/apply
Body (JSON):

{
  "OperationAdditionalData": {
    "additionalData": [
      { "name": "macAddress", "value": "AA:BB:CC:DD:EE:FF" },
      { "name": "policyName", "value": "ANC-QUAR-dACL" }
    ]
  }
}

Validate (GUI):

  • Operations → Adaptive Network Control → entry shows Applied
  • Operations → RADIUS → Live LogsCoA event + new AuthZ = QUAR

Validate (Switch CLI):

show authentication sessions interface Gi1/0/10 details
! Expect dACL/SGT/VLAN updated after CoA

Clear ANC (ERS):
POST {{BASE_ERS}}/config/ancendpoint/clear
Body (JSON):

{
  "OperationAdditionalData": {
    "additionalData": [
      { "name": "macAddress", "value": "AA:BB:CC:DD:EE:FF" }
    ]
  }
}

Re-validate: switch/WLC returns to normal; ISE Live Logs show CoA Reauth.


Phase 6 — API Lab 3: Internal User (ERS)

POST {{BASE_ERS}}/config/internaluser
Body (JSON):

{
  "InternalUser": {
    "name": "api-tester",
    "password": "S0m3C0mpl3x!",
    "enabled": true,
    "changePassword": false,
    "email": "api.tester@lab.local",
    "firstName": "API",
    "lastName": "Tester",
    "description": "Created by ERS",
    "identityGroups": "User Identity Group"
  }
}

Validate (GUI): Administration → Identity Management → Identities


Phase 7 — API Lab 4: MnT Session Proof (read-only validation)

GET {{BASE_MNT}}/Session/EndPointIPAddress/{{ip}}

  • Set Accept: application/xml
  • Confirm user, MAC, device profile, AuthZ profile, SGT, ANC state

Phase 8 — Python mini-SDK (quick wins)

Run on the Automation WS (has network reachability to ISE).

import requests, sys
BASE_ERS = "https://ise.lab.local:9060/ers"
BASE_MNT = "https://ise.lab.local/admin/API/mnt"
AUTH = ("ers-svc","<password>")
verify_tls = False  # set to CA bundle path in prod
headers_json = {"Accept":"application/json","Content-Type":"application/json"}
def get_endpoints():
    r = requests.get(f"{BASE_ERS}/config/endpoint", auth=AUTH, headers=headers_json, verify=verify_tls)
    r.raise_for_status()
    return r.json()
def create_endpoint(name, mac):
    body = {"ERSEndPoint":{"name":name,"mac":mac,"description":"API created",
            "staticGroupAssignment":False,"staticProfileAssignment":False}}
    r = requests.post(f"{BASE_ERS}/config/endpoint", json=body, auth=AUTH, headers=headers_json, verify=verify_tls)
    r.raise_for_status()
    return r.headers.get("Location")
def anc_apply(mac, policy):
    body = {"OperationAdditionalData":{"additionalData":[
        {"name":"macAddress","value":mac},{"name":"policyName","value":policy}]}}
    r = requests.post(f"{BASE_ERS}/config/ancendpoint/apply", json=body, auth=AUTH, headers=headers_json, verify=verify_tls)
    r.raise_for_status()
    return True
def anc_clear(mac):
    body = {"OperationAdditionalData":{"additionalData":[{"name":"macAddress","value":mac}]}}
    r = requests.post(f"{BASE_ERS}/config/ancendpoint/clear", json=body, auth=AUTH, headers=headers_json, verify=verify_tls)
    r.raise_for_status()
    return True
def mnt_session_by_mac(mac):
    r = requests.get(f"{BASE_MNT}/Session/MACAddress/{mac}", auth=AUTH, headers={"Accept":"application/xml"}, verify=verify_tls)
    r.raise_for_status()
    return r.text
if __name__ == "__main__":
    mac = "AA:BB:CC:DD:EE:FF"
    print("Endpoints:", get_endpoints())
    print("Create:", create_endpoint("Lab-Laptop-01", mac))
    print("ANC Apply:", anc_apply(mac, "ANC-QUAR-dACL"))
    print("MnT:", mnt_session_by_mac(mac)[:300], "...")
    print("ANC Clear:", anc_clear(mac))

Validate output:

  • HTTP 201 for create (Location header with object ID)
  • ANC apply/clear return 202/204 (ISE version dependent)
  • MnT returns XML with session fields

Phase 9 — Auditing & Logs (ISE GUI + CLI)

GUI:

  • Operations → Adaptive Network Control (who applied ANC, when)
  • Operations → Reports → RADIUS AuthC/AuthZ & Change of Authorization

ISE CLI (quick tailers)

show logging application ise-psc.log | include (ANC|CoA|AuthZ)
show logging application catalina.out | include ERS

(Log filenames differ across versions; if catalina.out not present, inspect /var/log/ise/ GUI via Operations → Troubleshoot → Download Logs.)


Phase 10 — “Break & Fix” drills

  1. Wrong password in Postman → 401 → fix credentials.
  2. ERS disabled → 404/connection refused on :9060 → enable ERS.
  3. TLS fail → trust the ISE CA on the workstation or use -k in lab.
  4. ANC applied but no enforcement → check CoA in Live Logs & switch CLI; ensure AuthZ rule for UseCase: ANC is above normal rules.
  5. MnT empty → session not active or using wrong MAC; verify on switch with show auth sess.

REST API Cookbook for Cisco ISE

1. Get All Active Sessions

  • Use case: See all authenticated endpoints.
  • API:
GET https://ISE-FQDN:9060/ers/config/session
  • cURL:
curl -k -u USERNAME:PASSWORD \
"https://ISE-FQDN:9060/ers/config/session"
  • Validation: Should return list of all current sessions with usernames, MACs, IPs.

2. Get Specific Session by MAC Address

  • API:
GET https://ISE-FQDN:9060/ers/config/session/MACADDRESS
  • Validation: Confirms status (Active, Disconnected, Posture Pending).

3. Add New Endpoint to ISE (Static Entry)

  • API:
POST https://ISE-FQDN:9060/ers/config/endpoint
  • Payload (JSON):
{
  "ERSEndPoint": {
    "name": "Lab-Printer",
    "mac": "00:11:22:33:44:55",
    "staticGroupAssignment": true,
    "groupId": "SGT_ID_HERE"
  }
}
  • cURL:
curl -k -u USERNAME:PASSWORD -H "Content-Type: application/json" \
-d @endpoint.json \
"https://ISE-FQDN:9060/ers/config/endpoint"

4. Delete an Endpoint

DELETE https://ISE-FQDN:9060/ers/config/endpoint/ENDPOINT_ID
  • Validation: 204 No Content → success.

5. Get All Security Group Tags (SGTs)

GET https://ISE-FQDN:9060/ers/config/sgt
  • Returns JSON/XML list of all SGTs defined in ISE.

6. Create a New Security Group Tag (SGT)

  • Payload:
{
  "Sgt": {
    "name": "IoT-Sensors",
    "description": "For all IoT Devices",
    "value": "5001"
  }
}
  • API:
POST https://ISE-FQDN:9060/ers/config/sgt

7. Trigger Session Reauthentication (Reauth)

  • Use case: Force reauthentication after policy change.
PUT https://ISE-FQDN:9060/ers/config/session/MACADDRESS/reAuth
  • Validation: Endpoint is forced to re-authenticate.

8. Quarantine an Endpoint (via ANC Policy)

  • Step 1 – Create ANC Policy
{
  "AncPolicy": {
    "name": "Quarantine",
    "actions": ["QUARANTINE"]
  }
}
POST https://ISE-FQDN:9060/ers/config/ancpolicy
  • Step 2 – Apply Policy to Endpoint
{
  "OperationAdditionalData": {
    "additionalData": [
      {"name": "macAddress", "value": "00:11:22:33:44:55"},
      {"name": "policyName", "value": "Quarantine"}
    ]
  }
}
POST https://ISE-FQDN:9060/ers/config/ancendpoint/apply

9. Remove Quarantine Policy from Endpoint

{
  "OperationAdditionalData": {
    "additionalData": [
      {"name": "macAddress", "value": "00:11:22:33:44:55"}
    ]
  }
}
POST https://ISE-FQDN:9060/ers/config/ancendpoint/clear

10. Get All Network Devices (Switches, WLCs, Routers)

GET https://ISE-FQDN:9060/ers/config/networkdevice
  • Validation: Returns JSON list of NADs registered in ISE.

11. Add New Network Device (Switch/WLC)

{
  "NetworkDevice": {
    "name": "LAB-SW1",
    "description": "Lab Switch",
    "authenticationSettings": {
      "radiusSharedSecret": "ISEsecret123"
    },
    "tacacsSettings": {
      "sharedSecret": "ISEtacacs123"
    },
    "NetworkDeviceIPList": [
      {"ipaddress": "10.10.10.2", "mask": 32}
    ]
  }
}
POST https://ISE-FQDN:9060/ers/config/networkdevice

12. Retrieve Posture Results for Endpoint

GET https://ISE-FQDN:9060/ers/config/posture/MACADDRESS
  • Returns compliance state (Compliant / Non-Compliant / Unknown).

13. Get All Identity Groups

GET https://ISE-FQDN:9060/ers/config/identitygroup

14. Create a New Identity Group

{
  "IdentityGroup": {
    "name": "Contractors",
    "description": "Temporary users"
  }
}
POST https://ISE-FQDN:9060/ers/config/identitygroup

15. Add a User to Identity Group

{
  "User": {
    "name": "contractor1",
    "password": "Cisco123!",
    "identityGroups": "Contractors"
  }
}
POST https://ISE-FQDN:9060/ers/config/internaluser

Validation in Lab

  • Use Postman, cURL, or Python requests module.
  • Validate API calls in ISE GUI (Work Centers → pxGrid/ANC → Endpoints → SGTs).
  • CLI check:
ise/admin# show logging application ise-psc.log tail

(to confirm API transaction success).


FAQs – REST API Automation in Cisco ISE

1. What are the prerequisites before using REST APIs on ISE?

  • Ensure ERS (External RESTful Services) is enabled under Administration → System → Settings → ERS Settings.
  • Create a dedicated ERS Admin user with ERS Admin role.
  • Confirm port 9060 (ERS) and port 443 (pxGrid/ERS over TLS) are open in firewall.
  • Test basic connectivity with:
curl -k -u ersadmin:password https://ISE-FQDN:9060/ers/config/version

2. Do ISE REST APIs require HTTPS?

  • Yes. All ISE REST APIs are secured over HTTPS only.
  • Self-signed certs can be used in labs (with -k in cURL / SSL verification off in Postman).
  • In production, always use CA-signed certificates.

3. How do I test APIs quickly without coding?

  • Use Postman or Insomnia REST clients.
  • Import Cisco’s ERS API collections (Cisco DevNet provides Postman collections).
  • Validate authentication with a simple GET like:
GET /ers/config/endpoint

4. What’s the difference between XML and JSON output in ISE APIs?

  • ISE supports both JSON and XML for request and response.
  • Default: XML.
  • To request JSON, add header:
-H "Accept: application/json"
-H "Content-Type: application/json"
  • JSON is recommended for automation (Python, Ansible, etc.).

5. Why do I get “401 Unauthorized” when calling APIs?

  • Common causes:
    1. Wrong username/password.
    2. User not assigned ERS Admin role.
    3. ERS API not enabled in global settings.
    4. Using wrong port (should be 9060).

6. Can I modify policy sets or authorization rules via API?

  • No. As of ISE 3.x, REST APIs allow managing endpoints, SGTs, identity groups, ANC, sessions, network devices, but not policy sets.
  • Policy changes must be done via GUI or pxGrid APIs for dynamic enforcement.

7. How do I automate endpoint quarantine with REST APIs?

  • Workflow:
    1. Create ANC policy (POST /ers/config/ancpolicy).
    2. Apply policy to endpoint (POST /ers/config/ancendpoint/apply).
    3. Verify with GUI → Operations → ANC Policy.
  • This is often integrated with SIEM/SOAR tools.

8. How do I pull real-time session data for automation?

  • Use:
GET /ers/config/session
  • This gives endpoint session details (IP, MAC, posture state).
  • Engineers often integrate this with scripts for reporting, threat hunting, or bulk actions (like force-re-authentication).

9. Is there rate limiting or performance impact when using APIs heavily?

  • Cisco ISE does not publish strict API rate limits, but best practice:
    • Avoid more than 10–15 API calls per second per node.
    • Use bulk APIs where available (e.g., exporting endpoints instead of looping individually).
    • Monitor ISE CPU/memory via show application status ise.

10. What tools/languages do engineers typically use with ISE APIs?

  • Python with requests module (most common).
  • Postman/Insomnia for testing.
  • Ansible for declarative automation.
  • SOAR/SIEM platforms (like Splunk Phantom, Palo Alto XSOAR, SecureX) integrate via ISE REST APIs.

YouTube Link

For more in-depth Cisco ISE Mastery Training, subscribe to my YouTube channel Network Journey and join my instructor-led classes for hands-on, real-world ISE experience

[NEW COURSE ALERT] CISCO ISE (Identity Service Engine) by Sagar Dhawan
CCIE Security v6.1 Training – Ticket#1 Discussed
CCIE Security v6.1 – MAC Authentication Bypass (MAB) in Cisco ISE
CCNP to CCIE SECURITY v6.1 – New Online Batch

Closing Notes

  • Treat ISE as a platform: ERS for action, MnT for truth.
  • Automate quarantine & rollback—and prove it with MnT + switch CLI.
  • Harden: CA-signed certs, least-privilege ERS accounts, IP restrictions, and logs shipped to SIEM.

Upgrade Your Skills – Start Today

“For more in-depth Cisco ISE Mastery Training, subscribe to my YouTube channel Network Journey and join my instructor-led classes.

Fast-Track to Cisco ISE Mastery Pro — (4-month live cohort).

Enroll Now & Future‑Proof Your Career
Emailinfo@networkjourney.com
WhatsApp / Call: +91 97395 21088