Systems Thinking
Authentication Is a Relay Race
Federated and proxied authentication isn't one check — it's a request handed between many parties, any of which can reject it, drop it, or pass it on. If you can't see which leg failed, you can't debug it.
- Systems Thinking
- Networking
- Authentication
- Debugging
People picture authentication as a single yes-or-no gate: present a credential, get an answer. In any federated or roaming system, it’s nothing like that. A real authentication request is a relay race — handed from the device, to an access point, to a routing layer, possibly proxied off to an entirely different organization’s identity server, through a multi-step credential exchange, and back. Each handoff is a place the request can be rejected, dropped, transformed, or sent somewhere unexpected. Once you see auth as a chain of legs instead of one check, both the design and the debugging change completely.
One “login” is many handoffs
I came to this watching how a roaming Wi-Fi authentication actually travels. A device associates and submits credentials, but that’s the starting gun, not the finish. The request gets classified, routed based on the identity’s realm, and then either handled locally or proxied to a partner’s authentication server — because the user might belong to a different provider entirely. Then a multi-round credential exchange runs, backend lookups happen, and only after all of that does an accept or reject come back.
That’s at least half a dozen distinct legs, several of them crossing trust and network boundaries, some of them leaving your infrastructure entirely. Calling the whole thing “login” hides the structure that matters. The user experiences one moment; the system runs a relay with many runners, and any one of them can drop the baton.
Realm routing decides who even runs the race
The first interesting leg is routing: figuring out which identity authority should handle this request at all. In a federated setup, the identity carries a realm — the part that says which organization owns this user — and a routing layer uses it to decide whether to terminate locally or hand off to a partner. Get this leg wrong and everything downstream is moot; the request runs to the wrong finish line or gets rejected before it starts.
This is also where a lot of policy lives: some realms are handled here, some are proxied there, some are rejected outright as a matter of policy. The routing decision is its own distinct stage with its own failure modes — “I sent it to the wrong place” and “I refused to send it anywhere” are different failures than “the credential was bad,” and they happen earlier.
Any leg can reject, drop, or proxy
The reason the relay framing is so useful for debugging is that the legs fail differently, and the user-facing symptom — “I couldn’t connect” — looks identical regardless of which one failed. The routing layer can refuse. The proxy to a partner can time out. The partner’s own identity server can reject the credential. A backend lookup mid-exchange can error. The multi-round credential handshake can stall waiting for a step that never comes.
“Authentication failed” is the aggregate result of a relay you can’t see. The useful question is never did it fail — it’s which runner dropped the baton.
If your only signal is the final accept/reject, you’re blind to all of this. A rejection from your own policy and a timeout proxying to someone else’s server are completely different problems with completely different fixes, and they’re indistinguishable unless the system tells you which leg produced the outcome.
Build visibility per leg, not just at the finish
The practical consequence: design federated auth so each leg is observable on its own. You want to be able to answer, for any given attempt, how far did it get and where did it stop? Did routing pick a destination? Did the proxy reach the partner? Did the credential exchange complete its rounds? Did the backend lookup return? A trace that shows the baton’s progress through the relay turns an opaque “auth failed” into a precise “it failed at the proxy handoff to that partner.”
This is the difference between debugging by guess and debugging by inspection. Without per-leg visibility, a federated auth problem becomes a finger-pointing exercise — is it us, is it them, is it the network in between? With it, you can say exactly which runner stopped, which usually also tells you whose problem it is, which is half the battle when the relay crosses organizational lines.
The pattern beyond Wi-Fi
This isn’t a networking-only lesson. Any time authentication spans multiple parties — single sign-on bouncing through an identity provider, a token validated against a remote authority, a chain of services each re-checking authorization — you’ve got a relay race. The same rules apply: name the legs, know which party owns each one, and instrument the handoffs so a failure tells you where it happened, not just that it happened.
It connects to two things I’ve written before. A TLS handshake failure is really a trust problem between two parties — one leg of exactly this kind of relay, where the failure is about the relationship, not just the bytes. And access control is a pipeline, not a switch: authorization, like authentication, is a sequence of stages, and treating it as a single gate hides the stage that’s actually failing. Design the relay so you can watch the baton. If you’re debugging a federated auth flow that fails in ways nobody can localize, I’m easy to reach.