👨🏻 Brother Talk — Phase 03, Off the Record
No slides, no STAR method. This is me, your brother, telling you the things people only say after the second coffee. Read it once now, and again the week before your interview.
Listen. Almost everyone who's "done auth" has wired an app to Entra with an SDK, watched the
login pop up, and moved on. What almost nobody can do — and what instantly separates a senior
from a principal in a security or platform interview — is draw the token flow from memory and
then list, in order, every check a service runs on the JWT it receives, and say what breaks if
you skip or reorder one. That gap — the inside of the token machine — is this whole phase.
Once you can narrate it, OAuth2 stops being three letters you nod at and becomes a sequence of
if statements you can defend line by line. And those if statements are, no exaggeration, the
most security-critical code you will ever write. Get them wrong and the firewall, the VNet, the
encryption — none of it matters, because the attacker walked in the front door holding a valid-
looking badge.
Here's the thing that took me too long to internalize: the SDK hides the part that matters.
acquireToken() and [Authorize] are beautiful until the day they're not — until a token is
getting rejected for a reason you can't see, or worse, accepted for a reason you didn't think
about. The engineers who get owned are the ones who treated auth as a library call. The ones who
go principal treated it as a protocol they could implement by hand. That's why we build the
validator in this lab from hashlib and hmac — not because you'll ship HS256 (you won't,
real Entra is RS256), but because once you've written the seven ordered checks, you own them.
They're not magic anymore. You can debug them at 2 a.m. and reason about them in a design review.
Now let me give you the things that actually bite people.
The aud check is the one. Love it, never skip it. I want you to overweight this, because
the industry under-weights it and it's where the real breaches live. A token can be perfectly
signed by Entra, perfectly current, from exactly the tenant you trust — and still be a weapon
against you, because it was minted for a different service and someone replayed it at yours.
The signature proves it's real. Only aud proves it's for you. That's the confused deputy,
and it is shockingly common in microservice meshes where everyone shares an issuer and a key.
When you can say in an interview "I verify the signature and I require my API in the aud,
because authenticity isn't audience" — that one sentence tells them you've actually thought
about token security instead of trusting a middleware default. Tattoo it: valid is not the same
as for-me.
Respect the order like it's load-bearing, because it is. Signature before you read any
claim — because until the signature verifies, that payload is just bytes an attacker handed you,
and reading exp or iss from it and acting on it is trusting the attacker. Pin the algorithm,
or someone sets alg:none and ships you an unsigned token your naive verifier happily "verifies."
Compare the signature in constant time, or you leak it byte-by-byte over a thousand requests.
Allow clock skew, or you take yourself down the next time an NTP server sneezes. None of these is
style. Each one is a real attack or a real outage with a name. The order is the security, and
the principal move is being able to justify every position in it, not just recite the list.
Understand authn vs authz so deeply it's boring. Who you are versus what you may do. A 401
versus a 403. The first half of your validator (signature, iss, aud, time) authenticates
the token; the second half (scp/roles) authorizes the action. People who blur this return
the wrong status codes, leak whether a resource exists, and build systems where "logged in" gets
confused with "allowed." When an interviewer asks the tired "what's the difference between
authentication and authorization" — most candidates recite a textbook line. You say "and here's
exactly where the line falls inside a JWT validator," and point at the two halves. That's the
difference between knowing the definition and having built the distinction.
The grant choice is a judgment call, and they're testing your judgment. When someone says "the service calls Graph," the junior says "use client credentials" because that's the snippet they remember. The principal says "as the app or as the user? Because if a user kicked this off and we use client-creds, we just elevated every downstream call to the app's permissions and erased the user from the audit trail — we want on-behalf-of." Same with SPAs: if you reach for the implicit flow, you've told them you stopped learning around 2018. Auth-code + PKCE, every time, for anything with a user and a browser. The grant is the identity model — picking it is the actual engineering, and picking wrong is the smell they're sniffing for.
The secretless thing is the future, and this phase is its foundation. PKCE's whole trick is prove you possess the verifier, don't store a password. Sit with that, because it's the same idea that runs the rest of your career: Managed Identity (P12) is a token from IMDS with no secret at all; OIDC workload-identity federation (P08) is your CI pipeline trading its own OIDC token for an Azure token with nothing stored to leak. The arc of cloud security is "stop storing secrets, start proving possession," and PKCE is where you first see the idea cleanly. The engineer who internalizes that stops asking "where do I put the client secret" and starts asking "why do I have one at all" — and that question is worth a level.
The honest truth about this phase: the code is not hard. HMAC is a library call, base64url
is twenty minutes, the flow is a handful of HTTP redirects. What makes this principal-level is
that it's unforgiving — security code that's 95% right is 0% secure, and the missing 5% is
always a check you skipped or mis-ordered. So don't rush the validator. For every line, ask:
what attack does this stop, and what happens if it's not here? The bad signature, the wrong
aud, the alg:none, the expired token, the missing scope — every negative test in the lab is a
real breach or a real outage someone lived through. Connect each one to its incident and the
knowledge becomes permanent instead of memorized.
And here's the career angle, brother to brother. Identity is the perimeter, which means the
people who truly understand it are trusted with the perimeter. Every other phase in this track —
RBAC, networking, secrets, the API gateway, the whole platform — sits behind the gate you build
here. If you own the token, you own the conversation about who gets in, and that's the
conversation principals get pulled into. The people who plateau treat auth as a solved library
problem; the people who go principal can open the box, find the missing aud check in a code
review, and explain in one calm sentence why it would've been a breach. Be that person. It starts
with the validator in this lab — write it by hand, break it on purpose, and watch it fail closed.
Go build the engine. Forge a token with the wrong aud and watch your validator reject it. Then
come find me in Phase 04 — that's where the token you just validated meets RBAC, and "who are
you" becomes "what, exactly, are you allowed to touch."
— your brother 👨🏻