# TACACS+ for device administration: a login and a command, exchange by exchange

> How a router asks a server whether an engineer may log in, whether the command just typed may run, and how it records that it ran: the three packet types of RFC 8907, the 12-byte header, the START, REPLY and CONTINUE of authentication, the per-command authorization with its name=value arguments, the START, STOP and WATCHDOG of accounting, the obfuscation the RFC refuses to call encryption, the 1993 ancestor of RFC 1492, and the method-list discipline that keeps an estate reachable when the servers are not.

Source: https://ronutz.com/en/learn/tacacs-plus-device-administration  
Updated: 2026-10-06

---

## A different job from network access

Admitting a laptop to a switch port is one decision: in or out, and with which VLAN (virtual local area network). Administering the switch is thousands of decisions: this engineer may log in, may enter configuration mode, may change this interface but not that routing process, and everything they type must be written down. RADIUS (Remote Authentication Dial-In User Service) answers the first kind of question well and the second badly, and Cisco's own comparison document says why: "RADIUS combines authentication and authorization" in one exchange, and "RADIUS does not allow users to control which commands can be executed on a router". TACACS+ was built for the second job. The same document records that Cisco "seriously evaluated RADIUS as a security protocol before it developed TACACS+", and that TACACS+ "uses the AAA architecture, which separates AAA", so that authorization can be asked for as often as the device likes, including once per command.

## Three names, one port

The name is older than the protocol. RFC 1492, An Access Control Protocol, Sometimes Called TACACS, published in July 1993 by Finseth of the University of Minnesota, documents a protocol invented on the ARPANET because "there was a desire to control who could use the dial up lines": a terminal server sent a username and password to a server on UDP port 49, or by TCP on a configurable port, and got accept or reject, with the credentials in clear text. The RFC notes that "Cisco Systems terminal servers implement an extended version of this TACACS protocol", XTACACS, with more request and response types. TACACS+ kept the name and TCP port 49 and replaced everything else; it circulated as a vendor specification, "The Draft" of 1998, and was finally written down as RFC 8907 in September 2020 by Dahm and Ota of Google, Medway Gash of Cisco, Carrel and Grant, as an Informational record of the protocol as deployed. None of the three interoperate, and anything configured today means the third.

## The header and the three packet types

Every TACACS+ packet begins with a 12-byte header: major and minor version, a type octet, a sequence number, flags, a session identifier and the length of the body. The type is 0x01 for authentication, 0x02 for authorization and 0x03 for accounting, and each type is a separate conversation with its own session identifier. Two header flags matter operationally. TAC_PLUS_UNENCRYPTED_FLAG (0x01) means the body was not obfuscated, and the RFC says of it: "This option MUST NOT be used in production." TAC_PLUS_SINGLE_CONNECT_FLAG (0x04) negotiates single-connection mode, in which several sessions are multiplexed over one TCP connection instead of a connection per session, which matters on a busy server.

## Exchange one: the login

An engineer opens an SSH session to a router. The router, as the TACACS+ client, sends an authentication START packet. The START carries the action, the privilege level requested, the authentication type and the service, plus the username and port where known. The authentication types RFC 8907 defines are ASCII (0x01), the interactive prompt-driven login, and PAP (0x02), CHAP (0x03), MSCHAP (0x05) and MSCHAPV2 (0x06) for clients that already hold a password or a challenge-response. The server answers with a REPLY whose status drives the conversation: GETUSER (0x04) asks the client to prompt for a username, GETPASS (0x05) for a password, GETDATA (0x03) for something else, each answered by a CONTINUE from the client carrying what the user typed; PASS (0x01) and FAIL (0x02) end it; RESTART (0x06) asks the client to start over with a different type; ERROR (0x07) reports a server fault; FOLLOW (0x21) redirects the client to another server. An ASCII login is therefore a short interactive script between router and server, with the server choosing the prompts, which is how a server can ask for a one-time code after a password without the router knowing what a one-time code is.

Privilege levels are part of the vocabulary from the start. RFC 8907 defines them from 0 to 15, with TAC_PLUS_PRIV_LVL_USER at 0x01 and TAC_PLUS_PRIV_LVL_ROOT at 0x0f, and the level a session is granted decides what the device will even offer before any per-command check.

## Exchange two: the command

The engineer types a configuration command. On a device configured for command authorization, the router sends an authorization REQUEST describing what is being attempted, as a list of arguments in the form name=value for mandatory arguments and name*value for optional ones. RFC 8907 lists the arguments: service, "the primary service", with values such as shell, tty-server, connection, system or firewall; cmd, "a shell (exec) command"; cmd-arg, "an argument to a shell (exec) command"; priv-lvl, "the privilege level to be assigned"; timeout and idletime, in minutes; acl, inacl and outacl for access lists; addr for a network address; autocmd for a command to run automatically; noescape and nohangup as session flags. A command check is service=shell with cmd=interface and cmd-arg=GigabitEthernet1/0/1, and the server's policy decides on exactly that string.

The server answers with an authorization REPLY carrying a status: PASS_ADD (0x01), the command is allowed and any arguments in the reply are added to the request's; PASS_REPL (0x02), allowed, but the reply's arguments replace the request's; FAIL (0x10), denied; ERROR (0x11), the server could not decide; FOLLOW (0x21), ask another server. Because the exchange is per command, a policy can allow show commands to everyone, interface commands to the network team and routing-protocol commands to two named people, and because the arguments are strings, the policy is written as patterns over command lines, which is both its power and the source of most of its surprises: an abbreviation, an alias or a command typed from a different mode produces a different string.

## Exchange three: the record

Whether or not the command was authorised, a device configured for command accounting sends an accounting REQUEST with the same kind of arguments plus the time, and a flag: START (0x02) for the beginning of a task, STOP (0x04) for its end, WATCHDOG (0x08) to report that a long task is still in progress. For a single command the record carries the command line and its time; for a session, START when it opens and STOP when it closes, with WATCHDOG records in between if it is long. The server answers with an accounting REPLY of SUCCESS (0x01), ERROR (0x02) or FOLLOW (0x21). The stream of those records, kept on the server, is the answer to who changed what on which device and when, and it is the single most valuable artefact TACACS+ produces; the article on accounting treats it as a design in its own right.

## What the obfuscation is, and is not

The body of each packet is XORed with a pseudo-pad built from successive MD5 digests: the first over the session identifier, the shared key, the version and the sequence number, each following one over the same values plus the previous digest. RFC 8907 is unusually candid for a protocol document. The mechanism "is best referred to as 'obfuscation' and not 'encryption'"; the protocol "does not include a security mechanism that would meet modern-day requirements"; and it therefore "MUST be deployed over networks that ensure privacy and integrity", separated from other traffic. The header is never obfuscated, which is what Cisco's comparison means by "TACACS+ encrypts the entire body of the packet but leaves a standard TACACS+ header."

The operational reading is specific. TACACS+ belongs on a management network or inside a tunnel, never across an untrusted path; the shared key is a secret of the same weight as a RADIUS secret and should be rotated with the same discipline; and the unencrypted flag exists for debugging on a bench and nowhere else. Against RADIUS, the body obfuscation is still an improvement, since RADIUS hides only the password attribute and sends everything else in the clear, but neither protocol's own cryptography should be the reason anyone sleeps at night.

## The availability problem, and the method list

Every engineer who has run TACACS+ remembers the day the servers were unreachable. A device configured to authenticate administrators against TACACS+ falls back to whatever its method list says, in order; if the list ends at the servers, or ends at a local account nobody created, or at a local account whose password was set three reorganisations ago and never tested, nobody can log in to fix the thing that broke the path to the servers. The discipline is boring and absolute: a method list that ends in a tested local credential kept somewhere a person on call can reach it; servers reachable by more than one route, and more than one server; and a periodic exercise, with the servers deliberately unreachable from a test device, in which the fallback is actually used. Single-connection mode and the FOLLOW status are the protocol's own contributions to resilience; the rest is configuration.

## Where it lands next to RADIUS

Most estates run both protocols from the same policy servers, and the division is now a rule rather than a debate. RADIUS owns network access: 802.1X at the port and the SSID, MAC Authentication Bypass, web authentication, VPN (virtual private network) logins, anything where a user or a device is being admitted and where the EAP methods are needed, since EAP travels only in RADIUS. TACACS+ owns device administration: who may log in to the infrastructure, with what privilege level, which commands they may run, and the record of what they ran. Cisco's document puts the final difference in one line, "RADIUS uses UDP while TACACS+ uses TCP", and the TCP connection is the right shape for a conversation that may need several exchanges per keystroke. The RADIUS article walks the other protocol through a login with the same care.

## Sources

- [RFC 8907, The Terminal Access Controller Access-Control System Plus (TACACS+) Protocol, Dahm, Ota, Medway Gash, Carrel, Grant, September 2020: the header and flags, the three packet types, the authentication START, REPLY and CONTINUE and the status values, the authentication types, the privilege levels, the authorization arguments and statuses, the accounting flags and statuses, the obfuscation and the deployment requirement, the 1998 Draft (read 2026-10-06)](https://www.rfc-editor.org/rfc/rfc8907)
- [RFC 1492, An Access Control Protocol, Sometimes Called TACACS, Finseth, July 1993: the ARPANET dial-up origin, port 49 for the UDP encoding and a configurable port for the TCP one, Cisco's extended version, clear-text credentials (read 2026-10-07)](https://www.rfc-editor.org/rfc/rfc1492)
- [Cisco, TACACS+ and RADIUS Comparison, document 13838: UDP against TCP, the encrypted body and standard header, AAA separated, per-command authorization, Cisco's evaluation of RADIUS before developing TACACS+ (read 2026-10-06)](https://www.cisco.com/c/en/us/support/docs/security-vpn/remote-authentication-dial-user-service-radius/13838-10.html)
- [Cisco IOS XE 16 Configuration Management guide, Configuration Change Notification and Logging: the device-side record of each command, who applied it and when, as the complement to command accounting (read 2026-10-06)](https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/config-mgmt/configuration/xe-16/config-mgmt-xe-16-book/cm-config-logger.html)
