Lion Cipher Lab
Build an OpenID Federation trust chain from scratch: entity statements, trust anchors, and chain resolution with no shared secrets
- Identity & Access Management
- Advanced
- ~90 min
- Free · no account required
Why it matters
Every OpenID Connect deployment you have ever configured was bilateral: a human registered the relying party at the provider, got back a client_id and usually a client_secret, and pasted it into a config file. That is fine for ten apps. It is impossible for a national eID scheme, a research-and-education federation spanning thousands of universities, or a wallet ecosystem where issuers and verifiers who have never met must still trust each other. It also has no bulk revocation story and no way to say 'trust anyone this authority vouches for, but only for these capabilities'. OpenID Federation…
What you'll learn
- explaining why bilateral OIDC client registration is O(n*m) and where it breaks
- reading the OpenID Federation entity statement claims off the spec: iss, sub, iat, exp, jwks, metadata, authority_hints, metadata_policy
- minting signed Entity Configurations and Subordinate Statements as ES256 JWTs by hand
- publishing a federation over the /.well-known/openid-federation path and a fetch endpoint
- writing a trust chain resolver: walk UP by authority_hints, verify DOWN from the trust anchor
- implementing the metadata policy operators (value, add, default, one_of, subset_of, superset_of, essential) in the spec's order
- watching a leaf's over-broad metadata get clipped, and a policy conflict correctly fail the whole chain
- diagnosing the four ways a chain dies: bad signature, expired statement, unanchored root, policy conflict
- judging when federation is worth it versus SAML metadata aggregates, RFC 7591 dynamic registration, or just registering ten clients by hand
Steps in this lab
- The problem: bilateral registration is O(n*m) paperwork, and it has no revoke button
- The model, defined from zero: entities, statements, anchors, and which way each arrow points
- Set up the project and install the one dependency you actually need
- fedlib.py — write the JWS, JWK and signature plumbing yourself
- Define the federation and mint every statement in it
- serve.py — publish the federation over HTTP on six ports
- Look at the wire: what an entity statement actually is
- policy.py — implement the metadata policy operators the spec's way
- resolve.py — walk UP by authority_hints, verify DOWN from the anchor
- Run it: a chain resolves, and the RP loses the argument
- Break it, part one: a tampered signature and an expired statement
- Break it, part two: the unanchored chain — a valid JWT with the wrong trust root
- Break it, part three: two superiors demanding incompatible values
- Named failure modes and the operational reality nobody warns you about
- When to reach for this — and when it is absolutely the wrong tool
- The judgment: trust is a decision you make in advance, and everything else is arithmetic