skip to content

A Kerberos client on an unattended overnight pipeline scheduler holds its long-term key on disk — what does that mean for its AS exchange?

level: seniorimportance: should knowfreq 40%

answer

  1. one test: possession of the key
  2. a copy of the key is the principal
  3. no host identity in the request
  4. unattended hosts drift out of skew
  5. till and renew-till bound the damage

basics

~20 s

The AS exchange tests possession of that long-term key and nothing else, so anyone who can read the file completes it identically and receives a ticket bearing the same flags. The exchange's other unattended dependency is the clock: drift outside the allowed skew fails pre-authentication at 03:00 with nobody watching.

solid answer

~50 s

Everything the AS exchange verifies reduces to one test: could the requester encrypt a current timestamp under the principal's long-term key? On an unattended host, that key must sit on disk, so the answer is yes for the scheduler and equally yes for anything else that can read the file — from any host, since the request carries no host identity beyond optional addresses in the ticket. The resulting ticket carries `initial(9)` and `pre-authent(10)` exactly as a legitimate run's would, so a verifier cannot tell the two apart from the credential. The second consequence is temporal: `PA-ENC-TS-ENC` carries `patimestamp`, which the KDC compares against its own clock, so a scheduler host whose time drifts stops authenticating with `KRB_AP_ERR_SKEW` rather than with anything that looks like a credential problem. The levers inside this exchange are the requested `till`, whether the ticket is renewable with a bounded `renew-till`, and address restriction.

code

pseudocode · 21 lines
pseudocode
# What the KDC evaluates for one AS-REQ from the scheduler
function handle_as_req(request):
    entry = lookup_principal(request.cname, request.realm)
    if entry is absent:
        return error KDC_ERR_C_PRINCIPAL_UNKNOWN

    if no common type between request.etype and entry.supported:
        return error KDC_ERR_ETYPE_NOSUPP

    pa = find_padata(request, pa-enc-timestamp)
    if pa is absent:
        return error KDC_ERR_PREAUTH_REQUIRED    # with METHOD-DATA

    ts = decrypt(pa.padata-value, entry.long_term_key)
    if decrypt failed:
        return error KDC_ERR_PREAUTH_FAILED      # wrong key
    if abs(now - ts.patimestamp) > allowed_skew:
        return error KRB_AP_ERR_SKEW             # drifted clock

    # nothing above distinguishes the scheduler from a copy of its key
    return issue_as_rep(entry, request.nonce, min(request.till, policy_max))

go deeper

for a junior

Recall that the exchange checks one thing — possession of the principal's long-term key — and that on an unattended host that key has to live somewhere readable.

for a middle

Explain the mechanism: the encrypted timestamp is built from that key and compared against the KDC's clock, so both a copied key and a drifted clock have predictable, different effects.

for a senior

Show the diagnosis and the levers. Separate a skew rejection from a key failure, bound lifetime with till and renew-till, and state plainly that the issued credential carries no mark of who obtained it.

for a principal

The tradeoff is where unattended identity should rest at all: a long-lived key on a host, a shorter lifetime with more frequent exchanges, or moving the credential off the filesystem entirely — each shifting cost between operability and blast radius.

## The setting A sequencing pipeline scheduler starts stages overnight. Nobody is at a keyboard at 03:00, so the long-term key of the principal it authenticates as has to be readable by the scheduler process without human help. That single fact determines almost everything about how its AS exchange behaves, and it is worth being exact about which consequences follow from the protocol and which do not. ## What the exchange actually tests The AS exchange applies one test. The client builds `PA-ENC-TS-ENC` with its current `patimestamp`, encrypts it under the principal's long-term key, and sends it as `padata` of type `pa-enc-timestamp`. The KDC decrypts it with the key it holds for that principal, checks the time, and issues the `AS-REP`. That test answers: **did something holding this key produce this request recently?** It does not answer who, from where, on what hardware, or with what authorisation. On an attended workstation the key is derived from something a person typed moments earlier, which smuggles in a weak presence signal. On an unattended host that signal is absent by construction, and the exchange is unchanged. ## Three consequences that follow 1. **A copy of the key is a full substitute for the scheduler.** Anything that can read the key file can complete the AS exchange from any host on the network. The `KDC-REQ-BODY` carries `cname` and `crealm`, not a host identity, and the KDC has no way to distinguish the copy. 2. **The resulting ticket is indistinguishable.** It carries `initial(9)` and `pre-authent(10)` set, an `authtime` of now, and the same `TicketFlags` a legitimate run would produce. A verifier downstream cannot separate them by inspecting the credential; that separation has to come from elsewhere. 3. **The blast radius is the principal's, not the host's.** Everything that principal may reach is reachable, for as long as tickets can be obtained, because the AS exchange is available to anyone holding the key. ## Clock drift is the failure you will actually see The exposure above is the one people discuss; the outage below is the one that wakes people up. `patimestamp` is compared against the KDC's own clock, and a value outside the realm's allowed skew is rejected with `KRB_AP_ERR_SKEW`. An unattended host is exactly the kind of machine whose time service quietly stops: no one logs in, no one notices, and the drift grows. The night it crosses the skew window, every stage fails to authenticate at once, and the failure does **not** look like a credential problem — the key is fine, the principal is fine, and a retry changes nothing until the clock is fixed. Diagnosing it means reading the error code rather than the symptom, and distinguishing it from `KDC_ERR_PREAUTH_FAILED`, which really is a key problem. ## The levers this exchange gives you Within the AS exchange itself the request body offers a small number of genuine controls: - **`till`** — the expiry the client asks for. The KDC grants at most what its policy allows, and the `endtime` in the reply's `enc-part` is the authoritative value. Asking for a lifetime that just covers the run, rather than the maximum, bounds what a captured credential is worth. - **Renewability and `renew-till`** — a renewable ticket lets a long run refresh without touching the long-term key again, while `renew-till` puts a hard ceiling on how far that can be carried. - **Address restriction** — the ticket's `caddr` field can name the addresses a ticket is valid from. It is a narrowing, not a boundary, and it constrains where a stolen ticket works rather than where the key works. ## What this exchange cannot do for you The honest part of the answer is the list of things outside it. The AS exchange offers no way to require a second factor at 03:00, no way to bind the request to a specific host beyond addresses, and no way to distinguish a process from a copy of its key. Protecting the key file, and detecting a principal authenticating from somewhere it has never authenticated from, are both real answers — but neither is a property of the messages. What the protocol gives you is a narrow proof, a bounded lifetime, and errors precise enough to tell a drifted clock from a wrong key.

  • The scheduler asks for a ticket lifetime of seven days in till. What does it get?
    At most what the realm's policy for that principal allows. `till` is a request, and the authoritative expiry is the `endtime` the KDC returns in the reply's `enc-part`. A client that assumes its requested value was granted will be surprised when tickets expire mid-run.
  • Two scheduler hosts share one key file. What does the AS exchange do about that?
    Nothing — it authenticates a principal, not a host or a process. Both complete the exchange, both receive tickets with identical flags, and the KDC sees two indistinguishable authentications of the same principal. Address restriction in `caddr` narrows where the issued tickets may be used, but not who may obtain them.
  • Overnight runs fail with KRB_AP_ERR_SKEW but the same key works interactively by day. Why?
    The key is not the problem. `patimestamp` is compared against the KDC's clock, so the scheduler host's time has drifted past the allowed skew — most likely its time service stopped, and the drift only crosses the window at certain hours or has grown steadily since. Fix the clock; rotating the key changes nothing.

saying these in an interview costs you the question

  • Says a successful AS exchange proves an operator was present.
  • Claims a stolen long-term key yields tickets a verifier can spot.
  • Thinks client clock drift is harmless because the KDC decides time.
  • Believes the till value requested is what the KDC must grant.
  • Says the key on disk is safe because no password crosses the wire.