Skip to content

docs(examples): add the federated-union OpenID Federation demo - #418

Merged
osanderson merged 2 commits into
mainfrom
feat/examples-federated-union
Sep 29, 2026
Merged

osanderson merged 2 commits into
mainfrom
feat/examples-federated-union

Conversation

@osanderson

Copy link
Copy Markdown
Collaborator

Summary

A runnable showcase in the style of OID4VCgo's passport-vdc. Three fictional countries (Northland, Southport, Eastmark) each run their own identity federation, then join the Meridian Union, an OpenID Federation 1.0 trust anchor above them. A service in one country signs in a citizen of another, with no registration on either side beforehand.

cd examples/federated-union && go run ./cmd/federated-union
# https://console.localhost:8443/

Everything runs in one process: 15 entities, each at its own *.localhost host, on one TLS listener. Browsers resolve *.localhost to loopback natively, so there's no hosts-file setup.

What it shows

  1. Cross-border sign-in with no onboarding: the bank resolves EastID's Trust Chain (EastID → Eastmark authority → Union); EastID registers the bank automatically (§12.1).

  2. Layered policy: the Union's metadata policy narrows each service's grant types, and Southport adds its own requirement. The console compares declared and resolved metadata.

  3. Recognized assurance: identity providers carry level-of-assurance Trust Marks from accreditation offices listed in the Union's trust_mark_issuers. Services verify them with RequireFederationAccreditation.

  4. Data minimization: the bank requests claims (BeginAuthorizationRequest.Claims), and the citizen unticks what they won't share (ApprovedIdentityClaims).

  5. Console scenes:

    • forged mark: refused, because the issuer isn't accredited;
    • suspended country: cross-border sign-ins fail while domestic ones keep working;
    • compromised authority: the impostor is contained by the Union's naming constraints.

    A live log of federation traffic sits alongside.

How

Repo wiring

  • A new CI job, examples: vet, go test -race, and golangci-lint on the demo module.
  • release-please-config.json: exclude-paths: ["examples"].
  • sonar-project.properties: examples/** excluded from the coverage metric only; all other rules still apply.
  • The README links to the demo.

Testing

  • union/e2e_test.go boots the whole federation on a free port and drives each scenario through the actual pages, with a cookie-jar browser client:
    • a cross-border sign-in where the unshared address never reaches the bank;
    • a domestic sign-in;
    • a forged mark refused with 403;
    • suspension cutting off cross-border sign-ins only;
    • the impostor rejected through the Union but resolvable through Eastmark alone;
    • console pages rendering the policy narrowing.
  • go test -race and golangci-lint are clean on the demo module.
  • The binary was run live and its console and service pages were checked.

Developer-experience notes found while building it (follow-ups, not in this PR)

  • When automatic registration fails, the identity provider can only answer invalid_client: unknown client, and the embedder gets no reason either. The cause here, a missing token_endpoint_auth_signing_alg, took reading the source to find. A registration-failure hook would help.
  • federation.OpenIDRelyingPartyMetadata doesn't mention that private_key_jwt needs TokenEndpointAuthSigningAlg for a FAPIgo identity provider.

🤖 Generated with Claude Code

examples/federated-union runs three fictional countries' identity
federations joined into one OpenID Federation 1.0 trust anchor, the
Meridian Union, in one process with each entity at its own *.localhost
host. A service in one country signs in a citizen of another with no
prior registration on either side: services find identity providers by
resolving their Trust Chains, and identity providers register services
automatically. The Union's metadata policy and naming constraints apply
on top of each country's own, identity providers carry
level-of-assurance Trust Marks from accreditation offices the Union
lists in trust_mark_issuers, and citizens choose which requested claims
to share. A console shows every member, decodes its statements,
resolves any Trust Chain, logs federation traffic and runs three
scenes: a forged assurance mark, a suspended country, and a compromised
national authority contained by naming constraints.

It's a separate Go module built against this checkout, uses only the
public API, and has end-to-end tests for every scene. CI gains an
examples job for it; release-please and Sonar's coverage metric
exclude it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Share the demo's repeated literals as constants and a countryHost
helper, split the console's chain view out of its resolve handler,
and suppress text:S8566 for examples' go.mod files, which have no
third-party dependencies for a go.sum to pin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@osanderson
osanderson merged commit be841b9 into main Sep 29, 2026
11 checks passed
@osanderson
osanderson deleted the feat/examples-federated-union branch September 29, 2026 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant