ISE Authorization Policy
1. Overview
ISE authorization policies determine what access users and devices receive after successful authentication. For Linux workstations with EAP-TLS:
-
Authorization Profiles - Define VLAN, dACL, and network attributes
-
Authorization Rules - Match conditions and assign profiles
-
dACLs - Downloadable ACLs for granular access control
2. Policy Sets
Policy sets group authentication and authorization rules. List available policy sets:
netapi ise get-policy-sets
Policy Sets (Page 1, Size 100)
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Name ┃ ID ┃ State ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ Domus-Wired 802.1X │ 2c2e6b05-a29c-46a4-a0ee-7fcea4853e47 │ enabled │
│ Domus-Wired MAB │ 6d941893-bfeb-4acf-8005-c54c3a098cd0 │ enabled │
│ Default │ 3a7f1206-d371-42fe-a845-cd3460535b6e │ enabled │
└─────────────────────┴──────────────────────────────────────┴─────────┘
Get details for a specific policy set:
netapi ise get-policy-set "Domus-Wired 802.1X"
╭─────────────────────────────────────────────────────────────────────────╮
│ Domus-Wired 802.1X │
╰────────────────────────── 2c2e6b05-a29c-46a4-a0ee-7fcea4853e47 ─────────╯
State enabled
Rank 3
Hit Count 682
Service Default Network Access
Condition Radius:NAS-Port-Type equals 'Ethernet'
3. Authorization Rules
Current authorization rules for Domus-Wired 802.1X:
netapi ise get-authz-rules "Domus-Wired 802.1X"
╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Authorization Rules │
╰─────────────────────────────────── Domus-Wired 802.1X ───────────────────────────────────────────╯
# Rule Name Profile(s) SGT State
0 Linux_EAP-TLS_Permit Linux_EAPTLS_Permit - enabled
1 Linux_Admin_EAP-TLS Linux_EAPTLS_Admins - disabled
2 Linux_Posture_Compliant Linux_Posture_Compliant - disabled
3 Linux_Posture_NonCompliant Linux_Posture_NonCompliant - disabled
4 Linux_Posture_Unknown Linux_Posture_Unknown - disabled
5 Default DenyAccess - enabled
| Rank | Rule Name | Profile | Status |
|---|---|---|---|
0 |
|
|
Active (working) |
1 |
|
|
Future (AD group check) |
2-4 |
|
Posture profiles |
Future (when posture ready) |
5 |
|
|
Catch-all deny |
|
Rule Ordering is Critical ISE evaluates authorization rules top-to-bottom. First match wins.
|
4. Authorization Profiles
4.1. View Current Profiles
netapi ise get-authz-profiles
netapi ise get-authz-profile "Linux_EAPTLS_Permit"
╭─────────────────────────────────────────────────────────────────────────╮
│ Authorization Profile: Linux_EAPTLS_Permit │
╰─────────────────────────────────────────────────────────────────────────╯
name Linux_EAPTLS_Permit
vlan {'nameID': 'ADMIN_VLAN', 'tagID': 1}
reauth {'timer': 3600, 'connectivity': 'RADIUS_REQUEST'}
daclName LINUX_RESEARCH_ZERO_TRUST_V2
4.2. Create Authorization Profile
4.2.1. Via netapi
netapi ise create-authz-profile "Linux_EAPTLS_Permit" \
--vlan "ADMIN_VLAN" \
--dacl "LINUX_EAPTLS_PERMIT_ALL" \
--descr "Full access for EAP-TLS authenticated Linux workstations"
# Add reauth timer (1 hour)
netapi ise update-authz-profile "Linux_EAPTLS_Permit" \
--reauth-timer 3600
4.2.2. Via REST API
curl -sk -X POST "https://${ISE_PAN}/ers/config/authorizationprofile" \
-H "Authorization: Basic ${ISE_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"AuthorizationProfile": {
"name": "Linux_EAPTLS_Permit",
"description": "Full access for EAP-TLS Linux workstations",
"accessType": "ACCESS_ACCEPT",
"vlan": {
"nameID": "ADMIN_VLAN",
"tagID": 1
},
"daclName": "LINUX_EAPTLS_PERMIT_ALL",
"reauth": {
"timer": 3600,
"connectivity": "RADIUS_REQUEST"
}
}
}'
4.2.3. Via ISE GUI
-
Navigate to: Policy → Policy Elements → Results → Authorization → Authorization Profiles
-
Click Add
-
Configure:
Field Value Name
Linux_EAPTLS_PermitDescription
Full access for EAP-TLS Linux workstations
Access Type
ACCESS_ACCEPTVLAN
ADMIN_VLAN(ID: 10)DACL Name
LINUX_EAPTLS_PERMIT_ALLReauthentication Timer
3600(1 hour)Reauthentication Connectivity
RADIUS_REQUEST -
Click Submit
5. Create Authorization Rules
5.1. Via netapi (Recommended)
# Create simple EAP-TLS permit rule at rank 0
# NOTE: Without --dict/--attr/--value, defaults to EapAuthentication=EAP-TLS
netapi ise add-authz-rule "Domus-Wired 802.1X" \
"Linux_EAP-TLS_Permit" \
"Linux_EAPTLS_Permit" \
--rank 0
# Verify rule was created
netapi ise get-authz-rules "Domus-Wired 802.1X"
5.2. Idempotent Rule Creation (Safe for Re-runs)
# Check if rule exists before creating
POLICY="Domus-Wired 802.1X"
RULE="Linux_EAP-TLS_Permit"
PROFILE="Linux_EAPTLS_Admins"
if netapi ise get-authz-rules "$POLICY" 2>/dev/null | grep -q "$RULE"; then
echo "Rule '$RULE' already exists -- SKIPPING"
else
netapi ise add-authz-rule "$POLICY" "$RULE" "$PROFILE" --rank 0
echo "✓ Created rule: $RULE"
fi
5.3. Delete and Recreate (Update Existing Rule)
Since update-authz-rule cannot change conditions, use delete+recreate:
POLICY="Domus-Wired 802.1X"
RULE="Linux_EAP-TLS_Permit"
PROFILE="Linux_EAPTLS_Admins"
# Check if rule exists
if netapi ise get-authz-rules "$POLICY" 2>/dev/null | grep -q "$RULE"; then
echo "Rule '$RULE' already exists"
echo -n "Delete and recreate with correct EAP-TLS condition? [y/N] "
read REPLY
if [ "$REPLY" = "y" ]; then
netapi ise delete-authz-rule "$POLICY" "$RULE" --force
netapi ise add-authz-rule "$POLICY" "$RULE" "$PROFILE" --rank 0
echo "✓ Rule recreated with EAP-TLS condition"
else
echo "-- SKIPPING (keeping existing rule)"
fi
else
netapi ise add-authz-rule "$POLICY" "$RULE" "$PROFILE" --rank 0
echo "✓ Created new rule"
fi
# Verify
netapi ise get-authz-rules "$POLICY" | grep -E "$RULE|Rank"
Rule 'TEST_EAP-TLS_DeleteMe' already exists
Delete and recreate with correct EAP-TLS condition? [y/N] y
╭──────────────────────────────────────────────────────────────────────────╮
│ Delete Authorization Rule │
╰────────────────────────────── Domus-Wired 802.1X ────────────────────────╯
Rule Name TEST_EAP-TLS_DeleteMe
Rule ID 559c97e1-d864-4b19-9ca5-bdb3c5b9636c
✓ Deleted authorization rule: TEST_EAP-TLS_DeleteMe
╭──────────────────────────────────────────────────────────────────────────╮
│ Add Authorization Rule │
╰────────────────────────────── Domus-Wired 802.1X ────────────────────────╯
Rule Name TEST_EAP-TLS_DeleteMe
Profile Linux_EAPTLS_Admins
Rank 5
Condition Network Access.EapAuthentication equals 'EAP-TLS'
✓ Created authorization rule: TEST_EAP-TLS_DeleteMe
✓ Recreated
5.4. Compound AND Conditions
For rules requiring multiple conditions (e.g., EAP-TLS + certificate issuer):
# Create rule with compound AND condition
netapi ise add-authz-rule "Domus-Wired 802.1X" "Linux_EAPTLS_Permit" "Linux_EAPTLS_Permit" \
--and "Network Access:EapAuthentication:equals:EAP-TLS" \
--and "CERTIFICATE:Issuer - Common Name:equals:HOME-ROOT-CA" \
--rank 0
The --and option is repeatable. Format: DICTIONARY:ATTRIBUTE:OPERATOR:VALUE
| Operator | Description |
|---|---|
|
Exact match (default if omitted) |
|
Substring match |
|
Prefix match |
|
Suffix match |
|
Dictionary Scope Matters
See Certificate Attributes Scope Limitations for details. |
netapi ise get-authz-rules "Domus-Wired 802.1X"
# Output shows AND block:
# Rule Name Condition
0 Linux_EAPTLS_Permit AND [EapAuthentication=EAP-TLS, Issuer - Common Name=HOME-ROOT-CA]
5.5. AD Group-Based Authorization
For granular access based on AD group membership:
# Step 1: Add AD group to ISE
netapi ise add-ad-groups "INSIDE-AD" "GRP-Linux-Admin-Workstations"
# Step 2: Create authorization rule with AD group condition
netapi ise add-authz-rule "Domus-Wired 802.1X" \
"Linux_Admin_EAP-TLS" \
"Linux_EAPTLS_Admins" \
--dict "INSIDE-AD" \
--attr "ExternalGroups" \
--value "inside.domusdigitalis.dev/Groups/GRP-Linux-Admin-Workstations" \
--operator contains
|
AD group values must use the full LDAP path format: |
5.6. Via REST API
# Get policy set ID
POLICY_SET_ID=$(netapi ise get-policy-sets -f json | \
jq -r '.[] | select(.name=="Domus-Wired 802.1X") | .id')
# Create authorization rule
curl -sk -X POST \
"https://${ISE_PAN}/api/v1/policy/network-access/policy-set/${POLICY_SET_ID}/authorization" \
-H "Authorization: Basic ${ISE_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"rule": {
"name": "Linux_EAP-TLS_Permit",
"rank": 0,
"state": "enabled",
"condition": {
"conditionType": "ConditionAttributes",
"dictionaryName": "Network Access",
"attributeName": "EapAuthentication",
"operator": "equals",
"attributeValue": "EAP-TLS"
}
},
"profile": ["Linux_EAPTLS_Permit"]
}'
6. Downloadable ACLs (dACLs)
6.2. Create dACL
6.2.1. Via netapi
# Create permit all dACL
netapi ise create-dacl "LINUX_EAPTLS_PERMIT_ALL" \
--acl "permit ip any any" \
--descr "Full network access for authenticated Linux workstations"
# Create zero-trust dACL from file
cat > /tmp/zero-trust-dacl.txt << 'EOF'
deny icmp any 10.0.0.0 0.255.255.255
deny icmp any 172.16.0.0 0.15.255.255
deny icmp any 192.168.0.0 0.0.255.255
permit icmp any any
permit udp any host 10.50.1.10 eq 53
permit udp any any eq 123
permit tcp any host 10.50.1.30 eq 8443
permit tcp any host 10.50.1.30 eq 8905
permit tcp any any eq 80
permit tcp any any eq 443
deny ip any 10.0.0.0 0.255.255.255
deny ip any 172.16.0.0 0.15.255.255
deny ip any 192.168.0.0 0.0.255.255
EOF
netapi ise create-dacl "LINUX_RESEARCH_ZERO_TRUST" \
--file /tmp/zero-trust-dacl.txt \
--descr "Zero-trust ACL - blocks RFC1918, permits internet"
6.2.2. Via REST API
curl -sk -X POST "https://${ISE_PAN}/ers/config/downloadableacl" \
-H "Authorization: Basic ${ISE_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"DownloadableAcl": {
"name": "LINUX_EAPTLS_PERMIT_ALL",
"description": "Full network access for authenticated Linux workstations",
"dacl": "permit ip any any",
"daclType": "IPV4"
}
}'
7. Verification
7.1. Check Session Authorization
# View session details including authorization profile
netapi ise mnt session "C8:5B:76:C6:59:62"
# Check which profile was applied
netapi ise mnt session "C8:5B:76:C6:59:62" | grep -E "profile|vlan|dacl"
7.2. Check Switch for Applied ACL
# View session on switch
netapi ios exec "show access-session interface GigabitEthernet1/0/5 detail"
MAC Address: c8:5b:76:c6:59:62
IPv4 Address: 10.50.10.101
User-Name: modestus-p50.inside.domusdigitalis.dev
Status: Authorized
Session timeout: 3600s (server), Remaining: 3584s
Vlan Group: Vlan: 10
ACS ACL: xACSACLx-IP-LINUX_RESEARCH_ZERO_TRUST_V2-6979132a
8. Change of Authorization (CoA)
To apply profile changes to active sessions without disconnecting:
# Send CoA Reauth to endpoint
netapi ise mnt coa "C8:5B:76:C6:59:62"
✓ CoA Reauth sent to C8:5B:76:C6:59:62
|
CoA requires:
1. Switch configured as CoA client in ISE
2. ISE PSN IPs configured on switch ( |
9. Troubleshooting
9.1. Wrong Authorization Profile Applied
Symptom: Authentication succeeds but wrong VLAN/dACL assigned.
Diagnosis:
# Check which rule matched
netapi ise mnt session "C8:5B:76:C6:59:62" --details
# Check rule order
netapi ise get-authz-rules "Domus-Wired 802.1X"
Common Causes: 1. Rule ordering - A generic rule matches before the specific rule 2. Condition mismatch - AD group not in ISE or not matching 3. Profile misconfigured - Wrong VLAN name or ID
Fix:
# Delete shadowing generic rule
netapi ise delete-authz-rule "Domus-Wired 802.1X" "Generic_EAP-TLS_Rule" --force
# Verify order
netapi ise get-authz-rules "Domus-Wired 802.1X"
9.2. dACL Not Applied
Symptom: Authorization succeeds but dACL not downloaded to switch.
Diagnosis:
# Check if dACL exists
netapi ise get-dacl "LINUX_EAPTLS_PERMIT_ALL"
# Check if profile has dACL assigned
netapi ise get-authz-profile "Linux_EAPTLS_Permit"
Fix:
# Assign dACL to profile
netapi ise update-authz-profile "Linux_EAPTLS_Permit" \
--dacl "LINUX_EAPTLS_PERMIT_ALL"
# Trigger CoA to apply
netapi ise mnt coa "C8:5B:76:C6:59:62"
9.3. Authorization Rule Not Matching
Symptom: Endpoint hits default deny instead of expected rule.
Diagnosis:
# Check rule conditions (use plural get-authz-rules with grep)
netapi ise get-authz-rules "Domus-Wired 802.1X" | grep "Linux_Admin_EAP-TLS"
Common Causes: 1. AD group not added to ISE join point 2. Condition attribute doesn’t match session 3. Rule is disabled
Fix:
# Add AD group to ISE
netapi ise add-ad-groups "INSIDE-AD" "GRP-Linux-Admin-Workstations"
# Enable rule
netapi ise update-authz-rule "Domus-Wired 802.1X" "Linux_Admin_EAP-TLS" --enable
9.4. Certificate Condition Rejected by ISE
Symptom: Creating authorization rule with Certificate:Template Name fails:
ERROR: Condition attributes are illegal for requested scope: [ Certificate : Template Name ]
Cause: Certificate dictionary attributes are only available in authentication rules, not authorization rules.
Fix: Use CERTIFICATE dictionary attributes instead:
# Extract issuer CN from endpoint certificate
openssl x509 -in /etc/ssl/certs/machine-eaptls.pem -noout -issuer | \
sed 's/.*CN = \([^,]*\).*/\1/'
# Use CERTIFICATE:Issuer - Common Name in authorization rule
netapi ise add-authz-rule "Domus-Wired 802.1X" "Linux_EAPTLS_Permit" "Linux_EAPTLS_Permit" \
--and "Network Access:EapAuthentication:equals:EAP-TLS" \
--and "CERTIFICATE:Issuer - Common Name:equals:YOUR-CA-CN" \
--rank 0
See Certificate Attributes Scope Limitations for the full explanation.
10. Next Steps
-
Hardened dACL Configuration - Zero-trust ACL design
-
Troubleshooting Guide - Common issues and resolutions
-
Posture Conditions - Compliance checking