What can the TACACS+ privilege-level scheme express about an operator, and what can it not express?
answer
- sixteen positions in one order
- each level contains the one below
- underscore field, hyphen argument
- rank is not the same as a set
- non-nested roles need command matching
basics
~20 sIt expresses one number from an ordered range of sixteen, where each level is a superset of the one below. That makes seniority easy to state and a non-nested role impossible to state, which is why per-command matching on cmd and cmd-arg exists beside it.
solid answer
~40 sTACACS+ builds in privilege levels 0 to 15 — `TAC_PLUS_PRIV_LVL_MIN := 0x00` for an unauthenticated session, `TAC_PLUS_PRIV_LVL_USER := 0x01` for a regular one, and `TAC_PLUS_PRIV_LVL_ROOT := 0x0f`, the same value as `TAC_PLUS_PRIV_LVL_MAX := 0x0f`. The levels are **ordered**: each is a superset of the one below. The session's current level travels in the REQUEST's fixed `priv_lvl` field, and the server assigns one by returning the `priv-lvl` argument in a session-based shell authorization. Use of the scheme is not mandatory for clients. Its limit is that a single monotonic hierarchy cannot describe a role that needs a few high-privilege commands and nothing else — for that, policy matches `cmd` and `cmd-arg` per command instead.
code
pseudocode · 12 linesAUTHOR REQUEST (seq_no = 1) # session-based: an empty cmd value
priv_lvl = 0x01 # the level the session holds now
arg_cnt = 2
arg_1 = "service=shell"
arg_2 = "cmd="
AUTHOR REPLY (seq_no = 2)
status = TAC_PLUS_AUTHOR_STATUS_PASS_ADD (0x01)
arg_cnt = 3
arg_1 = "priv-lvl=15" # the level to assign to the shell
arg_2 = "idletime=10"
arg_3 = "timeout=0"go deeper
Remember the range and the named bounds: 0 to 15, with 0x00 for an unauthenticated session, 0x01 for a regular one and 0x0f at the top.
Explain that the values are ordered and each is a superset of the one below, and keep the fixed priv_lvl field distinct from the returned priv-lvl argument.
Bring a case where a rank could not express the separation you needed, and say what command-set matching did instead without pretending levels went away.
Weigh a compact rank that every device already carries against a per-command policy that describes roles exactly and has to be maintained command by command.
## The scheme itself TACACS+ carries a privilege level as a first-class part of the protocol rather than leaving it to policy. The values run **0 through 15**, and four of them have names in the specification: - `TAC_PLUS_PRIV_LVL_MIN := 0x00` — the level of an unauthenticated session. - `TAC_PLUS_PRIV_LVL_USER := 0x01` — the level of a regular authenticated session. - `TAC_PLUS_PRIV_LVL_ROOT := 0x0f` — the top of the range. - `TAC_PLUS_PRIV_LVL_MAX := 0x0f` — the same value, named as the maximum. The defining property is not the count but the **ordering**: the levels are hierarchical, and each one is a superset of the level below it. Holding level 7 means holding everything level 6 holds, plus whatever the deployment attaches to 7. ## Two carriers of the same number The number appears twice on the wire and a precise answer says which one it means. | carrier | spelling | direction | meaning | |---|---|---|---| | fixed body field | `priv_lvl` | device to server | the level this session holds right now | | argument-value pair | `priv-lvl` | server to device | the level to assign | Underscore in the field, hyphen in the argument. The server normally returns `priv-lvl` in a **session-based** authorization — the one where the device sent an empty `cmd` value to bring up a command line — and that reply is what sets the level the session will then carry in its subsequent requests. ## What the scheme is good at 1. **Stating seniority compactly.** One octet says how far up an operator sits, and it travels in every request without policy having to restate it. 2. **Gating by rank.** Because the order is total, a rule of the form *this command needs at least level N* is trivially expressible and trivially evaluated. 3. **Surviving a quiet server.** The level is already in the session, so the device has a coarse notion of who it is dealing with even when it cannot ask about a specific command. ## What it cannot express A single monotonic hierarchy can only describe **nested** roles. Every permission you place high is also granted to everyone above that point, and every operator who needs one high-privilege command must be placed where all the others live too. Consider a broadcaster's contribution-circuit routers during a live feed: the transmission engineer on shift must be able to reroute a circuit, and must not be able to reload the chassis. Those two commands sit at the same rank in any honest ordering, so no single number separates them. That is the structural limit, and it is why the protocol carries `cmd` and `cmd-arg` as well. A **command set** describes a role as the collection of commands and argument prefixes the server will pass, with no requirement that roles nest at all. Two roles can overlap partly, or not at all, and neither contains the other. ## Roles in practice With per-command authorization in force, a role becomes a policy statement on the server: for this group of users, pass these `cmd` values with these `cmd-arg` prefixes and fail the rest. The privilege level does not disappear — it still arrives in `priv_lvl`, it can still be one of the inputs, and a shell authorization still returns one — but it stops being the whole story. Note also that the specification does not oblige clients to use privilege levels at all; a device may authorize purely per command. ## The interview trap The trap is treating the number as though it named a role. It names a **position in an order**, and an order is a much weaker thing than a set. A candidate who says "we gave the on-call engineers level 7" has described a rank, not a permission, and has not yet said what the estate does with it. A candidate who says "the scheme is monotonic, so anything we hand out at 7 is also held at 8 through 15, which is why the separation we needed had to be a command set" has answered the question.
- Which value does `TAC_PLUS_PRIV_LVL_ROOT` carry, and is it distinct from `TAC_PLUS_PRIV_LVL_MAX`?Both are `0x0f` — decimal 15, the top of the range. They are two names for one value, one describing the role of the top level and one describing the bound of the sixteen ordered values. Nothing sits above it.
- Must a network device use privilege levels at all?No. The specification does not make the scheme mandatory for clients. A device may run entirely on per-command authorization and let the server's decision on each `cmd` be the only control, with `priv_lvl` present in the request but unused by policy.
- If policy is per command anyway, what is the level still good for?It travels in every request as a cheap, always-present input, and a session-based shell authorization has to return one. It is a useful coarse rank to combine with command matching — but on its own it can only express a nested hierarchy.
A dial with sixteen numbered notches: you can only hand someone a notch, and a notch carries everything below it. If two jobs need different tools rather than more tools, no notch separates them.
saying these in an interview costs you the question
- Treats the levels as disjoint categories rather than an order
- Says a privilege level names a role
- Claims level 0 is the most privileged of the sixteen
- Thinks the server sets the level through the fixed priv_lvl field
- Believes every device must use the privilege-level scheme