In SAML 2.0, what does a party's `<EntityDescriptor>` metadata document declare, and what does exchanging it establish?
answer
- one document, one party
- entityID names software, not a person
- role descriptors hold the content
- keys, endpoints, NameID formats
- trust comes from the exchange itself
basics
~20 sA SAML EntityDescriptor names one party by its entityID and declares, per role, the endpoints it exposes, the public keys it signs with or is encrypted to, and the NameID formats it supports. Two exchanged documents are the trust relationship.
solid answer
~40 sA SAML 2.0 metadata document describes exactly one party. Its `<EntityDescriptor>` carries `entityID`, an absolute URI that names that party's deployed software — not a person — and is compared byte for byte rather than fetched. Beneath it sit role descriptors: `<IDPSSODescriptor>`, `<SPSSODescriptor>`, `<AttributeAuthorityDescriptor>`, or a generic `<RoleDescriptor>`, each carrying `protocolSupportEnumeration` to say which protocol it speaks. Inside a role descriptor are `<KeyDescriptor>` elements holding public keys, declared endpoints such as `<SingleSignOnService>`, `<AssertionConsumerService>`, `<SingleLogoutService>` and `<ArtifactResolutionService>`, and `<NameIDFormat>` elements listing supported subject-identifier formats. Nothing outside the exchanged pair vouches for any of it: in a bilateral relationship the trust comes from having accepted the counterparty's document out of band, which is why the certificates inside it are routinely self-signed.
code
xml · 20 lines<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
entityID="https://portal.regulator.example/saml"
cacheDuration="PT12H">
<md:SPSSODescriptor
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"
WantAssertionsSigned="true">
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Certificate>MIIC...</ds:X509Certificate>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:AssertionConsumerService index="0" isDefault="true"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://portal.regulator.example/saml/acs"/>
<md:SingleLogoutService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://portal.regulator.example/saml/slo"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>go deeper
Recall the shape: one XML document per party, naming that party and listing where to reach it and which public keys to believe. Know that the two parties swap documents before any login works.
Explain the nesting: EntityDescriptor with entityID, then role descriptors carrying protocolSupportEnumeration, then key descriptors, declared endpoints with Binding and Location, and NameIDFormat entries. Say why endpoints are declared and never discovered.
Show what the exchange costs to operate: every counterparty is a configuration act on both sides, the keys are trusted only because the document was accepted, and a missing or wrong endpoint is invisible until a real login hits it.
Weigh bilateral exchange against the alternatives at estate scale: a few hundred pairwise relationships means a few hundred documents to keep current, with no operator above the pair to police any of it.
## What a SAML metadata document is A SAML 2.0 metadata document is an XML instance that describes **one party** to a federation relationship. For a single party the root element is `<EntityDescriptor>`, and its `entityID` attribute is that party's name: an absolute URI, chosen once, treated as an opaque string by everyone who reads it. Two properties of `entityID` catch people out: - It names **an organisation's deployed software**, not a human being. The identifier for a person travels inside an assertion, as a different element entirely. - It is conventionally written as an `https://` URI, but a counterparty **compares it, it does not dereference it**. The document may well be published somewhere else, or handed over as a file. Several `<EntityDescriptor>` elements may be wrapped in an `<EntitiesDescriptor>` container. In a strictly pairwise relationship that container rarely earns its keep; it exists for the case where one document carries many parties. ## Role descriptors: which hat the party wears An entity is described **per role**, and a role descriptor is what actually holds the useful content: - `<IDPSSODescriptor>` — the party in its identity-provider role. - `<SPSSODescriptor>` — the party in its service-provider role. - `<AttributeAuthorityDescriptor>` — the party answering attribute queries. - `<RoleDescriptor>` — the generic form, for a role the metadata schema does not define. One entity may carry more than one of these; a party that both consumes assertions from partners and issues them to others publishes both SSO role descriptors under a single `entityID`. Every role descriptor carries **`protocolSupportEnumeration`**, a whitespace-separated list of protocol URIs — `urn:oasis:names:tc:SAML:2.0:protocol` for SAML 2.0. When an entity publishes two role descriptors of the same type, that attribute is what selects between them. ## What sits inside a role descriptor | element | what it declares | shape | |---|---|---| | `<KeyDescriptor>` | a public key, with `use` drawn from `md:KeyTypes` (`signing`, `encryption`) | wraps `<ds:KeyInfo>`, usually a `<ds:X509Certificate>` | | `<SingleSignOnService>` | where the identity-provider role receives requests | `Binding` + `Location` | | `<AssertionConsumerService>` | where the service-provider role receives responses | indexed: adds `index`, `isDefault` | | `<SingleLogoutService>` | where logout messages are received | `Binding` + `Location` | | `<ArtifactResolutionService>` | where artifact resolution is answered | indexed: adds `index`, `isDefault` | | `<NameIDFormat>` | a subject-identifier format the role supports | a URI, repeatable | ## Endpoints are declared, not discovered There is no probing step in SAML. An endpoint the counterparty can use is an endpoint that appears in the document, with two attributes on it: **`Binding`**, holding the binding URI such as `urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST`, and **`Location`**, holding the URL. Indexed endpoints — `<AssertionConsumerService>` and `<ArtifactResolutionService>` — additionally carry **`index`**, a small integer that lets one endpoint be referred to by number rather than by URL, and **`isDefault`**, marking which is used when nothing selects. How messages are encoded onto those bindings, and which message goes where, are separate subjects; metadata only publishes the addresses. `<NameIDFormat>` elements are a capability statement in the same spirit: they say which subject-identifier formats this role can handle, for example `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent`, `urn:oasis:names:tc:SAML:2.0:nameid-format:transient`, or `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress` — which keeps the older prefix. What such an identifier *means* once it appears in an assertion is the assertion's business, not the document's. ## Why exchanging two documents is the trust relationship In the bilateral case there is no third party vouching for anybody. A regulator's licensee reporting portal and one licensed operator's identity provider each publish one document; each side accepts the other's, out of band, once. From that moment: 1. The keys in the counterparty's `<KeyDescriptor>` elements are believed **because the document was accepted**, not because a certificate chains anywhere. This is why those certificates are commonly self-signed and given long lifetimes — they are key carriers. 2. The endpoints in it are the only addresses either side will use. 3. Adding a counterparty is a configuration act on **both** sides; so is removing one. Because the whole relationship rests on a cached copy of an XML file, the document must also say **when to stop believing it**. That is what `validUntil` and `cacheDuration` are for, and the root element of a metadata instance is required to carry at least one of them.
- One party both issues assertions to partners and consumes them from others. How does its metadata express that?As one `<EntityDescriptor>` with a single `entityID`, carrying two role descriptors: an `<IDPSSODescriptor>` and an `<SPSSODescriptor>`. The entity is one party; the roles are what differ. A counterparty reads whichever role descriptor matches the relationship it has, selecting on `protocolSupportEnumeration` if more than one of a type appears.
- What is the `index` attribute on an `<AssertionConsumerService>` for?It gives that endpoint a stable small-integer handle within the role descriptor, so a message can name the endpoint by number instead of repeating its URL. `isDefault="true"` marks the one used when nothing selects. It is unrelated to the `SessionIndex` value that names a session on a participant — same word, different mechanism.
- Why are the certificates inside a `<KeyDescriptor>` so often self-signed?Because in a bilateral exchange the certificate is only a carrier for a public key. The reason a counterparty believes the key is that it arrived in the document that party accepted out of band, not that the certificate chains to a public trust anchor. That is also why they tend to be issued with very long lifetimes.
Two firms swapping signed letterheads and a list of postal addresses before they will accept each other's paperwork: nobody notarises the swap, the exchange itself is what makes each side's letterhead recognisable.
saying these in an interview costs you the question
- Says entityID identifies the logged-in user rather than the party
- Assumes a counterparty fetches the document from the entityID URI
- Thinks the certificate in a KeyDescriptor must chain to a public CA
- Believes endpoints can be discovered or probed instead of declared
- Treats the document as describing both parties rather than one