Authentication, authorisation and data protection
Sessions versus tokens, OAuth and OIDC in the depth interviews ask for, service-to-service auth, authorisation models, secrets, encryption and the privacy requirements that change a design.
Security rarely gets its own interview, but it gets three minutes of every one: how users log in, how services trust each other, how the sensitive field is protected, and what happens when a token leaks. Answers that are specific here stand out, because most candidates wave at the topic.
Authentication: sessions versus tokens
Server-side sessions. The server stores session state (in Redis) and gives the browser an opaque cookie. Revocation is instant — delete the row. The cost is a lookup per request and session storage that has to be replicated across regions.
Stateless tokens (JWT). The server signs a token containing the user id, scopes and an expiry. Any service can verify it with the public key, no lookup needed. The cost is that revocation is hard: a signed token is valid until it expires.
The pattern that resolves it: short-lived access tokens (5–15 minutes) plus a long-lived refresh token that is stored server-side and can be revoked. Access tokens are checked by signature alone; the refresh path is the one place the database is consulted, and logout or compromise kills the refresh token so access dies within minutes.
Cookie mechanics worth saying out loud: HttpOnly (no JavaScript access), Secure (HTTPS only), SameSite=Lax or Strict (CSRF defence), a scoped domain and path, and rotation of the session id on privilege change.
OAuth 2 and OIDC, briefly
- OAuth 2 delegates *authorisation*: "this app may read your files." OIDC adds *authentication* on top: an
id_tokenthat says who the user is. "Sign in with Google" is OIDC. - The flow to name is authorisation code with PKCE: the client redirects to the provider, the user consents, the provider redirects back with a one-time code, and the client exchanges the code plus a verifier for tokens over a back channel. PKCE exists so a stolen code cannot be exchanged by someone else.
- Never use the implicit flow; it puts tokens in the URL.
- Validate on receipt: signature against the provider's JWKS, issuer, audience, expiry, and nonce.
Service-to-service
Inside the system, services need identity too. In order of maturity: a shared static secret (bad, unrotatable), per-service API keys in a secret manager, short-lived signed tokens from an internal issuer, and mTLS with SPIFFE-style identities issued by the platform, which is what a service mesh gives you. Say that internal calls carry both the service identity and the end-user context, so a downstream service can enforce "this user may read this record" rather than trusting the caller blindly.
Authorisation models
- RBAC: roles grant permissions. Simple, coarse, enough for most products.
- ABAC: a policy evaluates attributes (owner, department, region, time). Flexible, harder to reason about.
- ReBAC (Zanzibar-style): permissions are edges in a graph — "user is an editor of folder, document is in folder". This is what document and workspace products actually need, and naming it when the question has sharing semantics is a strong signal.
Two implementation facts that come up: permission checks must be fast, so the graph or role set is cached with a short TTL and invalidated on change; and a listing endpoint must filter by permission at the query, not after pagination.
Protecting data
- In transit: TLS everywhere, including inside the datacenter.
- At rest: disk or database encryption is table stakes and protects against a stolen disk, nothing more.
- Field-level encryption for the sensitive columns, with keys from a KMS and envelope encryption: a data key encrypts the field, the KMS master key encrypts the data key, and the encrypted data key is stored next to the row. Rotation re-encrypts data keys, not rows.
- Tokenisation for card numbers and similar: the sensitive value lives in a small isolated vault, and everything else holds a token. This is how a payment design keeps PCI scope to one service — say it that way.
- Hashing for passwords: bcrypt, scrypt or Argon2 with a per-user salt. Never SHA-256, never reversible.
Secrets
Application secrets live in a secret manager (Vault, cloud KMS/secrets) and are delivered at runtime, not in the image or the repository. Rotation needs to be possible without downtime, which means the consumer supports two valid keys at once during the overlap. Interviewers like asking "how do you rotate the database password with no downtime"; the answer is dual credentials plus a rolling restart.
Abuse and account safety
Rate limit by user, by IP and by endpoint, with stricter limits on login, signup, password reset and anything that sends email or SMS. Add exponential lockout with jitter on failed logins, bot checks on signup, and a device or session list the user can revoke. Log every security-relevant event — login, permission change, token issue, admin action — to an append-only audit trail with actor, subject, action and time.
Privacy requirements that change the design
- Data subject rights (GDPR, CCPA): export and delete on request. Deletion has to reach every derived copy — search index, caches, analytics, backups — which is why designs keep a user-id-keyed index of where data went. Backups are usually handled by documented retention plus crypto-shredding (delete the key), because rewriting backups is impractical.
- Data residency: EU data in EU regions changes the sharding key to include region.
- Minimisation and retention: raw location or message content with a bounded lifetime, aggregates kept longer.
- PII in logs is the most common real-world leak. Redact at the logging library, not by review.
Failure and compromise
Be ready for "a token leaked, now what": revoke the refresh token family, rotate signing keys (which is why key ids exist in JWT headers and JWKS supports multiple keys), force re-auth, and check the audit log for what that token touched. And for "someone dumps the database": passwords are hashed, sensitive fields are separately encrypted with keys the database does not hold, and the blast radius is what you can describe in one sentence.
Common mistakes
- Long-lived JWTs with no revocation path.
- Authorisation checks in the UI or the gateway only, so a direct API call bypasses them.
- Putting the user id from the request body, rather than the token, into the query.
- Storing secrets in environment variables committed to a repository.
- Ignoring the delete path for derived data when the question is about user privacy.
Checklist
- Login flow, token lifetimes, and how revocation works.
- Service-to-service identity.
- Authorisation model and where checks happen.
- Which fields are encrypted or tokenised, and where the keys live.
- Rate limits on the abuse-prone endpoints, plus the audit log.
- Deletion, retention and residency, if the data is personal.