skip to content

In a SAML role descriptor, what does the `use` attribute on a `<KeyDescriptor>` select, and what does omitting it mean?

level: seniorimportance: should knowfreq 38%

answer

  1. two values, one optional attribute
  2. values come from md:KeyTypes
  3. omitted means both purposes
  4. both keys belong to the publisher
  5. several signing keys enable an overlap

basics

~20 s

The use attribute is drawn from md:KeyTypes and takes the values signing or encryption, saying which purpose that published key serves. It is optional, and when omitted the key may be used for both. A role may publish several key descriptors.

solid answer

~50 s

`<KeyDescriptor>` publishes one public key, carried in `<ds:KeyInfo>` — most often as a `<ds:X509Certificate>`. Its `use` attribute, whose values come from `md:KeyTypes`, is either `signing` or `encryption`, and it is **optional**: a `<KeyDescriptor>` with no `use` declares a key good for both purposes. A role descriptor may carry several, and that plurality is what makes a pairwise rollover possible — two `<KeyDescriptor use="signing">` elements let either key be accepted while counterparty caches turn over. The practical failure is a consumer that stores "the counterparty's certificate" as a single value: it takes whichever `<KeyDescriptor>` it saw first, or the encryption key, and then nothing the counterparty sends is accepted. Four distinct keys take part in one login — the counterparty's signing key, the key it wants content encrypted to, the transport certificate on the endpoint being called, and the symmetric key that encrypts content — and only the first two are what `use` is about.

code

xml · 24 lines
xml
<md:IDPSSODescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
    protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">

  <!-- outgoing signing key, still in use -->
  <md:KeyDescriptor use="signing">
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:X509Certificate>MIIC...old...</ds:X509Certificate>
    </ds:KeyInfo>
  </md:KeyDescriptor>

  <!-- incoming signing key, published early for the overlap -->
  <md:KeyDescriptor use="signing">
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:X509Certificate>MIIC...new...</ds:X509Certificate>
    </ds:KeyInfo>
  </md:KeyDescriptor>

  <md:KeyDescriptor use="encryption">
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:X509Certificate>MIIC...enc...</ds:X509Certificate>
    </ds:KeyInfo>
  </md:KeyDescriptor>

</md:IDPSSODescriptor>

go deeper

for a junior

Recall that a published key says what it is for: verifying what that party sends, or encrypting content to that party. Know that both keys belong to the party the document describes.

for a middle

Explain the attribute precisely: optional, values signing and encryption, and omission meaning both. Say why a role may carry several key descriptors and that no precedence is implied between them.

for a senior

Diagnose from the symptom: one counterparty rejected wholesale while others work usually means the wrong key of the right party was stored, not a content problem. Know the four distinct keys that appear in a single login.

for a principal

Decide whether the estate separates signing and encryption keys at all, and what that costs: separated keys rotate independently and fail independently, a single unrestricted key halves the bookkeeping and doubles the blast radius of one change.

## The element and its one attribute A `<KeyDescriptor>` inside a role descriptor publishes **one public key** for that role. The key material sits inside `<ds:KeyInfo>`, in practice almost always as a `<ds:X509Certificate>`. The element's `use` attribute is optional and takes a value from `md:KeyTypes`: - `use="signing"` — this key verifies content that the party produces. - `use="encryption"` — this key is what a counterparty encrypts content to, for that party to decrypt. - **omitted** — the key serves both purposes. The omission rule is the part candidates get wrong. It is not "signing by default"; it is "unrestricted". A document that leaves `use` off publishes one key for both jobs, which is legal, common in older integrations, and worth noticing because it removes the separation the attribute exists to provide. ## Direction matters, and it is easy to state backwards | `use` value | whose key | what the counterparty does with it | |---|---|---| | `signing` | the publishing party's | verifies content that party produced | | `encryption` | the publishing party's | encrypts content **to** that party | Both keys in the document belong to the party the document describes. The asymmetry is in who acts: for the signing key the counterparty is a verifier, for the encryption key the counterparty is an encryptor. Saying "the encryption key is the one I encrypt with, so it is mine" is the classic reversal — the key is theirs, the act is yours. ## The certificate is a carrier, not a chain The `<ds:X509Certificate>` inside `<ds:KeyInfo>` exists because it is a convenient, well-understood envelope for a public key. In a bilateral relationship, what makes that key trustworthy is that it arrived in the document you accepted out of band. Two consequences follow: - Such certificates are routinely **self-signed** and given long lifetimes; this is not a defect in a pairwise exchange. - The certificate's own validity dates and the document's `validUntil` are separate clocks, and they routinely disagree. The document's freshness is what governs whether you may act on the key. Certificate anatomy, extension handling and path processing are a different subject entirely; here the certificate is simply how the key travelled. ## Several key descriptors at once, and why A role descriptor may carry **more than one** `<KeyDescriptor>`, including more than one with the same `use`. That is not an error and there is **no precedence rule between them**: a consumer may accept any of the published signing keys. This is the mechanism behind a pairwise rollover: 1. Publish the incoming key as a second `<KeyDescriptor use="signing">`, with the outgoing one still present. 2. Wait for counterparty copies to turn over, which their `cacheDuration` bounds. 3. Begin producing content under the new key. 4. Withdraw the old `<KeyDescriptor>` in a later revision. If metadata allowed only one signing key per role, that overlap could not exist and every rollover would be a synchronised flag day across every counterparty. ## The production failure this causes The portal in the worked setting receives responses from several hundred licensed operators. One operator's document carries two `<KeyDescriptor>` elements — one `signing`, one `encryption`. If the portal's configuration flattened that into a single "partner certificate" field, one of three things happens: - It kept the first element and the first happened to be the encryption key — **nothing from that operator is ever accepted**, and the symptom is a blanket rejection with no obvious cause on the wire. - It kept the signing key and lost the encryption key — content the operator expects to be encrypted to it cannot be prepared. - It kept a single unrestricted key from an older document and the counterparty has since separated the two — the relationship quietly works until the split lands. The diagnostic instinct worth having: when a counterparty's content is rejected wholesale rather than intermittently, suspect the **wrong key of the right party** before suspecting the content. ## Which key is which, in one login Four keys take part and only two are `use` values: 1. The counterparty's **signing** key, from `<KeyDescriptor use="signing">`. 2. The counterparty's **encryption** key, from `<KeyDescriptor use="encryption">`. 3. The **transport** certificate presented by whatever endpoint is being called — unrelated to metadata and frequently issued by a different authority. 4. The **symmetric** key that actually encrypts the content, generated per message and wrapped for the recipient. An answer that conflates any two of those is the reason this question gets asked at all.

  • A counterparty's document carries a single `<KeyDescriptor>` with no `use` attribute. Is that valid, and what does it cost?
    Valid — the key serves both purposes. What it costs is separation: the same key pair both verifies their content and receives content encrypted to them, so the two roles cannot be rotated or scoped independently, and any change touches both at once. Splitting it later is a coordinated change on both sides.
  • Which key descriptor would you look at first when every response from one counterparty is rejected, and why?
    The one marked `signing`, and specifically whether your configuration is holding that key rather than the encryption key from the same document. Wholesale rejection of one party's content, with other parties unaffected, points at the wrong key of the right party far more often than at the content itself.
  • Is the certificate in a `<KeyDescriptor>` the same as the certificate the endpoint presents on its transport connection?
    Usually not, and nothing requires them to be. The metadata certificate carries the key for message-level signing or encryption and is often self-signed and long-lived; the transport certificate secures the connection to the endpoint's `Location` and is typically issued by a public authority with a short lifetime.

saying these in an interview costs you the question

  • Says use defaults to signing when the attribute is omitted
  • Thinks the encryption key belongs to the counterparty doing the encrypting
  • Assumes only one KeyDescriptor per role is allowed
  • Treats the metadata certificate as the endpoint's transport certificate
  • Expects a precedence order between two published signing keys
  • Believes the embedded certificate must validate to a public trust anchor