Index

Auth, end to end: passwords, tokens, OAuth, OIDC, SSO and SAML

Chapters

Narration

Every login you have ever done answers two completely different questions. Who are you? And what are you allowed to do? Authentication, and authorization. Almost every real data leak is a system that checked the first one and forgot the second. Authentication runs on three kinds of proof. Something you know — a password. Something you have — a phone, or a hardware key. And something you are — a fingerprint, a face. Multi factor means two of these three. A password plus a security question is still only one. Now store that password. Plain text is the disaster: one breach and every account is gone. Encrypted looks safer and is not — encryption is reversible, and the key sits on the same server that just got stolen. Only a hash is one way. A bare hash still breaks twice. Precomputed tables reverse common passwords instantly, so you add a salt — random, per user, so no two hashes match. And a graphics card tries billions per second, so you use a deliberately slow hash. Argon two. Hashed, salted, slow. One factor is never enough, but the second factor has a ladder. Text messages lose to a sim swap. Time based codes are stronger, until you type one into a fake site. Push prompts get spammed at three in the morning until somebody taps approve. Passkeys end the argument. Your device holds a private key and signs a challenge, and the signature is bound to the site's real address. A phishing page has a different address, so the signature it collects is worthless. Phishing resistant by construction, not by being careful. You logged in once. Now every single request has to prove it is still you, and you cannot send the password again each time. So the server hands you something to carry. There are two designs, and the whole difference is who keeps the state. A session keeps the state on the server. It stores a record, and gives you a random id in a cookie. Every request, the server looks that id up. Deleting the record logs you out instantly — but now every server needs to reach the same store. A token keeps the state in your pocket. The server signs a small document saying who you are, and hands it over. Next request, it checks its own signature and trusts it. No lookup, no shared store, no database on the hot path at all. So the trade is exact. A session can be revoked the instant you click log out, because the truth lives on the server. A token cannot — it is valid until it expires. That is why access tokens live fifteen minutes, and a refresh token quietly issues the next one. That signed document is usually a J W T. Three pieces joined by dots: a header, a payload of claims, and a signature. The payload is base sixty four, not encryption. Anyone holding the token can read every claim in it, so never put a secret inside one. Where you keep it decides which attack kills you. Local storage is readable by any script on the page, so one cross site scripting bug takes every token. A cookie marked http only, secure, and same site is invisible to scripts and never sent cross site. A valet key starts the car and opens nothing else. That is the whole idea of OAuth. Some app wants your photos. The wrong answer is to give it your password, because a password is every door. OAuth gives it a valet key instead. There are four roles and they are worth naming properly. You are the resource owner. The app asking is the client. The authorization server is what issues tokens. And the resource server is the A P I actually holding your data. Four boxes, one token. Step one, the app sends you to the authorization server. Not a popup it drew — the real site, on the real domain. You log in there, and you see a consent screen listing exactly what it is asking for. Read photos. Nothing else. You approve, and it redirects back with a short lived code. Not the token. The app then swaps that code, plus its own secret, on a direct server to server call. The code travels through your browser. The token never does. A phone app or a single page app has no secret to keep — anyone can pull it apart. So P K C E replaces it. The app invents a random value, sends only its hash up front, and reveals the original when it redeems the code. Three guardrails hold it together. The redirect address must match exactly, or a stolen redirect leaks your token. A random state value proves the callback is the one you started. And the scope is the smallest thing that works, never everything. And here is the part people skip. A scope says what the token may ask for. It never says which rows belong to you. If the A P I trusts the scope and forgets to check ownership, anyone can change an id and read a stranger's data. Not every caller is a person. When one service calls another, there is nobody to redirect and no consent to give. Client credentials is the grant for that. The app authenticates as itself and gets a token for its own access. No user anywhere. Now a television. No keyboard, no browser worth using. The device asks for a code, puts a short one on screen with a web address, and starts polling. You approve it on your phone. The next poll comes back with a token. Refresh tokens are how a short lived token stays convenient. Rotate them: every refresh issues a new one and burns the old. If an old one is ever presented again, that is proof it was stolen — kill the entire chain. Two grants are dead and it is worth knowing why. Implicit returned the token directly in the browser address bar. That lands in history, in referrer headers, in every extension you installed. PKCE made it unnecessary, and version two point one removed it. The other one had the app collect your username and password directly and forward them. That is exactly the thing OAuth exists to prevent. Also gone. What survives is one shape: authorization code, with PKCE, every time, for everyone. Now the mistake that is everywhere. OAuth gave the app a token to use an A P I. It never said who you are. An access token is a valet key. It is not an identity card, and treating it as one is a real vulnerability. Watch it break. A hostile app collects a token you granted to it, and hands that token to a different site's log in. If that site simply calls who am I with the token it was given, it logs the attacker in as you. Open I D Connect is a thin layer on top that fixes this. It returns a second token — an I D token, a signed J W T about the user, meant for the app itself. Access token goes to the A P I. I D token stays home. Inside it: who issued it, a stable subject id, an expiry, a nonce that stops replay — and an audience field naming your client. That audience is what makes substitution impossible. Check it. And use the subject as the user key, never the email address. The rest is plumbing you get for free. A well known discovery document, a published key set so signatures verify and keys rotate, and a user info endpoint. Log in with a big provider is this, every time. OAuth is access. Open I D Connect is identity. Single sign on is one login for many applications. It needs an authority everyone agrees to trust: the identity provider. Each application is a service provider. When that trust crosses a company boundary, the word for it is federation. The trick is that there are two sessions, not one. A long one at the identity provider, and a short one at each application. Open a new app and it bounces you to the provider, which already knows you, and bounces you straight back. SAML is how the enterprise has done this for twenty years. You hit the app with no session. It sends you to the provider with a signed request. You authenticate. The provider posts back a signed assertion, and the app makes you a session. The assertion is signed X M L, and four parts matter. The subject, which is you. A validity window. An audience restriction naming this one application. And an attribute statement carrying your email and your groups — which is where your roles come from. Every SAML attack is an attack on that signature. Wrapping moves the signed element somewhere else in the document, so the validator checks one node while the parser reads another. And forgetting the audience check means an assertion for one app opens a different one. So which one? SAML is X M L and browser form posts, it has no real mobile story, and it hands you no A P I token. Open I D Connect is J S O N and J W Ts and works everywhere. Build new on Connect. Ship SAML because buyers ask for it. One last piece, and it is the one that gets forgotten. Single sign on handles logging in. It does not handle leaving. SCIM is the provisioning channel that creates and, far more importantly, deactivates accounts everywhere the moment somebody walks out. So: hashed, salted, slow for the password. Session or token depending on whether you need revoke or scale. OAuth for access, Open I D Connect for identity, SAML for the enterprise. And never, ever let a valid login stand in for a valid permission.

Saved in this browser only.