Cisco AAA with TACACS+ and ISE on IOS-XE: Command Authorization, Accounting, and Audit Trails

Cisco AAA with TACACS+ and ISE on IOS-XE: Command Authorization, Accounting, and Audit Trails

Why AAA Is Non-Negotiable on Managed Infrastructure

If your network devices still rely on a shared enable password and a local username list, you’re one leaked credential away from a very bad day. AAA—Authentication, Authorization, and Accounting—is the framework that separates professional network management from the kind of setup that gets audited (and not in a good way).

In this guide, I’m walking through a complete AAA deployment on Cisco IOS-XE using TACACS+ as the protocol and Cisco Identity Services Engine (ISE) as the policy server. We’ll cover everything from initial router configuration to ISE shell profiles and command authorization sets, plus the accounting config that gives you a full audit trail. Real CLI output included.

If you’re new to the Cisco ecosystem, you might want to review the differences between IOS, IOS-XE, and IOS-XR before diving in—some of the AAA syntax diverges between platforms.


AAA Concepts in 30 Seconds

Authentication: Who are you? Validates identity via credentials.
Authorization: What can you do? Controls access based on role.
Accounting: What did you do? Logs all activity for audit.

Two protocols dominate enterprise AAA:

  • TACACS+ (TCP/49): Separates auth/authz/accounting into independent functions; encrypts the entire payload; ideal for device administration.
  • RADIUS (UDP/1812-1813): Bundles auth and authz; encrypts only the password field; better suited for network access (802.1X, VPN).

For Cisco device administration, TACACS+ wins. Full stop. The granular command authorization and complete packet encryption make it the right tool for the job. ISE supports both, but its device administration policies are TACACS+-specific.


Lab Topology

For this guide:

  • Cisco ISE 3.3 (IP: 10.10.10.50) — Policy Administration Node + Policy Service Node (single-node lab)
  • Catalyst 9300 running IOS-XE 17.12.x (management IP: 10.10.10.1)
  • Management network: 10.10.10.0/24

Step 1: Configure ISE as a TACACS+ Server

Before touching the router, configure ISE. Log into ISE and navigate to Administration → Network Resources → Network Devices. Add your router as a network device with TACACS+ enabled and a shared secret. Remember this secret—you’ll need it on the router side.

Then navigate to Work Centers → Device Administration → Policy Elements → Results and create two shell profiles:

  • Network-Admin: Custom attribute priv-lvl = 15 (full access)
  • Network-ReadOnly: Custom attribute priv-lvl = 1 (view only)

Create a TACACS+ Command Set for read-only access:

Command Set: ReadOnly-Commands
Permit: show .*
Permit: ping .*
Permit: traceroute .*
Deny: .* (default deny all)

Finally, build a Device Administration Policy Set that matches on device type or location and assigns the correct shell profile based on the user’s Active Directory group.


Step 2: Configure TACACS+ on IOS-XE

Define the TACACS+ Server

! Define ISE as TACACS+ server
tacacs server ISE-PRIMARY
 address ipv4 10.10.10.50
 key 7 <your-encrypted-secret>
 timeout 5
 !
! Add a secondary if you have a second ISE PSN
tacacs server ISE-SECONDARY
 address ipv4 10.10.10.51
 key 7 <your-encrypted-secret>
 timeout 5

Use key 0 for a plaintext key during initial config—IOS-XE will encrypt it to type 7 automatically:

tacacs server ISE-PRIMARY
 address ipv4 10.10.10.50
 key 0 MySharedSecret123!

Create a Server Group

aaa group server tacacs+ ISE-SERVERS
 server name ISE-PRIMARY
 server name ISE-SECONDARY
 ip vrf forwarding Mgmt-vrf
 ip tacacs source-interface GigabitEthernet0/0

The ip vrf forwarding Mgmt-vrf line is critical if your management traffic runs in a VRF (common on Cat9K with the dedicated management port). Without it, the TACACS+ packets will try to exit via the default routing table and never reach ISE.


Step 3: Configure AAA Methods

Enable AAA

aaa new-model

This single command is irreversible within a session—once typed, AAA is active. Don’t type it remotely until your TACACS+ config is verified, or you risk locking yourself out. Always configure a local fallback user first.

Create a Local Fallback User

username LOCAL_ADMIN privilege 15 algorithm-type scrypt secret Str0ngL0calP@ss!

Use algorithm-type scrypt (or sha256 at minimum). Never use password—that stores credentials in type 7 “encryption” that takes seconds to reverse.

Authentication

! Login authentication: try ISE first, fall back to local
aaa authentication login VTY_AUTH group ISE-SERVERS local

! Enable (privilege escalation): try ISE first, fall back to local enable password
aaa authentication enable default group ISE-SERVERS enable

Authorization

! Exec authorization: applies shell profile (sets privilege level)
aaa authorization exec VTY_AUTH group ISE-SERVERS local if-authenticated

! Command authorization for all privilege levels
aaa authorization commands 1 VTY_AUTH group ISE-SERVERS local if-authenticated
aaa authorization commands 15 VTY_AUTH group ISE-SERVERS local if-authenticated

! Authorize config commands
aaa authorization config-commands

The if-authenticated keyword is the local fallback behavior—if ISE is unreachable, locally authenticated users get authorized without a second server query. Without this, a TACACS+ outage locks out local users entirely.

Accounting

! Exec accounting: log session start/stop
aaa accounting exec VTY_AUTH start-stop group ISE-SERVERS

! Command accounting: log every command
aaa accounting commands 1 VTY_AUTH start-stop group ISE-SERVERS
aaa accounting commands 15 VTY_AUTH start-stop group ISE-SERVERS

! System events (reloads, etc.)
aaa accounting system default start-stop group ISE-SERVERS

Apply to Line VTY

line vty 0 15
 login authentication VTY_AUTH
 authorization exec VTY_AUTH
 authorization commands 1 VTY_AUTH
 authorization commands 15 VTY_AUTH
 accounting exec VTY_AUTH
 accounting commands 1 VTY_AUTH
 accounting commands 15 VTY_AUTH
 transport input ssh
 transport output none

Note: transport input ssh blocks Telnet entirely. If you’re still using Telnet for device management in 2026, that’s a separate conversation we need to have.

Console Line (Local Only)

line con 0
 login authentication default
 authorization exec default

The default method list uses the global aaa authentication login default. Configure that to be local-only for the console so a TACACS+ failure doesn’t lock you out of physical access:

aaa authentication login default local
aaa authorization exec default local

Step 4: Lock Down SSH and Management Access

! Generate RSA key for SSHv2
crypto key generate rsa modulus 4096
ip ssh version 2
ip ssh time-out 60
ip ssh authentication-retries 3
ip ssh dh min size 2048

! Only allow SSH from management subnet
ip access-list standard MGMT-ONLY
 permit 10.10.10.0 0.0.0.255
 deny   any log

line vty 0 15
 access-class MGMT-ONLY in

Pair this with a Control Plane Policy to rate-limit SSH connection attempts. For a full treatment, see the CoPP guide—SSH brute-force sourced from inside your own network is more common than you’d think.


Step 5: Verification

Test TACACS+ Reachability

Router# test aaa group ISE-SERVERS testuser TestPass123! legacy

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

Check TACACS+ Server Status

Router# show tacacs

Tacacs+ Server : 10.10.10.50/49            Opens=5  Closes=5  Aborts=0  Errors=0
                                             Packets in=10  Packets out=10
  Expected Replies=0  Replies discarded=0
  Timeouts=0  Connection Failures=0  Elapsed time=0s
  Server is UP

Tacacs+ Server : 10.10.10.51/49            Opens=0  Closes=0  Aborts=0  Errors=0
                                             Packets in=0  Packets out=0
  Expected Replies=0  Replies discarded=0
  Timeouts=0  Connection Failures=0  Elapsed time=0s
  Server is UP

Verify Active Sessions and Accounting

Router# show aaa sessions

Total sessions since last reload: 47
Session Id=12
  Unique Id=47
  User = sarah
  IP Address = 10.10.10.100
  Idle Disconnect = 0
  IDB = GigabitEthernet0/0
Router# show aaa user all

Unique id 47 is being served by tty line 0
  No data for type 1
  No data for type 2
  No data for type 3
  No data for type 4
  AAA type EXEC:
    service=shell
    priv-lvl=15

Debug (Use Carefully in Production)

Router# debug tacacs
Router# debug aaa authentication
Router# debug aaa authorization

Always turn off debug after testing: undebug all

In ISE, go to Operations → TACACS → Live Logs to see real-time authentication, authorization, and accounting records with pass/fail status and matched policy sets.


Step 6: Command Authorization Troubleshooting

The most common complaint after enabling command authorization: “I can’t run any commands.” Here’s the quick checklist:

Check What Policy Matched in ISE

ISE Live Logs will show the matched Device Administration Policy Set and the shell profile returned. If it says priv-lvl=1 when you expected 15, your AD group membership or policy conditions need review.

Router Denying Commands?

Router# debug aaa authorization

AAA/AUTHOR (0x4600003A): Port='tty2' list='VTY_AUTH' type=CMD
  service=shell cmd=show running-config
AAA/AUTHOR/TACACS+ (463752650): Processing AV priv-lvl=15
AAA/AUTHOR (0x4600003A): Authorization successful

If you see Authorization failed, the command isn’t in an ISE permit command set for that user. Check ISE → Device Administration → Policy Elements → Results → TACACS Command Sets.

TACACS+ Server Unreachable

Router# show tacacs

Tacacs+ Server : 10.10.10.50/49
  Timeouts=10  Connection Failures=3
  Server is DEAD

If ISE is marked DEAD, the router falls to the next method in the list (local or if-authenticated). Check reachability, VRF config, and the shared secret (mismatched secrets cause silent failures—the connection opens on TCP/49 but TACACS+ rejects the session).

Verify the Shared Secret

Router# show run | section tacacs server
tacacs server ISE-PRIMARY
 address ipv4 10.10.10.50
 key 7 0822455D0A1657

Compare the decrypted key with what’s in ISE. Use a type-7 decoder (plenty available offline) to verify they match. A one-character mismatch is the most common deployment mistake.


Recommended ISE Policy Structure

Here’s a clean policy hierarchy for a typical enterprise environment:

Device Admin Policy Sets:
├── Network-Engineers (AD Group: NET-ADMINS)
│   ├── Auth Policy: Allow TACACS+ with AD auth
│   └── Authz Policy: Shell Profile → Network-Admin (priv 15)
│       Command Set: Permit-All
│
├── NOC-ReadOnly (AD Group: NOC-TEAM)
│   ├── Auth Policy: Allow TACACS+ with AD auth
│   └── Authz Policy: Shell Profile → Network-ReadOnly (priv 1)
│       Command Set: ShowOnly-Commands
│
└── Default
    └── Authz Policy: Deny All

The key design principle: explicit deny at the bottom of every policy set. Never let the default be “permit unknown.” An ISE deployment without an explicit default-deny is just theater—determined attackers will find the gaps.


Enabling TACACS+ Accounting on ISE Side

By default, ISE stores TACACS+ accounting records locally. To export to a SIEM or syslog server:

  1. Go to Administration → System → Logging → Remote Logging Targets and add your syslog server.
  2. Go to Administration → System → Logging → Logging Categories and enable TACACS Accounting to send to your remote target.

This gives you command-level audit logs in your SIEM. Every conf t, every no shutdown, every write mem—timestamped, attributed to a specific AD account, and stored off-device where they can’t be tampered with.


Full Running Config Summary

! Local fallback (configure BEFORE aaa new-model)
username LOCAL_ADMIN privilege 15 algorithm-type scrypt secret Str0ngL0calP@ss!

! Enable AAA
aaa new-model

! TACACS+ servers
tacacs server ISE-PRIMARY
 address ipv4 10.10.10.50
 key 0 MySharedSecret123!
 timeout 5
!
tacacs server ISE-SECONDARY
 address ipv4 10.10.10.51
 key 0 MySharedSecret123!
 timeout 5

! Server group
aaa group server tacacs+ ISE-SERVERS
 server name ISE-PRIMARY
 server name ISE-SECONDARY
 ip vrf forwarding Mgmt-vrf
 ip tacacs source-interface GigabitEthernet0/0

! Authentication
aaa authentication login default local
aaa authentication login VTY_AUTH group ISE-SERVERS local
aaa authentication enable default group ISE-SERVERS enable

! Authorization
aaa authorization exec default local
aaa authorization exec VTY_AUTH group ISE-SERVERS local if-authenticated
aaa authorization commands 1 VTY_AUTH group ISE-SERVERS local if-authenticated
aaa authorization commands 15 VTY_AUTH group ISE-SERVERS local if-authenticated
aaa authorization config-commands

! Accounting
aaa accounting exec VTY_AUTH start-stop group ISE-SERVERS
aaa accounting commands 1 VTY_AUTH start-stop group ISE-SERVERS
aaa accounting commands 15 VTY_AUTH start-stop group ISE-SERVERS
aaa accounting system default start-stop group ISE-SERVERS

! SSH hardening
crypto key generate rsa modulus 4096
ip ssh version 2
ip ssh time-out 60
ip ssh authentication-retries 3

! ACL for management access
ip access-list standard MGMT-ONLY
 permit 10.10.10.0 0.0.0.255
 deny   any log

! Console line
line con 0
 login authentication default
 authorization exec default

! VTY lines
line vty 0 15
 login authentication VTY_AUTH
 authorization exec VTY_AUTH
 authorization commands 1 VTY_AUTH
 authorization commands 15 VTY_AUTH
 accounting exec VTY_AUTH
 accounting commands 1 VTY_AUTH
 accounting commands 15 VTY_AUTH
 access-class MGMT-ONLY in
 transport input ssh
 transport output none

Common Gotchas

  • Order of operations matters. Configure the local fallback user and method lists before typing aaa new-model. Better yet, test everything on a non-production device first.
  • VRF awareness. If management is in a VRF, every AAA-related command needs the VRF context. Miss one and TACACS+ silently fails.
  • ISE shared secret is case-sensitive. “Secret123” ≠ “secret123”. TACACS+ connections will establish on TCP/49 but all auth attempts will fail.
  • Command authorization can be brutal to debug remotely. Always verify from a console or with a fallback method before enabling command authz on remote sessions.
  • ISE licenses. Device Administration (TACACS+) requires a separate license in ISE 3.x—the Plus or Advantage tier. Base license only covers network access (RADIUS). Confirm your entitlement before building the policy.

Wrapping Up

A properly deployed AAA stack with TACACS+ and ISE transforms your network from “shared passwords and hope” to a fully auditable, role-based access control system. Every login is authenticated against your directory, every command is authorized against a policy, and every action is logged with attribution.

The initial setup takes time—mostly in ISE policy configuration and the inevitable debugging of VRF or shared secret issues—but once it’s running, day-to-day management is cleaner and your auditors will thank you.

From here, look at extending ISE to cover 802.1X port authentication using RADIUS, and consider pairing your command accounting data with a SIEM rule that alerts on privilege escalation or configuration changes outside of change windows. For automation of routine tasks that don’t need interactive access, Python with Netmiko and NAPALM can handle templated changes without granting shell access at all.

Enjoying this post?

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