05. Auth, OAuth, JWT, and Sessions — let the wait staff check identity before service starts¶
~18 min read. Security gets clearer when you separate proving identity from deciding permission.
Built on the ELI5 in 00-eli5.md. The wait staff — the people who check who may enter, what they may ask for, and when service must stop — become your authentication and authorization layers.
1) Authentication and authorization are different questions¶
Authentication asks, "Who are you?" Authorization asks, "What may you do?" See. Teams confuse them all the time. That confusion creates weak designs.
Example. A user signs in with email and password. If the password is correct, authentication succeeds. Now the system knows the identity. Later, that same user tries to refund an order. Authorization decides whether this identity has refund rights.
A compact path:
User ──▶ login proof ──▶ identity established
User ──▶ action request ──▶ policy check on that identity
The wait staff analogy fits well. One person checks your booking or ID at the door. Another checks whether your ticket includes the private lounge. Not the same job. Simple, no?
Worked example with numbers. Imagine 50,000 daily active sellers on a marketplace. Only 600 finance admins may download payout reports. Authentication can identify all 50,000. Authorization must still block 49,400 from the report action. So never say, "User is logged in, so allow it." That is incomplete security thinking.
2) Sessions, JWTs, and API keys solve different access shapes¶
Session-based auth stores server-side session state. The browser usually carries a session id in a cookie. The server looks up the session and finds the user context. This fits classic web apps well.
Session flow:
Browser ──▶ login ──▶ Server creates session `s_91`
Browser ◀─ Set-Cookie: session=s_91
Browser ──▶ next request with cookie ──▶ Server loads session data
JWT-based auth stores claims inside a signed token. The server verifies the token signature, then reads claims like user id, role, and expiry. It reduces server-side lookup pressure in some designs, but revocation becomes trickier.
JWT structure has three parts:
- Header.
- Payload.
- Signature.
Example shape:
API keys are simpler. They usually identify a service, script, or partner integration, not a human login session. You issue the key, store it hashed, and apply quotas and scopes around it.
Worked comparison. A browser dashboard for internal staff often works cleanly with sessions. A mobile app talking to an API often uses short-lived JWT access tokens. A partner warehouse integration running nightly sync jobs often uses API keys or OAuth client credentials. The wait staff choose the right entry rule for the right guest.
3) JWTs help stateless APIs, but token lifecycle matters more than token shape¶
People talk about JWT format a lot. Good teams talk about expiry, rotation, storage, and revocation more. See. A pretty token format alone solves nothing.
Important JWT claims often include:
subfor subject.issfor issuer.audfor audience.expfor expiry.scopeor role data.
A safe access-token pattern:
- Access token lives 10 to 15 minutes.
- Refresh token lives days or weeks.
- Refresh token rotation is enabled.
- Stolen refresh tokens can be revoked.
Worked example. Assume an access token lasts 12 minutes. A thief steals it from bad frontend storage. The damage window is limited. If the same token lasted 30 days, that mistake becomes a gift to attackers. So what to do? Keep access tokens short-lived, and protect refresh logic strongly.
One more point. JWT payload is not encrypted by default. It is encoded. Do not place secrets in it. Clients can read the claims. The signature prevents tampering, not visibility.
4) OAuth 2.0 is delegated authorization, not "login with extra steps"¶
OAuth helps one application obtain limited access to another system on a user's behalf. That is delegation. A user grants scope. The client receives tokens. The resource server validates them.
Common OAuth flows to know:
- Authorization code with PKCE for browser and mobile apps.
- Client credentials for machine-to-machine service access.
- Refresh token flow for renewing access without full login again.
Authorization code with PKCE, very roughly:
App ──▶ Auth server login page
User authenticates
Auth server ──▶ code back to app
App ──▶ code + verifier ──▶ token endpoint
App ◀─ access token + refresh token
Why PKCE? It protects the code exchange from interception abuse, especially in public clients that cannot keep a client secret safely. That matters a lot for mobile and SPA contexts.
Worked example with numbers. A travel app wants read-only calendar access. Request scope
calendar.read, not full account control. If the token leaks, the blast radius stays narrower.
Scopes are not paperwork. They are safety boundaries.
5) Session revocation, refresh rotation, and authorization checks finish the real design¶
Token lifecycle is where mature systems separate from demo systems. A good design answers these questions clearly:
- How do users log out everywhere?
- How do you revoke a compromised refresh token?
- How do you rotate signing keys safely?
- Where do scopes and roles get checked?
- How do you audit sensitive actions?
A practical lifecycle diagram:
login ──▶ access token 12 min
│
└──▶ refresh token 14 days
│
├── rotate on use
├── revoke on suspicion
└── expire on logout or inactivity
Authorization checks should happen near each protected action. Do not trust UI hiding alone. If
DELETE /v1/users/88 needs admin scope, check that at the API layer every time. The wait staff
do not stop checking after the guest sits once. They keep enforcing house rules.
Worked example. Suppose a refresh token is reused from two IP regions within 3 minutes. That is suspicious. You can revoke the token family, force re-login, and alert the user. If you never track refresh token rotation state, you miss that attack signal completely.
Mini worked example. An internal admin cookie can carry only a session id, while the real role data stays server-side. That reduces token leakage value in the browser.
Another warning. Do not store access tokens in places where random scripts can read them easily. Storage choice changes theft risk materially.
One more control. Signing keys should rotate without breaking every active client at once. That usually means key ids and overlapping validation windows. See. Auth design is not one decision. It is a lifecycle. Door check, action check, ongoing trust.
Where this lives in the wild¶
- An Okta identity engineer designs token issuance, refresh rotation, and revocation so enterprises can trust delegated access flows.
- A Google Workspace security engineer separates identity proof from fine-grained permission checks across many admin actions.
- A Razorpay security engineer protects merchant APIs with API keys, scoped access, and strong audit trails for sensitive operations.
- A GitHub identity engineer uses OAuth scopes and token controls so third-party apps get limited repository access instead of full user power.
- A Swiggy platform engineer may combine mobile JWT access tokens with short expiries and server-side checks around delivery and payout actions.
Pause and recall¶
- What is the difference between authentication and authorization?
- Why is a short-lived access token safer than a month-long one?
- When does session-based auth fit better than API keys?
- What problem does OAuth authorization code with PKCE solve?
Interview Q&A¶
Why not store everything in a long-lived JWT and skip refresh tokens?¶
Long-lived bearer tokens expand the damage window after theft and make revocation painful. Short-lived access tokens plus refresh rotation are much safer operationally. Common wrong answer to avoid: "JWTs are stateless, so they should never expire quickly."
When would you choose server-side sessions over JWT access tokens?¶
Sessions fit browser-centric apps well when the server can store state and revoke access immediately. They also work nicely with secure cookies and CSRF protections. Common wrong answer to avoid: "Sessions are outdated and should always be replaced by JWTs."
What does OAuth solve that normal login does not?¶
OAuth lets one client gain limited access to another resource server on behalf of a user or itself. It is about delegated access and scopes, not only primary login UX. Common wrong answer to avoid: "OAuth is just social login branding."
Why must authorization checks stay server-side even if the UI hides buttons?¶
Because attackers can call APIs directly without your UI, and stale clients may still send forbidden actions. Server-side policy enforcement is the real control point. Common wrong answer to avoid: "If the frontend hides admin actions, normal users cannot trigger them."
Apply now (5 min)¶
Exercise. Design auth for an admin dashboard, a mobile consumer app, and a partner warehouse script. Choose sessions, JWTs, OAuth, or API keys for each case, and justify the choice in one line each. Then set access-token and refresh-token lifetimes with numbers.
Sketch from memory. Draw login, access token, refresh token, and protected API action. Then say where identity is proven, where permission is checked, and where revocation state lives.
Bridge. Once identity and permission rules exist, the next question is where they get enforced across many services. That is the API gateway and routing layer. → 06-api-gateway-and-routing.md