Rapid-Fire: Fundamentals

The opening questions in every API authentication interview, with the answer a senior candidate gives.

These come early and are used to calibrate. Short, precise answers buy you time for the harder material.

What is the difference between authentication and authorization?

Authentication establishes who is calling; authorization decides what they may do. Authentication happens once at the edge and fails with 401; authorization happens on every resource access and fails with 403. The distinction matters operationally: a client seeing 401 will refresh its credential and retry, so returning 401 for a permissions problem makes it retry forever.

Why can't the API just trust the user id the client sends?

Because the client controls it. GET /api/orders?user_id=8 is an insecure direct object reference — the identity must be derived from a verified credential and nothing else. This is still one of the most common API vulnerabilities found in the wild.

What does HTTPS give you, and what doesn't it?

Confidentiality, integrity, and server authentication. It says nothing about who the client is — that is what every scheme in this course exists to do. The exception is mTLS, which extends TLS to authenticate the client too.

When is 401 correct and when is 403?

401 means unauthenticated: missing, malformed or expired credential. Pair it with WWW-Authenticate so the client knows what to send. 403 means the credential was valid but the identity is not permitted — retrying changes nothing.

Why not put the API key in the query string?

URLs are recorded everywhere: server access logs, CDN logs, browser history, the Referer header sent to third parties, and screenshots in bug reports. A header ends up in none of those by default.

What is a bearer token?

A credential where possession alone is sufficient — no further proof is asked for. That is why the two things that matter are keeping it short-lived and, when the stakes justify it, sender-constraining it with DPoP or mTLS binding.

Someone shows you an endpoint. What do you check first?

Whether the object being accessed is scoped to the authenticated caller — inside the query, not after it. Authentication is usually right; the missing ownership check is what actually causes breaches.

Example

Example · javascript
// The one-liner that answers half of these questions at once

// ❌ junior
app.get('/api/orders', (req, res) => res.json(ordersFor(req.query.userId)));

// ✅ senior
app.get('/api/orders', authenticate, (req, res) =>
  res.json(ordersFor(req.user.id)));      // identity from the credential only

// And the follow-up they will ask: what about a single order?
app.get('/api/orders/:id', authenticate, async (req, res) => {
  // Ownership IS the query. Not a check after it.
  const order = await db.orders.findOne({ id: req.params.id, userId: req.user.id });
  if (!order) return res.status(404).json({ error: 'not_found' });   // not 403
  res.json(order);
});

When to use it

  • A candidate distinguishes 401 from 403 by describing client retry behaviour, which shows operational experience rather than memorised definitions.
  • An interviewer asks why 404 rather than 403 for another user's record, and the candidate names the existence-disclosure leak.
  • A screening round is passed in five minutes because the fundamentals were answered crisply, leaving time for the system design portion.

More examples

Questions where the follow-up is the real test

Interviewers rarely stop at the first answer. Rehearse the second layer, because that is where the level is decided.

Example · bash
Q: "How do you store passwords?"
   Surface answer : "Hashed with bcrypt."
   FOLLOW-UP      : "Why not SHA-256 with a salt?"
   Senior answer  : SHA-256 is fast by design — billions per second on a GPU.
                    Password hashes must be deliberately slow and memory-hard.
                    Argon2id, scrypt or bcrypt; the salt is included in all of
                    them, so "salted SHA" is still the wrong primitive.

Q: "How do you know a request is authenticated?"
   Surface answer : "We check the token."
   FOLLOW-UP      : "Check it how?"
   Senior answer  : Verify the signature with a pinned algorithm, then check
                    iss, aud and exp. A valid signature only proves someone
                    with the key made it — not that it was made for us.

Q: "Where do you put the token in a browser?"
   Surface answer : "localStorage."
   FOLLOW-UP      : "What can an XSS do then?"
   Senior answer  : Read it in one line and exfiltrate a portable credential.
                    Access token in memory, refresh token in an HttpOnly cookie:
                    an XSS can then act while the tab is open but cannot walk
                    away with something usable tomorrow.

Q: "Is CORS a security control for your API?"
   Surface answer : "Yes, it restricts who can call us."
   Senior answer  : No. CORS is enforced by browsers only — curl, Postman and
                    any server ignore it entirely. It protects the USER's
                    session from being read by an untrusted page. It is not
                    access control.

A 60-second whiteboard you can always draw

Having one diagram you can produce from memory keeps you driving the conversation instead of answering disconnected questions.

Example · bash
# When asked "walk me through how auth works in your API", draw this.

  Client                Edge                  Service              Data
    │                    │                      │                   │
    │─ credential ──────▶│                      │                   │
    │                    │ verify signature     │                   │
    │                    │ check iss/aud/exp    │                   │
    │                    │ route-level scope    │                   │
    │                    │ strip client headers │                   │
    │                    │─ internal token ────▶│                   │
    │                    │                      │ verify again      │
    │                    │                      │ tenant check      │
    │                    │                      │─ scoped query ───▶│
    │                    │                      │   WHERE user_id=? │
    │◀───────────────────┴──────────────────────┴───────────────────┘

# Then say the sentence that frames everything after it:
#   "The edge authorizes the ROUTE. The service authorizes the OBJECT.
#    Neither one is optional."

# Every follow-up — gateways, microservices, IDOR, multi-tenancy — hangs off
# this diagram, so you only have to draw it once.

Red-flag answers to unlearn

Each of these is a real sentence said in real interviews. Recognising why they are wrong is often more valuable than the correct answer alone.

Example · bash
❌ "JWTs are more secure than sessions."
   → They are not more or less secure; they trade instant revocation for
     stateless verification. Name the trade, not a winner.

❌ "We hash the JWT so nobody can read it."
   → A JWT is signed, not encrypted. Anyone holding it reads the payload with
     base64. Signing protects integrity and origin, never confidentiality.

❌ "CORS stops other sites calling our API."
   → Browsers only. Nothing stops curl.

❌ "We use HTTPS so we don't need to worry about tokens leaking."
   → TLS protects transit. Logs, referrers, browser history and XSS are all
     after decryption.

❌ "The gateway handles auth so services don't need to."
   → Then anything reaching a service directly is unauthenticated. Ask what
     happens on a misconfigured ingress.

❌ "We validate the token on the frontend."
   → Client-side validation is a UX optimisation. The server must verify.

❌ "Our API is internal, so it doesn't need authentication."
   → Network position is not a credential. This is the sentence zero trust
     exists to delete.

Discussion

  • Be the first to comment on this lesson.