ISE Authorization Policy

1. Overview

ISE authorization policies determine what access users and devices receive after successful authentication. For Linux workstations with EAP-TLS:

  1. Authorization Profiles - Define VLAN, dACL, and network attributes

  2. Authorization Rules - Match conditions and assign profiles

  3. 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
Example Output
                     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"
Example Output
╭─────────────────────────────────────────────────────────────────────────╮
│ 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

Linux_EAP-TLS_Permit

Linux_EAPTLS_Permit

Active (working)

1

Linux_Admin_EAP-TLS

Linux_EAPTLS_Admins

Future (AD group check)

2-4

Linux_Posture_*

Posture profiles

Future (when posture ready)

5

Default

DenyAccess

Catch-all deny

Rule Ordering is Critical

ISE evaluates authorization rules top-to-bottom. First match wins.

  • Most specific rules at rank 0 (top)

  • Generic fallback rules at bottom

  • Default deny as last rule

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

  1. Navigate to: Policy → Policy Elements → Results → Authorization → Authorization Profiles

  2. Click Add

  3. Configure:

    Field Value

    Name

    Linux_EAPTLS_Permit

    Description

    Full access for EAP-TLS Linux workstations

    Access Type

    ACCESS_ACCEPT

    VLAN

    ADMIN_VLAN (ID: 10)

    DACL Name

    LINUX_EAPTLS_PERMIT_ALL

    Reauthentication Timer

    3600 (1 hour)

    Reauthentication Connectivity

    RADIUS_REQUEST

  4. Click Submit

5. Create Authorization Rules

# 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"
Example Output
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

Table 1. Supported Operators
Operator Description

equals

Exact match (default if omitted)

contains

Substring match

startsWith

Prefix match

endsWith

Suffix match

Dictionary Scope Matters

  • Certificate dictionary (lowercase) — Only available in authentication rules

  • CERTIFICATE dictionary (uppercase) — Available in authorization rules

Certificate:Template Name does NOT work in authorization rules. Use CERTIFICATE:Issuer - Common Name instead.

Example: Verify Compound Condition Created
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: domain.com/Groups/GroupName

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.1. View Current dACLs

netapi ise get-dacls
netapi ise get-dacl "LINUX_EAPTLS_PERMIT_ALL"

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"
Expected Output
          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

7.3. Verify ACL Content on Switch

# Get the ACL name from session, then show its content
netapi ios exec "show ip access-list 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 (aaa server radius dynamic-author) 3. Correct shared secret 4. UDP 1700 allowed between ISE and 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