When a client sets GSS_C_DELEG_FLAG on a Kerberos context, what does the accepting service end up holding?
answer
- the switch lives at the GSS-API layer
- the credential rides inside the authenticator
- an optional tail on checksum 0x8003
- DlgOpt, Dlgth, Deleg
- acceptor holds a forwarded ticket-granting ticket
basics
~20 sA forwarded ticket-granting ticket for the client, plus its session key. GSS_C_DELEG_FLAG makes the initiator pack that credential into the AP-REQ Authenticator's checksum, so the acceptor can afterwards obtain service tickets in the client's name.
solid answer
~40 s`GSS_C_DELEG_FLAG (1)` is the switch above Kerberos that decides whether a credential travels at all. When `GSS_Init_sec_context` is called with it and the initiator holds a `forwardable(1)` ticket-granting ticket, the mechanism first obtains a *forwarded* ticket-granting ticket from the ticket-granting service, packages it with its session key as a `KRB-CRED` message, and appends it to the `checksum type 0x8003` value carried in the `Authenticator`'s `cksum` field of the `AP-REQ` — in the optional `DlgOpt`, `Dlgth` and `Deleg` fields. `GSS_Accept_sec_context` extracts it, and the acceptor now holds a credential it cannot read but can spend: it can run `TGS-REQ` exchanges whose resulting service tickets name the client in `cname` and `crealm`. Without the flag the acceptor learns who the client is and nothing more.
code
pseudocode · 14 lineschecksum type 0x8003, carried in the AP-REQ Authenticator cksum field
octets 0..3 Lgth length of Bnd; currently 16
octets 4..19 Bnd channel-binding value, or 16 zero octets
octets 20..23 Flags context flags requested by the initiator
bit 0 = GSS_C_DELEG_FLAG (1)
bit 1 = GSS_C_MUTUAL_FLAG (2)
bit 3 = GSS_C_SEQUENCE_FLAG (8)
-- the three fields below appear ONLY when delegating
octets 24..25 DlgOpt delegation option identifier, value 1
octets 26..27 Dlgth length in octets of the Deleg field
octets 28.. Deleg a KRB-CRED carrying the forwarded
ticket-granting ticket and its session keygo deeper
Recall that a service can be handed the right to act as the user, that this is a deliberate request rather than a side effect of logging in, and that the user's password is never what travels.
Explain the two preconditions — the GSS-API flag being requested and the initiator holding a forwardable ticket-granting ticket — and that the credential travels inside the AP-REQ rather than in a message of its own.
Diagnose the silent case: the flag was requested, no credential arrived, and the context established anyway. Name the field that would have carried it and check the flags the acceptor actually got back.
Treat delegation as an estate-wide default to be argued about, not a per-connection convenience. Weigh what a compromised middle tier gains against the work of having back ends accept the middle tier's own principal instead.
## The switch sits above Kerberos, not inside it Kerberos itself has no notion of an application deciding to delegate. It has `forwardable(1)`, which says forwarding is *permitted*, and it has the machinery to issue a forwarded ticket-granting ticket when asked. What decides whether a particular connection actually carries a credential is a **GSS-API context flag**, `GSS_C_DELEG_FLAG (1)`, requested by the initiator when it calls `GSS_Init_sec_context`. That separation matters in practice. Two conditions must both hold before anything is delegated: - the initiator must **ask**, by setting `GSS_C_DELEG_FLAG`; and - the initiator must **hold a `forwardable(1)` ticket-granting ticket**, or there is nothing the ticket-granting service will forward. When only one holds, the context still establishes and the acceptor still learns who the client is — it simply gets no credential. The `GSS_Accept_sec_context` result reports which flags were actually satisfied, which is the honest place to check rather than assuming the request succeeded. ## What the initiator does, in order 1. Obtain a **forwarded ticket-granting ticket** from the ticket-granting service in a `TGS-REQ`, asking for the `krbtgt` service of its own realm and requesting the forwarded option; the reply's ticket carries `forwarded(2)`, and may carry the acceptor's network address in `caddr` or no addresses at all. 2. Wrap that ticket and its session key in a **`KRB-CRED`** message, encrypted so that only the acceptor of this context can open it. 3. Build the `Authenticator` for the `AP-REQ` and place, in its `cksum` field, a value of **`checksum type 0x8003`** whose optional tail carries the `KRB-CRED`. 4. Send the `AP-REQ`. The delegated credential rides **inside** it; there is no separate delegation message. ## Where the credential rides The `0x8003` checksum value is a fixed-layout octet string, not a hash in the ordinary sense — it is the structure the Kerberos V5 GSS-API mechanism uses to carry channel bindings, context flags and, optionally, a credential: - `Lgth` — the length of the binding field, currently 16. - `Bnd` — the channel-binding value, or sixteen zero octets when no bindings are used. - `Flags` — the context flags the initiator requested; bit 0 is `GSS_C_DELEG_FLAG (1)`, bit 1 is `GSS_C_MUTUAL_FLAG (2)`, bit 3 is `GSS_C_SEQUENCE_FLAG (8)`. - `DlgOpt`, `Dlgth`, `Deleg` — **present only when delegating**: an option identifier, a length, and the `KRB-CRED` itself. So the entire delegation decision is visible in one field of one message, and its absence is equally visible: a context with no trailing `Deleg` field delegated nothing. | Context flag | What the initiator is asking for | What the acceptor gains | |---|---|---| | `GSS_C_DELEG_FLAG (1)` | send a usable credential for the client | the ability to act as the client downstream | | `GSS_C_MUTUAL_FLAG (2)` | prove the acceptor's own identity in return | nothing downstream; the initiator gains the `AP-REP` | | `GSS_C_SEQUENCE_FLAG (8)` | detect reordered per-message tokens | ordering guarantees on `GSS_GetMIC` and `GSS_Wrap` output | ## What the acceptor holds afterwards, and what it does not What it holds is a **credential**, not a copy of a secret: - The forwarded ticket-granting ticket is sealed under the **`krbtgt` key**. The acceptor cannot read the client name, flags or `renew-till` inside its `enc-part`. - The **session key** arrives alongside it in the `KRB-CRED`, which is what makes the ticket spendable: the acceptor can build its own `Authenticator` and run a `TGS-REQ`. - The service tickets that come back name the **client** in `cname` and `crealm`. The back-end service sees the user, applies the user's own rights, and has no protocol-level way to tell that a middle tier asked. - The client's **long-term key never travels**. Nothing in this exchange discloses the password or the key `string-to-key` derived from it. What the acceptor does **not** get is any limit. This is unconstrained forwarding: the credential is good for whatever the ticket-granting service will issue, for as long as the forwarded ticket-granting ticket lives, including its renewal window. That is the property the constrained and resource-based models were introduced to remove, and it is why the flag is a deployment decision rather than a default. Declining to delegate costs the acceptor much less than people expect. Identity still comes from the `AP-REQ` and its `Authenticator`; the acceptor still knows exactly who called. It simply has to reach downstream services as **its own service principal**, which for most back ends is the correct design anyway.
- What does the acceptor have to do to use a delegated credential it has received?Import it as a credential for the client principal, then run an ordinary `TGS-REQ` with it exactly as the client would: present the forwarded ticket-granting ticket as `pa-tgs-req (padata-type 1)`, authenticate with the session key that arrived in the `KRB-CRED`, and receive a service ticket whose `cname` and `crealm` are the client's.
- Does an acceptor that declines delegation lose the ability to know who the client is?No. Identity comes from the `AP-REQ` and its `Authenticator`, which are present either way. Without `GSS_C_DELEG_FLAG` the acceptor knows the client's `cname` and `crealm` and holds a session key for the context; it simply has to reach downstream services with its own service principal's rights.
- The initiator set GSS_C_DELEG_FLAG but the acceptor got no credential. What is the likely cause?The initiator's own ticket-granting ticket was not marked `forwardable(1)`, so the ticket-granting service had nothing to forward. The context still establishes, because delegation is a request rather than a requirement — which is why the flags actually returned by `GSS_Accept_sec_context` must be checked rather than assumed.
saying these in an interview costs you the question
- Says the client's long-term key or password is sent to the service.
- Thinks every Kerberos context delegates credentials by default.
- Claims the delegated credential arrives in its own message after the AP-REQ.
- Confuses GSS_C_DELEG_FLAG with GSS_C_MUTUAL_FLAG, which only asks for an AP-REP.
- Believes the acceptor merely learns the user's name, not a usable credential.