AAA Authentication with TACACS+ and Cisco ISE on IOS-XE: The Complete Configuration Guide

Why TACACS+ Beats RADIUS for Device Administration

If you’ve ever sat through a post-incident review where an engineer made an unauthorized change — and nobody could prove exactly who ran which commands — you already know the problem. RADIUS was built for network access authentication: dial-up, 802.1X, VPN. It encrypts only the password in the Access-Request packet and treats authorization as a binary allow/deny. TACACS+, on the other hand, encrypts the entire payload, separates authentication, authorization, and accounting into distinct control planes, and hands you per-command authorization. That granularity is what makes it the standard for device administration in any serious shop.

Cisco Identity Services Engine (ISE) ships with a full TACACS+ Device Administration module that replaces the old ACS (Access Control Server) that many of us ran for years before Cisco killed it. ISE 3.3 and 3.4 are current as of 2026, and the Device Admin persona has matured considerably. This guide walks you through end-to-end configuration: ISE policy set setup, IOS-XE TACACS+ client config, AAA method lists, command authorization, and per-command accounting — with full CLI output so you can follow along on real hardware.

Architecture at a Glance

The flow is straightforward:

  1. An engineer SSHes into a Catalyst switch or ISR router (the Network Access Device, NAD).
  2. The NAD sends an Authentication request to ISE over TCP/49 (TACACS+).
  3. ISE checks the identity (AD, LDAP, or local identity store) and returns Authen-Reply: PASS or FAIL.
  4. After login, each command the engineer runs triggers an Authorization request. ISE evaluates the Shell Profile and Command Sets and replies permit/deny.
  5. Every command is logged in the Accounting records — session start, session stop, each individual command.

The key ISE components are: Network Device Groups (to segment policy by device type/location), Identity Source Sequences (AD first, fallback to internal), Shell Profiles (privilege levels and custom attributes), Command Sets (permit/deny regex per command), and Policy Sets (the outer container that maps a NAD to its policy).

Step 1: Add Your NADs to ISE

Before anything else, every device that will use ISE for TACACS+ must be registered as a Network Device in ISE. Navigate to Administration → Network Resources → Network Devices → Add.

Key fields:

  • Name: Use a naming convention matching your inventory (e.g., SW-CORE-01).
  • IP/Mask: The management IP of the device (loopback preferred).
  • Device Profile: Cisco (this loads the correct TACACS+ attribute dictionary).
  • TACACS+ Authentication Settings: Check the box, enter a shared secret. Use a long random string — this is symmetric, so both sides must match.

For bulk imports, ISE accepts a CSV via Network Devices → Import. The format is documented in the ISE admin guide, but the critical columns are Name, Description, IP, Mask, and TACACS_SHARED_SECRET.

Step 2: Build Your Shell Profiles and Command Sets

Navigate to Work Centers → Device Administration → Policy Elements.

Shell Profiles

Create at minimum two Shell Profiles: one for full admins and one for read-only operators.

Full Admin Shell Profile:

  • Default Privilege: 15
  • Maximum Privilege: 15

Read-Only (NOC) Shell Profile:

  • Default Privilege: 5
  • Maximum Privilege: 5

You can also pass custom attributes here — for example, autocmd to auto-run a script on login, or timeout to set idle session timeouts per group.

Command Sets

Command Sets control what individual commands are permitted. Navigate to Work Centers → Device Administration → Policy Elements → Results → TACACS Command Sets.

Permit All Commands (for full admins): Add a single rule with Grant = Permit, Command = .*, Arguments = blank.

NOC Read-Only Commands: Add explicit permits for show commands, deny everything else:

Grant Command Arguments
Permit show .*
Permit ping .*
Permit traceroute .*
Permit exit
Permit logout

Check If no match, then Deny at the bottom of the Command Set. This is critical — without it, unmatched commands default to permit, which defeats the purpose.

Step 3: Create the Device Administration Policy Set

In Work Centers → Device Administration → Device Admin Policy Sets, create a new Policy Set or modify the Default one.

Policy Set Condition: Match on the Network Device Group (NDG) — for example, NDG:Device Type:Switches. This scopes the policy to only switch devices in this set.

Inside the Policy Set, configure:

  • Authentication Policy: Match Default, use Identity Source Sequence = AD_then_Internal, with PAP/ASCII as the allowed protocol.
  • Authorization Policy:
    • Rule 1: If AD Group = Network-Admins, then Shell Profile = Full Admin + Command Set = Permit All
    • Rule 2: If AD Group = NOC-Operators, then Shell Profile = NOC Read-Only + Command Set = NOC Read-Only Commands
    • Default: DenyAccess

Step 4: Configure TACACS+ on Cisco IOS-XE

Now the part most network engineers live in: the IOS-XE side. All of the following examples are tested on IOS-XE 17.x running on Catalyst 9300 series and ISR 4000 series.

Define the TACACS+ Server

! Define ISE nodes (use both PSN nodes for redundancy)
tacacs server ISE-PSN1
 address ipv4 10.100.1.10
 key 7 your-shared-secret-here
 timeout 5
 single-connection
!
tacacs server ISE-PSN2
 address ipv4 10.100.1.11
 key 7 your-shared-secret-here
 timeout 5
 single-connection
!
! Group both servers together
aaa group server tacacs+ ISE-TACACS
 server name ISE-PSN1
 server name ISE-PSN2
 ip vrf forwarding Mgmt-vrf
 ip tacacs source-interface GigabitEthernet0/0

The single-connection keyword tells the device to reuse a single persistent TCP connection to ISE instead of opening a new TCP session per authentication attempt. This reduces overhead significantly on busy devices. The ip vrf forwarding Mgmt-vrf line is required if your management interfaces live in a VRF (as they should — see our VLAN segmentation guide for why isolating management traffic matters).

Enable AAA and Configure Method Lists

! Enable AAA (this is irreversible without console access — test carefully)
aaa new-model
!
! Authentication: try ISE first, fall back to local
aaa authentication login default group ISE-TACACS local
aaa authentication login CONSOLE local
aaa authentication enable default group ISE-TACACS enable
!
! Authorization: command authorization via ISE
aaa authorization exec default group ISE-TACACS local if-authenticated
aaa authorization commands 1 default group ISE-TACACS local if-authenticated
aaa authorization commands 15 default group ISE-TACACS local if-authenticated
aaa authorization config-commands
!
! Accounting: log everything to ISE
aaa accounting exec default start-stop group ISE-TACACS
aaa accounting commands 1 default start-stop group ISE-TACACS
aaa accounting commands 15 default start-stop group ISE-TACACS

A few things to note here:

  • The CONSOLE method list uses local only. Never run TACACS+ authorization on the console line. If ISE goes down or you have a reachability issue, you need that console to be your fallback. Local auth on console is a hard requirement.
  • if-authenticated on authorization: This means if the TACACS+ server is unreachable, users who already authenticated locally can still run commands. Without this, a TACACS+ outage during a session will lock out every connected engineer.
  • aaa authorization config-commands: Without this line, commands entered in configuration mode are NOT sent to TACACS+ for authorization. Turn it on — you want every config command logged and authorized.

Apply Method Lists to Lines

line con 0
 login authentication CONSOLE
 authorization exec default
 accounting exec default
 exec-timeout 10 0
!
line vty 0 15
 login authentication default
 authorization exec default
 authorization commands 1 default
 authorization commands 15 default
 accounting exec default
 accounting commands 1 default
 accounting commands 15 default
 transport input ssh
 exec-timeout 15 0

Note that the VTY lines explicitly reference default method lists, which maps back to your AAA configuration above. The console line uses CONSOLE for authentication (local only) but still uses default for accounting — you still want console sessions logged via TACACS+ accounting when ISE is reachable.

Step 5: Verify the Configuration

After applying, test from a second terminal while keeping your current session open. On the IOS-XE device:

! Check TACACS+ server reachability
SW-CORE-01# test aaa group ISE-TACACS sarah-chen testpassword new-code

Attempting authentication test to server-group ISE-TACACS using tacacs+
User was successfully authenticated.

! Check server status
SW-CORE-01# show tacacs
Tacacs+ Server: 10.100.1.10/49  (Single connection)
               Opens=147   Closes=0    Aborts=0    Errors=0
               Packets In=294 Packets Out=294

Socket opens:  147
Socket closes: 0
Total packets sent: 294
Total packets recv: 294
Reference count: 1  Use count: 0

Tacacs+ Server: 10.100.1.11/49  (Single connection)
               Opens=0    Closes=0    Aborts=0    Errors=0
...

The second PSN showing zero opens is expected — ISE-PSN1 is answering everything, and PSN2 is standby. If PSN1 fails, IOS-XE will automatically shift to PSN2.

! Check authorization status
SW-CORE-01# show aaa method-lists

authen queue=AAA_ML_AUTHEN_LOGIN
   name=default  valid=TRUE  flag=NONE
     action=ERROR  methods= group ISE-TACACS  local
   name=CONSOLE  valid=TRUE  flag=NONE
     action=ERROR  methods= local

author queue=AAA_ML_AUTHOR_CMDAUTHZ
   name=default  valid=TRUE  flag=NONE
     action=ERROR  methods= group ISE-TACACS  local if-authenticated

acct queue=AAA_ML_ACCT_EXEC
   name=default  valid=TRUE  flag=START_STOP
     action=ERROR  methods= group ISE-TACACS

Step 6: Validate in ISE TACACS+ Live Logs

In ISE, navigate to Operations → TACACS → Live Logs. After authenticating to the switch, you should see entries like:

  • AuthenticationPassed — the login succeeded, identity = sarah-chen@corp.example.com
  • AuthorizationPassed — exec shell permitted, privilege 15 assigned
  • For each command run: CommandAuthorizationPassed or CommandAuthorizationFailed
  • AccountingStart / AccountingStop with session duration

This is your audit trail. ISE stores these logs locally and can forward them to a SIEM via syslog. Parsing ISE syslog feeds with a log aggregator lets you build dashboards showing which engineers touched which devices, across your entire fleet, in a single view.

Common Issues and Fixes

Authorization Passes but Commands Are Denied

This usually means your Command Set has Deny All at the bottom, and the permit rules aren’t matching. Check the command exactly — ISE command authorization is case-sensitive and matches the command as typed, not the expanded form. sh ip int br and show ip interface brief are different strings in ISE’s eyes. Build your regex to account for abbreviations:

Command: sh(ow)?
Arguments: ip (int(erface)? (br(ief)?)?|route.*|bgp.*|ospf.*)

Or, more practically for NOC operators, permit the show command with argument regex .* — that covers all abbreviations since IOS-XE expands to the full command before sending the authz request (behavior varies by platform, test it).

ISE Is Reachable but Authentication Fails with “No Response from Server”

Check your VRF. If the device is sourcing TACACS+ packets from an interface in Mgmt-vrf but the aaa group server tacacs+ config doesn’t specify ip vrf forwarding Mgmt-vrf, the packets leave via the global routing table and never reach ISE. Always verify with:

debug tacacs
debug aaa authentication

The debug output will show the source IP being used. Cross-check that it’s the management interface IP, not an in-band SVI.

Console Locked Out After Applying AAA

If you accidentally applied the default method list to the console line and ISE is unreachable, the local fallback will still work — assuming you have a local user configured. Always configure a break-glass local account before enabling AAA:

username breakglass privilege 15 algorithm-type scrypt secret VeryLongPassphraseHere

Store this credential in your vault — an offline PAM solution or a self-hosted option like Vaultwarden. The break-glass account should never be the same as any engineer’s daily login credentials.

Accounting Records Showing Wrong Username

If TACACS+ accounting shows the username as the device hostname or blank, check that aaa accounting send stop-record authentication failure is configured. Also ensure the accounting method list is explicitly applied to the VTY lines — without it, IOS-XE won’t send accounting records for those sessions even if a global method list exists.

Hardening the TACACS+ Configuration

A few additional hardening steps worth implementing alongside TACACS+:

! Restrict management access to known subnets
ip access-list standard MGMT-ACCESS
 permit 10.100.0.0 0.0.255.255
 deny any log
!
line vty 0 15
 access-class MGMT-ACCESS in
!
! Log unauthorized auth attempts
aaa authentication fail-message ^
Unauthorized access attempt logged. Your session will be terminated.
^
!
! Set session timeout aggressively for VTY
line vty 0 15
 exec-timeout 15 0

Also consider enabling Control Plane Policing (CoPP) to rate-limit TACACS+ traffic to the control plane — this prevents a brute-force attack from overwhelming the device’s CPU.

Putting It All Together

A properly configured TACACS+/ISE stack gives you three things that matter at audit time: proof of who authenticated, proof of what they were authorized to do, and a full record of what they actually did. That’s the difference between “someone ran no ip route at 2am” and having a name, a session ID, timestamps, and a printable log you can hand to management.

The configuration in this guide follows current ISE 3.3/3.4 and IOS-XE 17.x conventions. If you’re still running ACS (end-of-life since 2023), the ISE Device Administration licensing is now included in the Advantage tier — migration is overdue. The ISE migration tool handles bulk ACS policy import reasonably well for simple deployments, though complex shared secret and command set structures usually need manual review.

Start with a pilot group of devices in a lab NDG, validate the Live Logs, then roll to production in waves. Don’t enable command authorization globally until you’ve confirmed your Command Sets are correct — a misconfigured deny rule can lock out your own team faster than any attacker could.

For related reading: the Cisco IOS vs IOS-XE vs IOS-XR comparison covers platform differences that matter when deploying TACACS+ across a mixed environment — command abbreviation behavior and authorization interaction varies between platforms.

Enjoying this post?

Get more guides like this delivered straight to your inbox. No spam, just tech and trails.