Chapter 13 Interview: Security

🎙️ Practice answering these out loud — aim for 2–3 minute responses.

1. How would you design auth for a microservices system?

Right, so the big challenge with microservices auth is you can't just check credentials at the edge and hope for the best — every service needs to independently verify who's making the request without creating a bottleneck.

I'd use a centralized identity provider — something like Keycloak or Auth0 — that issues JWTs after authentication. The API gateway validates the token on the way in, and then each downstream service can verify the JWT signature locally without calling back to the auth server. That's the key insight: verification is decentralized, but issuance is centralized.

For service-to-service calls, I'd use a separate credential system — mutual TLS or short-lived service tokens from something like HashiCorp Vault. You don't want Service A impersonating a user; it should authenticate as itself and carry the user context as a claim in a propagated token.

Token lifetime matters a lot. Short-lived access tokens (5-15 minutes) with longer-lived refresh tokens. If a token is compromised, the blast radius is limited to minutes. And I'd include scope/permissions in the token claims so services can do authorization checks locally too.

  • Centralized issuance: one identity provider issues JWTs
  • Decentralized verification: each service validates signatures locally
  • Service identity: mTLS or service tokens separate from user auth
  • Short-lived tokens: 5-15 min access tokens limit breach impact

2. Explain OAuth2 flows and when to use each.

OAuth2 has several flows and honestly the naming is confusing, but each exists for a specific trust scenario. Let me break them down.

Authorization Code flow — this is for server-side apps. The user gets redirected to the auth provider, logs in, gets a short-lived code, and your server exchanges that code for tokens. The tokens never touch the browser. This is the most secure for web apps.

Authorization Code with PKCE — same thing but for public clients like SPAs and mobile apps that can't keep a client secret. PKCE adds a code verifier/challenge pair so even if someone intercepts the auth code, they can't exchange it. This has basically replaced the Implicit flow.

Client Credentials — machine-to-machine. No user involved. Service A presents its client ID and secret directly to get a token. Used for backend service communication, cron jobs, batch processes.

Resource Owner Password — the user gives their username/password directly to your app. Only use this if you own both the app AND the auth server, and even then it's being phased out. Legacy migration scenarios only.

Device Code flow — for devices with limited input like smart TVs. Display a code, user goes to a URL on their phone to authorize. Polls until approved.

  • Auth Code: server-side web apps — most secure, tokens stay on server
  • Auth Code + PKCE: SPAs, mobile — replaces Implicit flow
  • Client Credentials: machine-to-machine, no user context
  • Device Code: limited-input devices (TVs, CLI tools)

3. How do you secure service-to-service communication?

Zero trust is the mindset here — even internal network traffic can't be assumed safe. I'd layer multiple controls.

Mutual TLS is the foundation. Both sides present certificates, both verify. This gives you encryption in transit AND identity verification. In Kubernetes, a service mesh like Istio or Linkerd handles this transparently — the sidecar proxies manage cert rotation and mTLS without your application code knowing.

Beyond transport security, you need authorization. Just because Service A's identity is verified doesn't mean it should access Service B's admin endpoints. I'd use a policy engine — something like OPA (Open Policy Agent) — that defines which services can call which endpoints. Network policies in Kubernetes can restrict pod-to-pod communication at the network layer too.

Secrets management is critical. No hardcoded credentials, no environment variables with long-lived secrets. Use Vault or AWS Secrets Manager with automatic rotation. Services get short-lived credentials that expire and auto-renew.

And audit everything. Log every service-to-service call with caller identity, timestamp, and outcome. If something gets compromised, you need to trace exactly what was accessed.

  • mTLS: mutual authentication + encryption for all internal traffic
  • Service mesh: transparent cert management via sidecar proxies
  • Authorization policies: OPA or similar to enforce which services can call what
  • Secrets rotation: short-lived, auto-rotating credentials from a vault

4. What security concerns do you consider when designing a new system?

I think about this in layers — from the outside in. It's like a threat modeling exercise I run mentally every time.

First, the attack surface. What's exposed to the internet? Every public endpoint is a potential entry point. I minimize the surface — API gateway as single entry, everything else in private subnets. Input validation and rate limiting at the edge before anything hits business logic.

Authentication and authorization — who are the actors, what can they access? Principle of least privilege everywhere. Role-based or attribute-based access control depending on complexity. I'd also think about multi-tenancy — can Tenant A ever see Tenant B's data?

Data protection — what's sensitive? PII, credentials, financial data. Encrypt at rest and in transit. Consider field-level encryption for the most sensitive stuff. Where does data live geographically? GDPR, CCPA compliance constraints.

Then the operational angle — how do we detect breaches? Logging, monitoring, anomaly detection. How do we respond? Incident runbooks, ability to revoke access quickly. And supply chain — what third-party dependencies are we pulling in? Container image scanning, dependency audits.

  • Minimize attack surface: single entry point, private subnets, input validation
  • Least privilege: RBAC/ABAC, tenant isolation, scoped permissions
  • Data protection: encryption at rest + transit, compliance constraints
  • Detection & response: audit logs, anomaly monitoring, incident playbooks

5. How would you handle storing sensitive user data?

The first question I'd ask is: do we actually need to store it? Seriously. Every piece of sensitive data you hold is a liability. If you can avoid storing it — like using a payment processor so you never touch credit card numbers — do that.

For what you must store, encryption at rest is baseline — AES-256 with proper key management. But here's the thing: database-level encryption protects against disk theft but not against application-level breaches. For highly sensitive fields — SSNs, health data — I'd use application-level encryption where the app encrypts before writing to the DB. Even a DB admin can't read it.

Key management is where most people mess up. Keys can't live next to the data. Use a dedicated KMS — AWS KMS, GCP KMS, or HashiCorp Vault. Key rotation on a schedule, and envelope encryption so you're rotating data encryption keys without re-encrypting all the data.

Access controls around sensitive data should be strict. Separate database roles — most services get read access to non-sensitive columns only. Tokenization for data that needs to be referenced but not read — replace the SSN with a token, store the mapping in a hardened vault service.

And don't forget the audit trail. Log every access to sensitive data — who, when, why. Set up alerts for unusual patterns. Retention policies too — delete data you no longer need. You can't leak what you don't have.

  • Minimize retention: don't store what you don't need; use third-party processors
  • Application-level encryption: encrypt sensitive fields before DB write
  • Key management: dedicated KMS, envelope encryption, automatic rotation
  • Tokenization: replace sensitive values with opaque tokens for most use cases
  • Audit + retention: log all access, alert on anomalies, purge expired data