Allowed Protocols API

Overview

Allowed Protocols define which EAP methods are permitted for authentication. This is critical for:

  • Enabling EAP-TLS (certificate-based)

  • Enabling TEAP with EAP chaining

  • Migration from PEAP to EAP-TLS

  • Disabling weak protocols (PAP, CHAP, LEAP)

Base URL

ise-01.inside.domusdigitalis.dev:9060/ers/config/allowedprotocols

Auth

Basic Authentication

Content-Type

application/json

Setup

dsource d000 dev/network

# ERS API configuration
ISE_HOST="${ISE_PAN_IP}"
ISE_PORT="9060"
ISE_AUTH="${ISE_API_USER}:${ISE_API_PASS}"
BASE_URL="https://${ISE_HOST}:${ISE_PORT}/ers/config"

Operations

List All Allowed Protocols

netapi
# List all allowed protocols services
netapi ise ers allowed-protocols | jq -r '
  .[] |
  "\u001b[36m" + .name + "\u001b[0m │ " + .id
'
curl
# List allowed protocols (curl)
curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/allowedprotocols" \
  -H "Accept: application/json" | jq -r '
  .SearchResult.resources[] | "\(.name) │ \(.id)"
'

Check EAP Methods Enabled

# Check which EAP methods are enabled in a protocol service
PROTOCOL_NAME="Default Network Access"
netapi ise ers allowed-protocols --name "$PROTOCOL_NAME" | jq -r '
  "=== EAP Methods ===",
  "EAP-TLS:     " + (if .allowEapTls then "\u001b[32mEnabled\u001b[0m" else "\u001b[31mDisabled\u001b[0m" end),
  "PEAP:        " + (if .allowPeap then "\u001b[32mEnabled\u001b[0m" else "\u001b[31mDisabled\u001b[0m" end),
  "TEAP:        " + (if .allowTeap then "\u001b[32mEnabled\u001b[0m" else "\u001b[31mDisabled\u001b[0m" end),
  "EAP-FAST:    " + (if .allowEapFast then "\u001b[32mEnabled\u001b[0m" else "\u001b[31mDisabled\u001b[0m" end),
  "EAP-MD5:     " + (if .allowEapMd5 then "\u001b[32mEnabled\u001b[0m" else "\u001b[31mDisabled\u001b[0m" end),
  "EAP-TTLS:    " + (if .allowEapTtls then "\u001b[32mEnabled\u001b[0m" else "\u001b[31mDisabled\u001b[0m" end),
  "",
  "=== Inner Methods ===",
  "PEAP inner:  " + (.peapInnerMethods // [] | join(", ")),
  "TEAP inner:  " + (.teapInnerMethods // [] | join(", ")),
  "",
  "=== Non-EAP ===",
  "PAP:         " + (if .allowPapAscii then "\u001b[32mEnabled\u001b[0m" else "\u001b[31mDisabled\u001b[0m" end),
  "CHAP:        " + (if .allowChap then "\u001b[32mEnabled\u001b[0m" else "\u001b[31mDisabled\u001b[0m" end),
  "MS-CHAPv2:   " + (if .allowMsChapV2 then "\u001b[32mEnabled\u001b[0m" else "\u001b[31mDisabled\u001b[0m" end)
'

Audit All Protocols

# Audit all allowed protocols services for EAP method status
netapi ise ers allowed-protocols | jq -r '
  "┌────────────────────────────────┬───────┬──────┬──────┬────────┬─────┐",
  "│ Protocol Service               │ TLS   │ PEAP │ TEAP │ EAP-FAST│ MAB │",
  "├────────────────────────────────┼───────┼──────┼──────┼────────┼─────┤",
  (.[] |
    "│ " + (((.name // "") + "                              ") | .[0:30]) + " │" +
    (if .allowEapTls then " \u001b[32m✓\u001b[0m    " else " \u001b[31m✗\u001b[0m    " end) + "│" +
    (if .allowPeap then " \u001b[32m✓\u001b[0m   " else " \u001b[31m✗\u001b[0m   " end) + "│" +
    (if .allowTeap then " \u001b[32m✓\u001b[0m   " else " \u001b[31m✗\u001b[0m   " end) + "│" +
    (if .allowEapFast then " \u001b[32m✓\u001b[0m     " else " \u001b[31m✗\u001b[0m     " end) + "│" +
    (if .processHostLookup then " \u001b[32m✓\u001b[0m  " else " \u001b[31m✗\u001b[0m  " end) + "│"
  ),
  "└────────────────────────────────┴───────┴──────┴──────┴────────┴─────┘"
'

Create Allowed Protocols

EAP-TLS Only (Most Secure)

# Create an EAP-TLS only allowed protocols service (most secure)
curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/allowedprotocols" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X POST \
  -d '{
    "AllowedProtocols": {
      "name": "EAP-TLS-Only",
      "description": "Certificate-based authentication only - zero trust",
      "allowEapTls": true,
      "allowPeap": false,
      "allowTeap": false,
      "allowEapFast": false,
      "allowEapMd5": false,
      "allowEapTtls": false,
      "allowPapAscii": false,
      "allowChap": false,
      "allowMsChapV2": false,
      "allowLeap": false,
      "processHostLookup": false,
      "eapTlsLBit": false,
      "allowWeakCiphersForEap": false,
      "requireCryptobinding": true,
      "eapTlsSessionTicket": {
        "sessionTicketTtl": 2,
        "sessionTicketTtlUnits": "HOURS"
      }
    }
  }' | jq '.'

TEAP + EAP-TLS (Modern Secure)

# Create TEAP + EAP-TLS allowed protocols (modern secure)
curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/allowedprotocols" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X POST \
  -d '{
    "AllowedProtocols": {
      "name": "TEAP-EAP-TLS-Secure",
      "description": "TEAP with EAP-TLS inner method - machine+user chaining",
      "allowEapTls": true,
      "allowTeap": true,
      "allowPeap": false,
      "allowEapFast": false,
      "allowEapMd5": false,
      "allowEapTtls": false,
      "allowPapAscii": false,
      "allowChap": false,
      "allowMsChapV2": false,
      "allowLeap": false,
      "processHostLookup": false,
      "teap": {
        "allowTeapEapMsChapV2": false,
        "allowTeapEapMsChapV2PwdChange": false,
        "allowTeapEapMsChapV2PwdChangeRetries": 3,
        "allowTeapEapTls": true,
        "allowTeapEapTlsAuthOfExpiredCerts": false,
        "acceptClientCertDuringTunnelEst": true,
        "enableEapChaining": true,
        "allowDowngradeMsk": false,
        "requestBasicPwdAuth": false
      },
      "requireCryptobinding": true,
      "allowWeakCiphersForEap": false
    }
  }' | jq '.'

Migration (PEAP + EAP-TLS)

# Create transitional allowed protocols (PEAP + EAP-TLS during migration)
curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/allowedprotocols" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X POST \
  -d '{
    "AllowedProtocols": {
      "name": "Migration-PEAP-to-EAP-TLS",
      "description": "Transitional: Allow both PEAP and EAP-TLS during certificate rollout",
      "allowEapTls": true,
      "allowPeap": true,
      "allowTeap": false,
      "allowEapFast": false,
      "allowEapMd5": false,
      "allowEapTtls": false,
      "allowPapAscii": false,
      "allowChap": false,
      "allowMsChapV2": false,
      "allowLeap": false,
      "processHostLookup": false,
      "peap": {
        "allowPeapEapMsChapV2": true,
        "allowPeapEapMsChapV2PwdChange": true,
        "allowPeapEapMsChapV2PwdChangeRetries": 3,
        "allowPeapEapGtc": false,
        "allowPeapEapTls": true,
        "allowPeapEapTlsAuthOfExpiredCerts": false,
        "requireCryptobinding": true,
        "allowPeapV0": false
      },
      "eapTls": {
        "allowEapTlsAuthOfExpiredCerts": false,
        "eapTlsEnableStatelessSessionResume": true
      },
      "allowWeakCiphersForEap": false
    }
  }' | jq '.'

Update Existing Protocols

Enable TEAP

# Enable TEAP on existing allowed protocols (GET -> modify -> PUT)
PROTOCOL_NAME="Default Network Access"

# Get current config
PROTOCOL_ID=$(curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/allowedprotocols/name/${PROTOCOL_NAME// /%20}" \
  -H "Accept: application/json" | jq -r '.AllowedProtocols.id')

# Get full config, enable TEAP, PUT back
curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/allowedprotocols/${PROTOCOL_ID}" \
  -H "Accept: application/json" | jq '.AllowedProtocols |
    .allowTeap = true |
    .teap = {
      "allowTeapEapMsChapV2": false,
      "allowTeapEapTls": true,
      "enableEapChaining": true,
      "acceptClientCertDuringTunnelEst": true
    }' > /tmp/protocol-update.json

# Apply update
curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/allowedprotocols/${PROTOCOL_ID}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X PUT \
  -d "{\"AllowedProtocols\": $(cat /tmp/protocol-update.json)}" | jq '.'

Disable Weak Protocols

# Disable weak protocols (PAP, CHAP, MS-CHAPv1, LEAP)
PROTOCOL_NAME="Default Network Access"

PROTOCOL_ID=$(curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/allowedprotocols/name/${PROTOCOL_NAME// /%20}" \
  -H "Accept: application/json" | jq -r '.AllowedProtocols.id')

curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/allowedprotocols/${PROTOCOL_ID}" \
  -H "Accept: application/json" | jq '.AllowedProtocols |
    .allowPapAscii = false |
    .allowChap = false |
    .allowMsChapV1 = false |
    .allowLeap = false |
    .allowEapMd5 = false |
    .allowWeakCiphersForEap = false' > /tmp/protocol-hardened.json

curl -sk -u "${ISE_AUTH}" \
  "${BASE_URL}/allowedprotocols/${PROTOCOL_ID}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X PUT \
  -d "{\"AllowedProtocols\": $(cat /tmp/protocol-hardened.json)}" | jq '.'

Validation

Check Auth Method Adoption

# Validate auth method adoption after enabling new protocol
# Shows breakdown of auth methods used in last 24h
netapi ise dc --format json query "
  SELECT
    authentication_method as method,
    COUNT(*) as total,
    SUM(CASE WHEN passed = 1 THEN 1 ELSE 0 END) as passed,
    ROUND(SUM(CASE WHEN passed = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 1) as pct
  FROM mnt.radius_auth_48_live
  WHERE acs_timestamp > SYSDATE - 1
  GROUP BY authentication_method
  ORDER BY total DESC
" | jq -r '
  "┌────────────────┬────────┬────────┬─────────┐",
  "│ Auth Method    │  Total │ Passed │ Success │",
  "├────────────────┼────────┼────────┼─────────┤",
  (.[] |
    "│ " +
    (if .method == "EAP-TLS" then "\u001b[32m" elif .method == "TEAP" then "\u001b[32m" elif .method == "PEAP" then "\u001b[33m" else "\u001b[34m" end) +
    (((.method // "") + "              ") | .[0:14]) + "\u001b[0m │" +
    (("      " + ((.total // 0)|tostring))[-6:]) + " │" +
    (("      " + ((.passed // 0)|tostring))[-6:]) + " │" +
    (if (.pct // 0) >= 98 then "\u001b[32m" elif (.pct // 0) >= 90 then "\u001b[33m" else "\u001b[31m" end) +
    (("      " + ((.pct // 0)|tostring))[-6:]) + "%\u001b[0m │"
  ),
  "└────────────────┴────────┴────────┴─────────┘"
'

Compare Before/After

# Compare auth method distribution: yesterday vs today
# Run BEFORE enabling new protocol, save output, run AFTER to compare
netapi ise dc --format json query "
  SELECT
    CASE
      WHEN acs_timestamp > TRUNC(SYSDATE) THEN 'Today'
      ELSE 'Yesterday'
    END as period,
    authentication_method as method,
    COUNT(*) as count
  FROM mnt.radius_auth_48_live
  WHERE acs_timestamp > SYSDATE - 2
  GROUP BY
    CASE WHEN acs_timestamp > TRUNC(SYSDATE) THEN 'Today' ELSE 'Yesterday' END,
    authentication_method
  ORDER BY period, count DESC
" | jq -r '
  group_by(.period) | .[] |
  "\u001b[1m=== " + (.[0].period // "Unknown") + " ===\u001b[0m",
  "  Method     │ Count",
  "─────────────┼──────",
  (sort_by(-.count) | .[] |
    "  " + (((.method // "") + "          ") | .[0:10]) + " │ " + ((.count // 0) | tostring)
  ),
  ""
'