skip to content

In OpenID Federation 1.0, what distinguishes an Entity Configuration from a Subordinate Statement?

level: middleimportance: should knowfreq 38%

answer

  1. one container, two subject relationships
  2. iss equals sub means self-issued
  3. Superior's statement carries the subject's keys
  4. policy only travels downward
  5. authority_hints never in a Subordinate Statement

basics

~20 s

Both are Entity Statements, but an Entity Configuration is self-issued, with iss equal to sub, and served from the entity's own well-known path. A Subordinate Statement is issued by a Superior about an entity immediately beneath it, so iss and sub differ.

solid answer

~40 s

An **Entity Statement** is a signed JWT with the `typ` header `entity-statement+jwt`, carrying at least `iss`, `sub`, `iat`, `exp` and `jwks`; its `alg` must not be `none`. Which of the two kinds you are holding is decided by the subject relationship. If `iss` equals `sub`, it is an **Entity Configuration**: the entity's self-description, fetched from its own `/.well-known/openid-federation` path, carrying its `metadata`, its `authority_hints` and any `trust_marks` it claims. If `iss` differs from `sub`, it is a **Subordinate Statement**: the Superior's attestation about an entity below it, fetched from the Superior's `federation_fetch_endpoint`, carrying that subject's federation keys as the Superior attests them, plus `metadata_policy` and `constraints`. `metadata_policy` appears only in a Subordinate Statement.

code

json · 16 lines
json
{
  "iss": "https://op.trust-a.schools.example",
  "sub": "https://op.trust-a.schools.example",
  "iat": 1758240000,
  "exp": 1758326400,
  "jwks": {
    "keys": [
      { "kty": "RSA", "use": "sig", "kid": "fed-2026a", "n": "0vx7ag…", "e": "AQAB" }
    ]
  },
  "authority_hints": [ "https://intermediate.schools.example" ],
  "metadata": {
    "openid_provider": { "issuer": "https://op.trust-a.schools.example" },
    "federation_entity": { "organization_name": "Trust A" }
  }
}

go deeper

for a junior

Recall that a federation entity both describes itself and is described by the party above it, and that these are two separate signed documents fetched from two different places.

for a middle

Explain the discriminator — iss equal to sub or not — and name what only the Superior's statement can carry: the attested key set, metadata_policy and constraints.

for a senior

Be able to debug from it: if a member's change appears in its own Entity Configuration but nothing downstream sees it, look at what the Superior last attested and when that statement expires.

for a principal

Consider what belongs to the member and what belongs to the operator. Everything you push into policy is something members can no longer change without you, and everything you leave out is something you cannot enforce.

## One container, two roles OpenID Federation 1.0 has a single wire object, the **Entity Statement**: a JWT signed with a key of the issuer, with the `typ` header `entity-statement+jwt` (media type `application/entity-statement+jwt`) and an `alg` that must not be `none`. Every statement carries `iss`, `sub`, `iat`, `exp` and `jwks`. The container is used in two distinct roles, and confusing them is the commonest early mistake in this material — not least because people call both "the entity's metadata", which names neither. ## Entity Configuration: what an entity says about itself An **Entity Configuration** has `iss` equal to `sub`: the entity issued a statement about itself, signed with its own federation key. It is published at the entity's `/.well-known/openid-federation` path, so any party that knows the **Entity Identifier** can fetch it without asking anyone. It typically carries: - `jwks` — the entity's own federation keys, as it declares them; - `authority_hints` — the Entity Identifiers of its **Immediate Superiors**. This is **required** in the Entity Configuration of any Entity that has a Superior, and it must not be an empty array. A **Trust Anchor**, having no Superior, does not carry it; - `metadata` — keyed by Entity Type Identifier: `federation_entity`, `openid_provider`, `openid_relying_party`, `oauth_authorization_server`, `oauth_client`, `oauth_resource`; - `trust_marks` — the marks the entity claims to hold, each an object with a `trust_mark_type` and the signed `trust_mark` itself. Note what it is worth on its own: nothing. It is self-signed, so it proves only that whoever holds that key wrote it. ## Subordinate Statement: what a Superior says about someone below A **Subordinate Statement** has `iss` different from `sub`. The issuer is a Superior — an **Intermediate Entity** or the Trust Anchor — and the subject is one of its **Immediate Subordinates**. It is not published at the subject's well-known path; it is served by the Superior from its `federation_fetch_endpoint`, which Intermediates and Trust Anchors must publish and Leaf Entities must not. Its `jwks` is the load-bearing part: these are the **subject's** federation keys *as the Superior attests them*. That is what turns a self-signed Entity Configuration into evidence — you verify the subject's self-description with keys handed down from above, not with keys the subject published about itself. A Subordinate Statement may also carry: - `metadata_policy` and `metadata_policy_crit` — rules the Superior imposes on the subject's resolved metadata. **These appear only here**, never in an Entity Configuration; - `constraints` — `max_path_length`, `naming_constraints`, `allowed_entity_types`; - trust-mark governance claims, which are honoured only when the issuer is a Trust Anchor. | | Entity Configuration | Subordinate Statement | |---|---|---| | `iss` vs `sub` | Equal | Different | | Signed by | The subject itself | The subject's Superior | | Fetched from | `/.well-known/openid-federation` of the subject | The Superior's `federation_fetch_endpoint` | | Whose keys are in `jwks` | The subject's, self-declared | The subject's, attested by the Superior | | May carry `authority_hints` | Yes, and required if it has a Superior | No | | May carry `metadata_policy` | No | Yes | ## Why the split exists Separating the two lets the subject own its own description while the federation owns the attestation. A member can change a contact address or add an endpoint in its own Entity Configuration without the operator signing anything. But it cannot give itself a new signing key that anyone will honour, cannot widen what its metadata resolves to past the anchor's policy, and cannot keep itself in the federation once the Superior stops issuing statements about it. The self-description is free; the attestation is not. That also explains the fetch paths. The self-description lives where the name points, so discovery needs nothing but the Entity Identifier. The attestation lives with the party that made it, so withdrawing it is a local act by the Superior rather than a request to the subject to delete something.

  • Which entity's Entity Configuration carries no authority_hints, and why?
    A Trust Anchor's. `authority_hints` names an entity's Immediate Superiors, and a Trust Anchor is defined as having none. The claim is required in the Entity Configuration of any entity that does have a Superior, and it must not be present as an empty array — an empty array is not the way to say "I am an anchor".
  • If a Subordinate Statement lists keys for its subject, why does the subject publish jwks too?
    Because the two are used at different moments. The subject's own `jwks` lets anyone read its self-description straight from its well-known path, and the Superior's attested `jwks` is what a verifier actually uses to check that self-description while walking a Trust Chain. If they disagree, the attested set is the one that carries authority.
  • Which of the two kinds may carry metadata_policy?
    Only a Subordinate Statement. Policy is something a Superior imposes on an entity below it, so it travels downward in statements the Superior signs. An entity cannot write policy about itself into its own Entity Configuration, which is what stops a member from granting itself latitude the federation did not give it.

saying these in an interview costs you the question

  • Calls both kinds the entity's metadata without saying which
  • Thinks a Superior's statement replaces the entity's own configuration
  • Assumes a Subordinate Statement's jwks holds the Superior's keys
  • Says an Entity Configuration is fetched from the Superior
  • Treats entity-statement+jwt as an unsigned JSON document