ISE Policy Migration Runbook

Executive Summary

This runbook documents the migration of ISE policy sets from legacy naming to a standardized Domus_* convention. The migration includes:

  • Policy set consolidation (4 → 2)

  • Allowed protocols separation: MAB vs Certificate-based

  • Domus_HOST_ONLY = MAB (processHostLookup) only

  • Domus_TEAP_TLS_TTLS = EAP-TLS + EAP-TEAP + EAP-TTLS

Mission: Use netapi to recreate policy sets, validate against current config, then cut over.

ISE Policy Migration Workflow
Figure 1. Migration Workflow Overview

Current State Audit

Policy Sets

Run the following commands to capture current state before making changes.

List All Policy Sets

netapi ise get-policy-sets
Table 1. Current Policy Sets (from netapi ise get-policy-sets)
# Policy Set Name ID Status

1

Domus-Wired MAB

6d941893-bfeb-4acf-8005-c54c3a098cd0

enabled → migrate to Domus_MAB

2

Domus-Wired 802.1X

2c2e6b05-a29c-46a4-a0ee-7fcea4853e47

enabled → migrate to Domus_8021X

3

Domus-Secure 802.1X

9557d91c-591b-4d8d-9898-657a62f28d76

enabled → migrate to Domus_8021X

4

Domus-IoT iPSK

64e93c0e-2ce5-490b-a9da-f10daf2784bb

enabled → migrate to Domus_MAB

5

Default

3a7f1206-d371-42fe-a845-cd3460535b6e

enabled (keep as fallback)

Policy Set Details

# Authentication rules (authc = get-auth-rules)
netapi ise authc "Domus-Wired MAB"
netapi ise authc "Domus-Wired 802.1X"
netapi ise authc "Domus-Secure 802.1X"
netapi ise authc "Domus-IoT iPSK"

# Authorization rules (authz = get-authz-rules)
netapi ise authz "Domus-Wired MAB"
netapi ise authz "Domus-Wired 802.1X"
netapi ise authz "Domus-Secure 802.1X"
netapi ise authz "Domus-IoT iPSK"

Authorization Profiles

netapi ise get-authz-profiles
Table 2. Current Authorization Profiles (Legacy - to be replaced)
Profile Name VLAN dACL Description

Linux_EAPTLS_Permit

40

TBD

Linux cert-based access → Domus_Profile_Research

Research_Onboard

40

TBD

Research onboarding → Domus_Profile_Quarantine

Domus_Secure_Profile

10

None

Wireless secure → Domus_Profile_User

Trusted_LAN_VLAN10

10

TBD

Trusted LAN → Domus_Profile_User

DenyAccess

-

-

Default deny (keep)

Table 3. New Authorization Profiles (Domus_* naming)
Profile Name VLAN dACL Description

Domus_Profile_Admin

10

Domus_dACL_Admin

Domain admins - full access

Domus_Profile_Research

40

Domus_dACL_Research

Research users - VLAN 40

Domus_Profile_User

10

Domus_dACL_User

Standard domain users

Domus_Profile_IoT

30

Domus_dACL_IoT

IoT devices - restricted

Domus_Profile_AP

10

-

Access points - trunk native

Domus_Profile_Quarantine

99

Domus_dACL_Quarantine

Posture remediation

Downloadable ACLs (dACLs)

netapi ise get-dacls
Table 4. Current dACLs (Legacy - audit before migration)
dACL Name Purpose

Audit current dACLs with `netapi ise get-dacls`

Document before migration

Table 5. New dACLs (Domus_* naming)
dACL Name Purpose

Domus_dACL_Admin

Full access for domain admins

Domus_dACL_Research

Research network access

Domus_dACL_User

Standard user network access

Domus_dACL_IoT

IoT restricted - local LAN only

Domus_dACL_Quarantine

Quarantine - DHCP/DNS/HTTPS only for posture

Allowed Protocols

Zero-Trust Gap Identified: Current allowed protocols may include legacy methods (PEAP, EAP-MD5, etc.) that weaken zero-trust posture.

For true zero-trust, only EAP-TLS should be permitted on certificate-based policy sets.

# List allowed protocols
netapi ise get-allowed-protocols

Target State Design

Policy Set Comparison
Figure 2. Policy Set Migration: Old to New

New Policy Set Naming Convention

Policy sets are unified across wired and wireless - no need to duplicate by medium.

Allowed Protocols

Key Distinction:

  • Domus_HOST_ONLY = MAB (processHostLookup) - NO EAP methods

  • Domus_TEAP_TLS_TTLS = Certificate auth - EAP-TLS + EAP-TEAP + EAP-TTLS

Allowed Protocols Methods Use Case

Domus_HOST_ONLY

processHostLookup (MAB) only

IoT, APs, printers (static MAC)

Domus_TEAP_TLS_TTLS

EAP-TLS, EAP-TEAP, EAP-TTLS

Linux certs, Windows TEAP, smart printers

Policy Sets

Policy Set Uses Allowed Protocols Condition Replaces

Domus_MAB

Domus_HOST_ONLY

Service-Type = Call Check

Domus-Wired MAB, Domus-IoT iPSK

Domus_8021X

Domus_TEAP_TLS_TTLS

Service-Type = Framed

Domus-Wired 802.1X, Domus-Secure 802.1X

Allowed Protocols Configuration

Allowed Protocols Comparison
Figure 3. Zero-Trust vs Legacy Allowed Protocols

Zero-Trust Allowed Protocols (EAP-TLS Only)

Name: Domus_ZeroTrust_Protocols

Allowed Methods:
  [x] EAP-TLS
  [ ] PEAP (DISABLED - password-based)
  [ ] EAP-FAST (DISABLED)
  [ ] EAP-MD5 (DISABLED - insecure)
  [ ] PAP/ASCII (DISABLED)
  [ ] CHAP (DISABLED)
  [ ] MS-CHAPv1 (DISABLED)
  [ ] MS-CHAPv2 (DISABLED)

EAP-TLS Settings:
  [x] Allow EAP-TLS
  [x] Enable Stateless Session Resume
  Client Certificate Required: Yes
# Create zero-trust allowed protocols
netapi ise create-allowed-protocols "Domus_ZeroTrust_Protocols" \
  --eap-tls \
  --no-peap \
  --no-eap-fast \
  --no-eap-md5 \
  --description "Zero-trust: EAP-TLS certificate authentication only"

Authorization Rules (Per Policy Set)

Domus_8021X Authorization Rules (Certificate-Based)

Rank Rule Name Condition Profile

1

Domus_Cert_Admins

CERTIFICATE:Subject-OU contains "Domus-Admins"

Domus_Profile_Admin

2

Domus_Cert_Research

CERTIFICATE:Subject-OU contains "Research"

Domus_Profile_Research

3

Domus_Cert_Users

CERTIFICATE:Subject-OU contains "Domus-Users"

Domus_Profile_User

4

Domus_Windows_TEAP

EapChainingResult = User and machine both succeeded

Domus_Profile_User

99

Domus_Default_Deny

(default)

DenyAccess

Domus_MAB Authorization Rules (Endpoint Identity Groups)

Rank Rule Name Condition Profile

1

Domus_Trusted_APs

EndPoints:LogicalProfile = 'Trusted_Access_Points'

Domus_Profile_AP

2

Domus_MGMT_Devices

IdentityGroup:Name = 'MGMT_DEVICES'

Domus_Profile_Admin

3

Domus_IoT_Devices

IdentityGroup:Name = 'IoT_Devices'

Domus_Profile_IoT

4

Domus_Research_Onboard

IdentityGroup:Name = 'Research_Onboard'

Domus_Profile_Quarantine

99

Domus_MAB_Default_Deny

(default)

DenyAccess

Migration Procedure

Phase 1: Create New Resources (Parallel)

New resources are created alongside existing ones. No impact to production.

1.1 Create Allowed Protocols

Domus_HOST_ONLY = MAB only (processHostLookup). NO EAP methods.

Domus_TEAP_TLS_TTLS = Certificate-based authentication:

  • EAP-TLS = Linux machine certs (domus-root-ca)

  • EAP-TEAP = Windows machine+user chaining

  • EAP-TTLS = Smart printers with cert support

# MAB only - NO EAP flags = host-lookup only (default)
netapi ise create-allowed-protocols "Domus_HOST_ONLY" \
  -d "MAB only - IoT, APs, printers, static MAC devices"

# Certificate-based (EAP-TLS + TEAP + TTLS)
netapi ise create-allowed-protocols "Domus_TEAP_TLS_TTLS" \
  --eap-tls \
  --eap-teap \
  --eap-ttls \
  -d "Cert auth: Linux TLS, Windows TEAP, Printer TTLS"

# CRITICAL: Disable host lookup on cert protocol (created with it ON by default)
netapi ise update-allowed-protocols "Domus_TEAP_TLS_TTLS" --no-host-lookup

# Set EAP-TLS as preferred protocol
netapi ise update-allowed-protocols "Domus_TEAP_TLS_TTLS" \
  --preferred-eap EAP_TLS \
  --enable-preferred

Verify allowed protocols after creation:

# Domus_HOST_ONLY should have: processHostLookup=true, all EAP=false
netapi ise --format json get-allowed-protocol "Domus_HOST_ONLY" | \
  jq '{processHostLookup, allowEapTls, allowPeap}'

# Domus_TEAP_TLS_TTLS should have: processHostLookup=false, EAP methods=true
netapi ise --format json get-allowed-protocol "Domus_TEAP_TLS_TTLS" | \
  jq '{processHostLookup, allowEapTls, allowEapTtls, allowTeap}'

Valid preferred EAP values: EAP_TLS, EAP_FAST, EAP_TTLS, PEAP, TEAP, LEAP, EAP_MD5

The preferred protocol must be enabled in the allowed protocols config.

1.2 Create New dACLs

New dACLs with Domus_ prefix for testing netapi coverage and clean separation from legacy.

# Admin full access
netapi ise create-dacl "Domus_dACL_Admin" \
  -d "Full access for domain admins" \
  --acl "permit ip any any"

# Research limited access (VLAN 40)
netapi ise create-dacl "Domus_dACL_Research" \
  -d "Research network access - limited scope" \
  --acl "permit ip any any"

# User standard access
netapi ise create-dacl "Domus_dACL_User" \
  -d "Standard user network access" \
  --acl "permit ip any any"

# IoT restricted access
netapi ise create-dacl "Domus_dACL_IoT" \
  -d "IoT restricted - local LAN only" \
  --acl "permit ip any 10.50.0.0 0.0.255.255; deny ip any any"

# Onboarding quarantine (semicolon-separated ACL lines)
netapi ise create-dacl "Domus_dACL_Quarantine" \
  -d "Quarantine - DHCP/DNS only for posture" \
  --acl "permit udp any any eq 67; permit udp any any eq 68; permit udp any any eq 53; permit tcp any any eq 443; deny ip any any"

1.3 Create New Authorization Profiles

VLAN names must match your switch config, not numeric IDs!

Check your switch VLAN names first:

ssh admin@switch "show vlan brief"

Common VLAN names: DATA_VLAN, RESEARCH_VLAN, IOT_VLAN, QUARANTINE_VLAN

# Admin profile (DATA_VLAN, full access)
netapi ise create-authz-profile "Domus_Profile_Admin" \
  --vlan DATA_VLAN \
  --dacl "Domus_dACL_Admin" \
  --descr "Domain admins - full access"

# Research profile (RESEARCH_VLAN, research access)
netapi ise create-authz-profile "Domus_Profile_Research" \
  --vlan RESEARCH_VLAN \
  --dacl "Domus_dACL_Research" \
  --descr "Research users - VLAN 40 access"

# User profile (DATA_VLAN, standard access)
netapi ise create-authz-profile "Domus_Profile_User" \
  --vlan DATA_VLAN \
  --dacl "Domus_dACL_User" \
  --descr "Standard domain users"

# IoT profile (IOT_VLAN, restricted)
netapi ise create-authz-profile "Domus_Profile_IoT" \
  --vlan IOT_VLAN \
  --dacl "Domus_dACL_IoT" \
  --descr "IoT devices - restricted access"

# AP profile (DATA_VLAN, for access points - no dACL for wireless)
netapi ise create-authz-profile "Domus_Profile_AP" \
  --vlan DATA_VLAN \
  --descr "Access points - trunk native VLAN"

# Quarantine profile (QUARANTINE_VLAN, posture remediation)
netapi ise create-authz-profile "Domus_Profile_Quarantine" \
  --vlan QUARANTINE_VLAN \
  --dacl "Domus_dACL_Quarantine" \
  --descr "Quarantine for posture remediation"
Configure Reauthentication Timer

Set 8-hour reauth timer (28800 seconds) on all authorization profiles.

This ensures endpoints reauthenticate periodically, allowing policy changes to take effect without manual intervention.

# Update all Domus profiles with 8-hour reauth timer
for profile in Domus_Admin_Profile Domus_BYOD_Full_Access Domus_BYOD_Provisioning \
               Domus_Guest_Hotspot_Redirect Domus_Guest_Profile Domus_IoT_Profile \
               Domus_Research_Profile Domus_Secure_Profile Domus_Voice_Profile; do
  echo "Updating $profile..."
  netapi ise update-authz-profile "$profile" --reauth-timer 28800
done

Or individually:

netapi ise update-authz-profile "Domus_Admin_Profile" --reauth-timer 28800
netapi ise update-authz-profile "Domus_Secure_Profile" --reauth-timer 28800
netapi ise update-authz-profile "Domus_Research_Profile" --reauth-timer 28800
netapi ise update-authz-profile "Domus_IoT_Profile" --reauth-timer 28800

Reauth timer options:

  • --reauth-timer 28800 = 8 hours (recommended for production)

  • --reauth-timer 3600 = 1 hour (for testing)

  • --reauth-connectivity RADIUS_REQUEST = Default, sends RADIUS request on reauth

1.4 Create New Policy Sets

Unified policy sets - no separate wired/wireless. NAD handles medium; ISE handles identity.

# MAB policy set (IoT, APs, static MAC devices)
# Condition: Service-Type = Call Check (MAB request from switch)
netapi ise create-policy-set "Domus_MAB" \
  --allowed-protocols "Domus_HOST_ONLY" \
  --condition-attr "Service-Type" \
  --condition-value "Call Check" \
  -d "MAB - IoT, APs, printers, static MAC"

# 802.1X policy set (certificate-based auth)
# Condition: Service-Type = Framed (EAP request from supplicant)
netapi ise create-policy-set "Domus_8021X" \
  --allowed-protocols "Domus_TEAP_TLS_TTLS" \
  --condition-attr "Service-Type" \
  --condition-value "Framed" \
  -d "802.1X - EAP-TLS/TEAP/TTLS certificate auth"

1.5 Fix MAB Authentication Rule

CRITICAL: The default MAB auth rule uses All_User_ID_Stores with REJECT on not-found, which blocks unknown MACs!

Must change to:

  • Identity Source: Internal Endpoints

  • If Not Found: CONTINUE (allows unknown MACs to proceed to authorization)

netapi limitation: add-auth-rule defaults to EAP-TLS condition and update-auth-rule cannot change identity source. Use direct API call:

# Get the policy set ID and Default rule ID
POLICY_ID=$(netapi ise --format json get-policy-sets | jq -r '.[] | select(.name=="Domus_MAB") | .id')
RULE_ID=$(netapi ise --format json authc "Domus_MAB" | jq -r '.[0].rule.id')

# Update Default auth rule via direct API
curl -s -k -X PUT "https://${ISE_PAN_IP}/api/v1/policy/network-access/policy-set/${POLICY_ID}/authentication/${RULE_ID}" \
  -H "Authorization: Basic $(echo -n ${ISE_API_USER}:${ISE_API_PASS} | base64)" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "rule": {
      "default": true,
      "name": "Default",
      "rank": 0,
      "state": "enabled",
      "condition": null
    },
    "identitySourceName": "Internal Endpoints",
    "ifAuthFail": "REJECT",
    "ifUserNotFound": "CONTINUE",
    "ifProcessFail": "DROP"
  }'

# Verify the fix
netapi ise authc "Domus_MAB"
# Should show: Identity Source = Internal Endpoints, If Not Found = CONTINUE

1.6 Add Authorization Rules

Certificate Fields from domus-root-ca:

Certs issued by Vault PKI include these fields for authorization:

  • O=Domus Digitalis - Organization

  • OU=Domus-Admins - Admin workstations

  • OU=Research-Users - Research workstations

  • OU=Domus-Users - Standard user workstations

ISE Certificate Dictionary Requirements (netapi tested):

The CERTIFICATE dictionary is only available for authorization rules when:

  1. Authentication rule with certificate profile exists first - The policy set must have an authentication rule that uses a certificate authentication profile (e.g., AD_Cert_Profile)

  2. Use Subject - Organization not Subject - Organizational Unit - Despite ISE GUI showing "Subject - Organizational Unit", the API requires Subject - Organization for the O= field

  3. Combine with EapAuthentication condition - Use AND condition:

    --and "Network Access:EapAuthentication:EAP-TLS" \
    --and "CERTIFICATE:Subject - Organization:contains:Domus"

Example auth rule (required first):

netapi ise add-auth-rule "Domus_8021X" "EAP_TLS_CertAuth" "AD_Cert_Profile" \
  --dict "Network Access" --attr "EapAuthentication" --value "EAP-TLS" --rank 0

Then authz rule works:

netapi ise add-authz-rule "Domus_8021X" "Domus_Cert_Research" "Domus_Research_Profile" \
  --and "Network Access:EapAuthentication:EAP-TLS" \
  --and "CERTIFICATE:Subject - Organization:contains:Domus"
Domus_8021X Authorization Rules (Certificate-Based)

Rule order matters! Specific rules first, general fallback last.

  • Specific O= equals rules at top (exact match)

  • TEAP chaining rules for Windows

  • General O contains rules (broader match)

  • EAP_TLS_Permit fallback (prevents blocking valid certs)

  • Default DenyAccess

# Specific O= matches (exact - higher priority)
netapi ise add-authz-rule "Domus_8021X" "Domus_Cert_Infra_Specific" "Domus_Admin_Profile" \
  --and "Network Access:EapAuthentication:EAP-TLS" \
  --and "CERTIFICATE:Subject - Organization:equals:Domus-Infrastructure"

netapi ise add-authz-rule "Domus_8021X" "Domus_Cert_Research_Specific" "Domus_Research_Profile" \
  --and "Network Access:EapAuthentication:EAP-TLS" \
  --and "CERTIFICATE:Subject - Organization:equals:Domus-Research"

# TEAP chaining rules (Windows machine+user auth)
netapi ise add-authz-rule "Domus_8021X" "Domus_TEAP_Machine_Only" "Domus_Secure_Profile" \
  --and "Network Access:EapTunnel:TEAP" \
  --and "Network Access:EapChainingResult:User failed and machine succeeded"

netapi ise add-authz-rule "Domus_8021X" "Domus_TEAP_Chaining" "Domus_Secure_Profile" \
  --and "Network Access:EapTunnel:TEAP" \
  --and "Network Access:EapChainingResult:User and machine both succeeded"

# General O contains matches (broader - lower priority)
netapi ise add-authz-rule "Domus_8021X" "Domus_Cert_Admins" "Domus_Admin_Profile" \
  --and "Network Access:EapAuthentication:EAP-TLS" \
  --and "CERTIFICATE:Subject - Organization:contains:Infrastructure"

netapi ise add-authz-rule "Domus_8021X" "Domus_Cert_Research" "Domus_Research_Profile" \
  --and "Network Access:EapAuthentication:EAP-TLS" \
  --and "CERTIFICATE:Subject - Organization:contains:Domus"

netapi ise add-authz-rule "Domus_8021X" "Domus_Cert_Users" "Domus_Secure_Profile" \
  --and "Network Access:EapAuthentication:EAP-TLS" \
  --and "CERTIFICATE:Subject - Organization:contains:Digitalis"

# BYOD devices (CN contains "byod" - no O= field in cert)
netapi ise add-authz-rule "Domus_8021X" "Domus_BYOD_Devices" "Domus_Secure_Profile" \
  --and "Network Access:EapAuthentication:EAP-TLS" \
  --and "CERTIFICATE:Subject - Common Name:contains:byod"

# FALLBACK: Any valid EAP-TLS gets PermitAccess (prevents blocking)
netapi ise add-authz-rule "Domus_8021X" "EAP_TLS_Permit" "PermitAccess" \
  --and "Network Access:EapAuthentication:EAP-TLS"

Vault PKI roles should issue certs with:

  • O=Domus-Infrastructure → Admin profile

  • O=Domus-Research → Research profile

  • O=Domus Digitalis → User profile (general)

  • CN=<device>.byod.<domain> → BYOD profile (no O= needed)

Domus_MAB Authorization Rules (Endpoint Identity Groups)
# Trusted Access Points
netapi ise add-authz-rule "Domus_MAB" "Domus_Trusted_APs" "Domus_Secure_Profile" \
  --and "IdentityGroup:Name:equals:Endpoint Identity Groups:Trusted_Access_Points"

# Management Devices (switches, UPS, NAS, etc.)
netapi ise add-authz-rule "Domus_MAB" "Domus_MGMT_Devices" "Domus_Admin_Profile" \
  --and "IdentityGroup:Name:equals:Endpoint Identity Groups:MGMT_DEVICES"

# Printers
netapi ise add-authz-rule "Domus_MAB" "Domus_Printers" "Domus_IoT_Profile" \
  --and "IdentityGroup:Name:equals:Endpoint Identity Groups:DOMUS_Printers"

# Storage devices
netapi ise add-authz-rule "Domus_MAB" "Domus_Storage" "Domus_Admin_Profile" \
  --and "IdentityGroup:Name:equals:Endpoint Identity Groups:STORAGE"

# Research onboarding (quarantine for posture)
netapi ise add-authz-rule "Domus_MAB" "Domus_Research_Onboard" "Research_Onboard" \
  --and "IdentityGroup:Name:equals:Endpoint Identity Groups:Research_Onboard"

MAB rules use existing endpoint identity groups. The Default rule (DenyAccess) is automatic.

Unknown MACs proceed to authorization due to If Not Found = CONTINUE in auth rule.

Phase 2: Validation

2.1 Verify New Resources Created

# List all dACLs - verify Domus_dACL_* exist
netapi ise get-dacls | grep Domus_

# List all authorization profiles - verify Domus_Profile_* exist
netapi ise get-authz-profiles | grep Domus_

# List all allowed protocols - verify Domus_HOST_ONLY and Domus_TEAP_TLS_TTLS
netapi ise get-allowed-protocols | grep Domus_

# List policy sets - verify Domus_MAB and Domus_8021X
netapi ise get-policy-sets

2.2 Compare Policy Sets

# Compare old 802.1X vs new Domus_8021X
echo "=== OLD: Domus-Wired 802.1X ==="
netapi ise authz "Domus-Wired 802.1X"

echo "=== OLD: Domus-Secure 802.1X ==="
netapi ise authz "Domus-Secure 802.1X"

echo "=== NEW: Domus_8021X ==="
netapi ise authz "Domus_8021X"

# Compare old MAB vs new Domus_MAB
echo "=== OLD: Domus-Wired MAB ==="
netapi ise authz "Domus-Wired MAB"

echo "=== OLD: Domus-IoT iPSK ==="
netapi ise authz "Domus-IoT iPSK"

echo "=== NEW: Domus_MAB ==="
netapi ise authz "Domus_MAB"

2.3 Test with Single Device (modestus-aw)

# Trigger authentication from test workstation
# (on modestus-aw): sudo systemctl restart wpa_supplicant

# Check authentication result via DataConnect
netapi ise dc query "SELECT TIMESTAMP, POLICY_SET_NAME, AUTHORIZATION_RULE, AUTHORIZATION_PROFILE, PASSED FROM RADIUS_AUTHENTICATIONS WHERE CALLING_STATION_ID = '14:F6:D8:7B:31:80' ORDER BY TIMESTAMP DESC FETCH FIRST 5 ROWS ONLY"

# Verify certificate OU was matched
netapi ise dc query "SELECT TIMESTAMP, SUBJECT_COMMON_NAME, SUBJECT_ORGANIZATIONAL_UNIT, POLICY_SET_NAME FROM RADIUS_AUTHENTICATIONS WHERE CALLING_STATION_ID = '14:F6:D8:7B:31:80' ORDER BY TIMESTAMP DESC FETCH FIRST 3 ROWS ONLY"

2.4 Verify Certificate Conditions

Confirm the certificate OU from domus-root-ca is being read correctly by ISE:

  • OU=Domus-Admins → should match Domus_Cert_Admins rule

  • OU=Research-Users → should match Domus_Cert_Research rule

  • OU=Domus-Users → should match Domus_Cert_Users rule

# Check RADIUS auth details for OU matching
netapi ise dc query "SELECT SUBJECT_ORGANIZATIONAL_UNIT, AUTHORIZATION_RULE, PASSED FROM RADIUS_AUTHENTICATIONS WHERE PASSED = 1 AND EAP_TYPE = 'EAP-TLS' ORDER BY TIMESTAMP DESC FETCH FIRST 10 ROWS ONLY"

2.5 Verify Local Certificate Fields

Before testing 802.1X, verify the certificate subject fields that ISE will use for rule matching:

# Extract certificate subject fields with awk
CERT_FILE="/etc/ssl/certs/<hostname>-eaptls.pem"
openssl x509 -in "$CERT_FILE" -noout -subject | \
  awk -F', ' '{gsub(/^subject=/, "", $1); for(i=1;i<=NF;i++) print $i}'
Example (modestus-razer)
openssl x509 -in /etc/ssl/certs/modestus-razer-eaptls.pem -noout -subject | \
  awk -F', ' '{gsub(/^subject=/, "", $1); for(i=1;i<=NF;i++) print $i}'
Expected output
O=Domus-Infrastructure
OU=Domus-Admins
CN=modestus-razer.inside.domusdigitalis.dev

ISE matches on the O= field (Subject - Organization), not OU= (Subject - Organizational Unit).

The ISE API rejects Subject - Organizational Unit in conditions, so authorization rules use O= values:

  • O=Domus-InfrastructureDomus_Cert_Infra_Specific → Admin profile

  • O=Domus-ResearchDomus_Cert_Research_Specific → Research profile

  • O=Domus Digitalis (contains) → Domus_Cert_Users → User profile

2.6 Test Wired 802.1X Connection

Find Wired 802.1X Connection Name
# List all wired connections with 802.1X configured
nmcli -t conn show | awk -F: '/ethernet/ {print $1}' | while read c; do
  nmcli conn show "$c" 2>/dev/null | grep -q "802-1x.eap" && echo "$c"
done
# Get first wired connection and verify 802.1X is configured
CONN=$(nmcli -t -f NAME,TYPE conn show | awk -F: '/ethernet/ {print $1; exit}')
nmcli conn show "$CONN" | awk '/802-1x.eap/ {print "802.1X:", $2}'
Monitor Authentication (Terminal 1)
# Watch NetworkManager and wpa_supplicant logs with key events filtered
journalctl -f -u NetworkManager -u wpa_supplicant | awk '
/SUCCESS|COMPLETED/ {print "\033[32m" $0 "\033[0m"; next}
/FAIL|ERROR|reason=/ {print "\033[31m" $0 "\033[0m"; next}
/EAP-TLS|EAPOL|802.1X/ {print "\033[33m" $0 "\033[0m"; next}
{print}
'

Or minimal output:

journalctl -f -u NetworkManager -u wpa_supplicant | awk '/CTRL-EVENT|EAP:/'
Connect (Terminal 2)
# Get connection name and connect
CONN=$(nmcli -t conn show | awk -F: '/ethernet/ {print $1}' | while read c; do
  nmcli conn show "$c" 2>/dev/null | grep -q "802-1x.eap" && echo "$c"
done | head -1)

nmcli conn up "$CONN"
Verify ISE Session (Terminal 3)
# Get wired MAC address
MAC=$(ip link show enp86s0 | awk '/ether/{print $2}')
echo "Wired MAC: $MAC"
# Check ISE authentication status (requires dsec credentials loaded)
netapi ise mnt auth-status "$MAC"
# DataConnect query for auth details
netapi ise dc query "SELECT POLICY_SET_NAME, AUTHORIZATION_RULE, AUTHORIZATION_PROFILES, PASSED FROM RADIUS_AUTHENTICATIONS WHERE CALLING_STATION_ID LIKE '%${MAC: -8}%' ORDER BY TIMESTAMP DESC FETCH FIRST 3 ROWS ONLY"
Example: Successful Wired 802.1X Authentication
NetworkManager logs (color-coded awk output)
Feb 16 21:41:13 modestus-razer NetworkManager[4979]: <info> device (enp130s0): supplicant interface state: associated -> completed
Feb 16 21:41:13 modestus-razer NetworkManager[4979]: <info> device (enp130s0): Activation: (ethernet) Stage 2 of 5 (Device Configure) successful.
Feb 16 21:41:13 modestus-razer NetworkManager[4979]: <info> dhcp4 (enp130s0): state changed new lease, address=10.50.1.200
Feb 16 21:41:13 modestus-razer NetworkManager[4979]: <info> device (enp130s0): Activation: successful, device activated.
Feb 16 21:41:13 modestus-razer NetworkManager[4979]: <info> manager: NetworkManager state is now CONNECTED_GLOBAL
One-liner: Get MAC and verify ISE session
MAC=$(ip link show enp130s0 | awk '/ether/{print $2}') && netapi ise mnt auth-status "$MAC"
Expected output
                                       Auth Status: 98:bb:1e:1f:a7:13
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Time                          ┃ Status ┃ Username                        ┃ AuthZ Profile       ┃ Failure ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ 2026-02-16T21:42:07.393-08:00 │ true   │ modestus-razer.inside.domusdig… │ Domus_Admin_Profile │         │
└───────────────────────────────┴────────┴─────────────────────────────────┴─────────────────────┴─────────┘
Table 6. Validated: Both Wired and Wireless
Interface MAC Policy Set AuthZ Rule Profile

Wireless

70:15:FB:F8:47:EC

Domus_8021X

Domus_Cert_Infra_Specific

Domus_Admin_Profile

Wired

98:bb:1e:1f:a7:13

Domus_8021X

Domus_Cert_Infra_Specific

Domus_Admin_Profile

Both interfaces use the same certificate (O=Domus-Infrastructure) and hit the same zero-trust authorization rule.

Phase 3: Cutover

Pre-cutover checklist:

  • All Domus_* dACLs created

  • All Domus_Profile_* authorization profiles created

  • Domus_HOST_ONLY and Domus_TEAP_TLS_TTLS allowed protocols created

  • Domus_MAB and Domus_8021X policy sets created with rules

  • Test device (modestus-aw) validated with Domus_8021X

3.1 Disable Old Policy Sets

# Disable in order (least impactful first)
netapi ise update-policy-set "Domus-IoT iPSK" --state disabled
netapi ise update-policy-set "Domus-Wired MAB" --state disabled
netapi ise update-policy-set "Domus-Secure 802.1X" --state disabled
netapi ise update-policy-set "Domus-Wired 802.1X" --state disabled

3.2 Verify New Policy Sets Active

netapi ise get-policy-sets

# Expected output:
# ┌─────────────┬──────────┬───────────────────────┐
# │ Policy Set  │ State    │ Allowed Protocols     │
# ├─────────────┼──────────┼───────────────────────┤
# │ Domus_MAB   │ enabled  │ Domus_HOST_ONLY       │
# │ Domus_8021X │ enabled  │ Domus_TEAP_TLS_TTLS   │
# │ Default     │ enabled  │ Default Network Access│
# └─────────────┴──────────┴───────────────────────┘

3.3 Monitor Authentication Attempts

# Watch for failed authentications after cutover
netapi ise dc query "SELECT TIMESTAMP, CALLING_STATION_ID, POLICY_SET_NAME, FAILURE_REASON, PASSED FROM RADIUS_AUTHENTICATIONS WHERE TIMESTAMP > SYSDATE - INTERVAL '10' MINUTE ORDER BY TIMESTAMP DESC FETCH FIRST 20 ROWS ONLY"

# Check which policy sets are being hit
netapi ise dc query "SELECT POLICY_SET_NAME, COUNT(*) as AUTH_COUNT FROM RADIUS_AUTHENTICATIONS WHERE TIMESTAMP > SYSDATE - INTERVAL '1' HOUR GROUP BY POLICY_SET_NAME"

Phase 4: Cleanup (After Validation Period)

Only delete old policy sets after confirming new ones work for all devices (recommended: 1 week validation).

netapi ise delete-policy-set "Domus-Wired MAB" --force
netapi ise delete-policy-set "Domus-Wired 802.1X" --force
netapi ise delete-policy-set "Domus-Secure 802.1X" --force
netapi ise delete-policy-set "Domus-IoT iPSK" --force

Rollback Procedure

If issues occur, immediately re-enable old policy sets:

# STEP 1: Disable new policy sets
netapi ise update-policy-set "Domus_MAB" --state disabled
netapi ise update-policy-set "Domus_8021X" --state disabled

# STEP 2: Re-enable old policy sets (reverse order of disable)
netapi ise update-policy-set "Domus-Wired 802.1X" --state enabled
netapi ise update-policy-set "Domus-Secure 802.1X" --state enabled
netapi ise update-policy-set "Domus-Wired MAB" --state enabled
netapi ise update-policy-set "Domus-IoT iPSK" --state enabled

# STEP 3: Verify old policy sets are active
netapi ise get-policy-sets

After rollback, investigate root cause:

# Check recent failures
netapi ise dc query "SELECT TIMESTAMP, CALLING_STATION_ID, FAILURE_REASON, POLICY_SET_NAME FROM RADIUS_AUTHENTICATIONS WHERE PASSED = 0 AND TIMESTAMP > SYSDATE - INTERVAL '30' MINUTE ORDER BY TIMESTAMP DESC"

Appendix: netapi Commands Reference

Policy Set Management

Command Purpose

netapi ise get-policy-sets

List all policy sets

netapi ise create-policy-set "<name>" --allowed-protocols "<ap>" --condition "<cond>"

Create new policy set

netapi ise update-policy-set "<name>" --state enabled|disabled

Enable/disable policy set

netapi ise delete-policy-set "<name>" --force

Delete policy set

Authentication & Authorization Rules

Command Purpose

netapi ise authc "<policy-set>"

List authentication rules (alias for get-auth-rules)

netapi ise authz "<policy-set>"

List authorization rules (alias for get-authz-rules)

netapi ise add-authz-rule "<policy>" "<rule-name>" "<profile>" --condition "<cond>"

Add authorization rule

Authorization Profiles & dACLs

Command Purpose

netapi ise get-authz-profiles

List authorization profiles

netapi ise create-authz-profile "<name>" --vlan <id> --dacl "<dacl-name>"

Create authorization profile

netapi ise get-dacls

List downloadable ACLs

netapi ise create-dacl "<name>" --rules "<acl-lines>"

Create dACL

Allowed Protocols

Command Purpose

netapi ise get-allowed-protocols

List allowed protocols

netapi ise create-allowed-protocols "<name>" --eap-tls --eap-teap --eap-ttls

Create allowed protocols (EAP methods)

netapi ise create-allowed-protocols "<name>" --process-host-lookup

Create allowed protocols (MAB only)

DataConnect Queries

Command Purpose

netapi ise dc query "<sql>"

Run DataConnect SQL query

netapi ise dc auth-history "<mac>"

Get authentication history for MAC

netapi Limitations and Workarounds

Known netapi limitations discovered during testing:

Limitation Impact Workaround

add-auth-rule defaults to EAP-TLS condition

Cannot create MAB auth rules (no condition needed)

Use direct API call with condition: null

update-auth-rule cannot change identity source

Cannot fix MAB auth to use Internal Endpoints

Use direct API PUT to update identity source

ISE API rejects Subject - Organizational Unit

Cannot match certificate OU field via API

Use Subject - Organization (O=) field instead; configure Vault PKI roles with appropriate O= values

Rules inserted at rank 0 by default

New rules go to top, may need reordering

Plan rule creation order carefully or reorder via ISE GUI

Direct API Template for MAB Auth Rule Fix

# Variables
ISE_PAN_IP="10.50.1.20"
ISE_API_USER="domus_ers_admin"
ISE_API_PASS="your_password"

# Get IDs
POLICY_ID=$(netapi ise --format json get-policy-sets | \
  jq -r '.[] | select(.name=="Domus_MAB") | .id')
RULE_ID=$(netapi ise --format json authc "Domus_MAB" | \
  jq -r '.[0].rule.id')

# Update auth rule
curl -s -k -X PUT \
  "https://${ISE_PAN_IP}/api/v1/policy/network-access/policy-set/${POLICY_ID}/authentication/${RULE_ID}" \
  -H "Authorization: Basic $(echo -n ${ISE_API_USER}:${ISE_API_PASS} | base64)" \
  -H "Content-Type: application/json" \
  -d '{
    "rule": {"default": true, "name": "Default", "rank": 0, "state": "enabled", "condition": null},
    "identitySourceName": "Internal Endpoints",
    "ifAuthFail": "REJECT",
    "ifUserNotFound": "CONTINUE",
    "ifProcessFail": "DROP"
  }'

Future: ISE Posture with Secure Client

After EAP-TLS validation is complete, the next phase is ISE Posture assessment using Cisco Secure Client.

Posture Architecture

  • Secure Client deployed via ISE Client Provisioning

  • Quarantine VLAN (99) for non-compliant endpoints

  • Posture policies check for:

    • AV/EDR status

    • OS patch level

    • Disk encryption

    • Required software

Integration Points

Component Integration

Domus_Profile_Quarantine

Assigned to non-compliant endpoints → triggers posture remediation

Domus_dACL_Quarantine

Allows only DHCP/DNS/HTTPS for posture agent communication

Secure Client

Cisco agent performs posture assessment and reports to ISE

Posture Flow

  1. Endpoint authenticates via EAP-TLS (Domus_8021X)

  2. If posture unknown → assign Domus_Profile_Quarantine

  3. Secure Client runs posture checks

  4. If compliant → CoA to Domus_Profile_User or Domus_Profile_Admin

  5. If non-compliant → remain in quarantine, display remediation portal

Posture support for Linux is limited. Focus initial deployment on Windows TEAP endpoints.

Document Revision History

Version Date Changes

1.0

2026-02-16

Initial runbook creation - policy migration framework

1.1

2026-02-16

Major overhaul:
- Fixed Domus_HOST_ONLY = MAB (not EAP-TLS)
- Added Domus_8021X = TEAP_TLS_TTLS for certs
- Added dACL and authorization profile creation
- Added certificate OU-based authorization rules
- Added ISE Posture future section
- Updated all netapi commands

1.2

2026-02-16

Added ISE Certificate Dictionary Requirements:
- Auth rule with cert profile required first
- Use "Subject - Organization" not "Subject - Organizational Unit"
- Combine with EapAuthentication in AND condition

1.3

2026-02-16

Complete tested configuration:
- Fixed Domus_TEAP_TLS_TTLS (disabled processHostLookup)
- Fixed Domus_MAB auth (Internal Endpoints + CONTINUE)
- Added TEAP machine-only rule
- Added specific O= equals rules above general O contains
- Added EAP_TLS_Permit fallback to prevent blocking
- Documented netapi limitations and workarounds
- Added direct API template for MAB auth fix

1.4

2026-02-16

Added Section 2.5 Verify Local Certificate Fields:
- openssl + awk command to extract cert O=/OU=/CN= fields
- Explains ISE matches on O= not OU=
- Maps O= values to authorization rules

1.5

2026-02-16

Added Section 2.6 Test Wired 802.1X Connection:
- awk one-liners to find wired 802.1X connection name
- Color-coded journalctl + awk for auth monitoring
- One-liner MAC extraction + netapi verification
- Example output: successful wired/wireless auth
- Validation table: both interfaces hitting same policy


Environment: Domus Digitalis Home Enterprise
Author: Evan Rosado
Last Updated: 2026-02-16