skip to content

Why does a TACACS+ command accounting log hold commands that no authorization REQUEST was ever sent for?

level: seniorimportance: should knowfreq 40%

answer

  1. two exchanges, two obligations
  2. the logs are meant to differ
  3. every command entered, however authorized
  4. service, cmd and cmd-arg pairs
  5. completeness costs volume and secrets

basics

~20 s

Because the two exchanges answer to different obligations. Where TACACS+ is used for device administration and all commands must be logged, clients are required to send a start accounting packet for every command entered, irrespective of how that command was authorized.

solid answer

~50 s

Authorization is consulted for the commands a device is configured to ask about; accounting is required for every command entered. Where TACACS+ supports the device-administration case and all commands must be logged, a client must be configured to send a start accounting packet for **every** command, irrespective of how the command was authorized — including commands the device permitted locally and commands for which no authorization exchange ran at all. The record carries `service`, `cmd` and any `cmd-arg` pairs, so the log describes the command as typed. That asymmetry is a feature for an auditor: the accounting trail is the superset, and it is the one to read when the question is what was done rather than what was asked. It also means the two logs will not reconcile line for line, and a reviewer who expects them to will conclude something is broken when nothing is.

code

pseudocode · 11 lines
pseudocode
// one start record per command entered, however it was authorized
flags = TAC_PLUS_ACCT_FLAG_START
args  = [ "service=shell",
          "cmd=configure",
          "cmd-arg=terminal",
          "task_id=9042",
          "start_time=1758249600",
          "priv-lvl=15" ]

// accounting arguments come before any authorization arguments
// in the same packet, and each string is at most 255 characters

go deeper

for a junior

Recall that a command accounting record is one start record per command, carrying service, cmd and any cmd-arg pairs, and that it is sent whatever decided the command.

for a middle

Explain the obligation in the specification's own terms — a start accounting packet for every command entered, irrespective of how it was authorized — and why that makes accounting the superset.

for a senior

Show that you can read two logs that legitimately disagree, name which discrepancy is normal and which is worth investigating, and state the cost of full command logging in volume and in credential exposure.

for a principal

The judgement call is how much of an estate should log every command at all, weighed against record volume, the dependence it creates on a server for routine administration, and the sensitivity of what those records end up holding.

## Two exchanges, two obligations TACACS+ separates authorization and accounting into independent exchanges, and they are not driven by the same rule. - The **authorization** exchange happens when the device is set up to ask before acting. Which commands it asks about is a property of how the device is wired. - The **accounting** exchange is governed by a stronger obligation: where TACACS+ supports the device-administration use case and all commands must be logged, clients must be configured to send a start accounting packet for **every command entered, irrespective of how the command was authorized**. Read that clause carefully — *irrespective of how the command was authorized* covers commands approved by the device-administration server, commands the device allowed on its own, and commands for which no authorization question was asked. The accounting log is therefore a **superset** of the authorization log, by design rather than by accident. ## What one command accounting record carries A command accounting record is a start record whose argument-value pairs describe the command as typed: - `service`, naming the service the command belongs to; - `cmd`, the command itself; - `cmd-arg` pairs where the command had arguments, one pair per argument; - the correlating and timing arguments — `task_id`, `start_time` — and the identity fields in the body, including the username and the terminal line. Each argument-value string is capped at 255 characters, and pairs use `'=' (0x3D)` for a mandatory argument or `'*' (0x2A)` for an optional one. Accounting arguments precede any authorization arguments in the same packet. A typed command is not a long-running task, so the specification's obligation is stated in terms of a start packet; there is rarely a meaningful stop record to pair with it. This is the opposite shape to a shell task, which is exactly the start-and-stop interval `task_id` was built to close. ## Why the two logs will not reconcile For a reviewer this is the operationally important consequence, and it is worth naming the cases: 1. **A command with a record and no authorization exchange.** Entirely normal. The device was obliged to account for it and was not obliged to ask about it. 2. **A command with both.** Also normal, and the usual case for whatever the device does ask about. 3. **A command with an authorization exchange and no record.** This is the one to investigate — either the accounting request was not recorded, or the client is not configured to log all commands. A reviewer who assumes a one-to-one mapping will read case 1 as an authorization bypass and open an investigation into a device that is behaving exactly as specified. The correct reading is that the accounting log answers *what was done*, and the authorization log answers *what was asked about*; only the first is intended to be complete. ## What completeness costs Logging every command has a price, and a senior answer should say so: - **Volume.** A busy console generates a record per keystroke-completed command, and each is a separate exchange, a separate `task_id` and a separate stored record. - **Latency and coupling.** Every command entered now produces an exchange with a server, so the device's administrative path depends on that server more often than the authorization configuration alone implies. - **Content risk.** RFC 8907 is explicit that some client implementations have been observed placing passwords and keys into accounting data. A command whose arguments contain a credential puts that credential into the record, and the trail is typically kept for a long time. Treat the accounting store as holding secrets until proven otherwise. - **Fidelity.** The record describes the command the device saw. It is the device's own account of itself, and it is no better than the device that wrote it. ## The answer an interviewer is listening for The candidate who says *the log must be wrong, that command was never authorized* has assumed one obligation governs both exchanges. The candidate who says *accounting is required for every command entered however it was authorized, so the two logs are supposed to differ, and the accounting one is the audit record* has understood why this exchange exists at all: it is the only part of TACACS+ whose output is read by someone who was not in the room.

  • Does the presence of a command accounting record prove the command succeeded on the device?
    No. The record says the command was entered and the device accounted for it. Whether it took effect is a separate matter the accounting arguments for a typed command do not settle, so read the record as evidence of an attempt by a named operator at a known time.
  • What does RFC 8907 warn may end up inside accounting data?
    Passwords and keys. Some client implementations have been observed placing them into accounting data, and because the trail is retained, anything that lands in a record stays readable for as long as the record does. Treat the accounting store as credential-bearing by default.
  • Why is a command accounting record usually a start record with no stop?
    Because the obligation is phrased as a start accounting packet per command, and a typed command has no meaningful duration to close. The start-and-stop pair, correlated by `task_id`, is the shape used for tasks that genuinely run over time, such as a shell session.
  • A reviewer finds an authorization exchange with no matching accounting record. What does that suggest?
    Something is wrong on the accounting side rather than the authorization side. Either the accounting request was not recorded — in which case an ERROR reply may have been returned — or the client is not configured to send a record for every command entered.

saying these in an interview costs you the question

  • Assumes every accounted command must have an authorization exchange
  • Calls an unauthorized-but-accounted command an authorization bypass
  • Says accounting records are generated by the server from its decisions
  • Thinks a command accounting record proves the command took effect
  • Treats the accounting store as free of credentials by default