API Security, Authentication and Authorization Questions
Controlling who can call an API, what they may do, and defending it against abuse. Covers the access-control mechanics: API keys, OAuth 2.0 flows, OpenID Connect, JWT issuance/validation, session vs. token auth, scopes/roles for fine-grained authorization, token lifetime and refresh, mutual TLS, and machine-to-machine vs. user-delegated access. Also covers the adversarial hardening view: input validation, injection and deserialization risks, broken object-level authorization (BOLA), mass assignment, secrets handling, and the OWASP API Security Top 10, plus securing data in transit, preventing enumeration/scraping, and testing APIs for vulnerabilities.
Compare opaque tokens versus self-contained JWTs for service-to-service authentication in a distributed microservices environment. Discuss performance (validation latency), revocation complexity, payload confidentiality, token size, caching implications, and give recommendations for hybrid approaches that balance stateless validation with revocation needs.
Sample Answer
Direct answer
Opaque tokens trade a network round trip (an introspection call to the issuer) for instant, centralized revocation. Self-contained JSON Web Tokens (JWTs) trade that centralized control for fast, local, offline validation. In a distributed machine-to-machine (M2M) environment at real scale, most teams land on a hybrid: short-lived signed JWTs as the default, since the overwhelming majority of calls should need zero network hop to validate, backed by a narrow, fast-path mechanism for the rare "kill this credential right now" case.
Structured elaboration
| Dimension | Opaque token | Self-contained JWT |
|---|---|---|
| Validation latency | Every validating service calls the issuer's introspection endpoint, adding a network hop and making the issuer a shared, latency-sensitive dependency at scale | Local signature check only, using a cached public key, no network call, scales horizontally with the caller itself |
| Revocation | Trivial: the issuer marks the token invalid, the very next introspection call reflects it | Hard: the token is valid until its exp claim regardless of what the issuer now wants, unless you add an auxiliary mechanism |
| Payload confidentiality | The token itself carries no information; a captured token reveals nothing without querying the issuer | Claims are base64url-encoded, not encrypted, by default, readable by anyone holding the token, including any intermediary that logs or proxies it |
| Token size | Small and fixed, often just an opaque identifier | Grows with claim count, adding real header overhead on every call at high queries-per-second (QPS) if claims bloat |
| Caching implications | Services cache introspection results, reintroducing a staleness-versus-load trade-off on top of the revocation problem itself | Services cache the issuer's signing keys (via a JWKS, JSON Web Key Set, endpoint), which change rarely, so this cache is cheap and carries no correctness trade-off |
Why revocation is the real fork in the road: because a JWT is self-contained, "revoking" it does not mean anything to the token itself, the signature still verifies and the claims are still readable. Real revocation for JWTs requires bolting on state: short time-to-live (TTL) values as the default mitigation (bounding the exposure window), a deny-list checked at validation time (which reintroduces a lookup, partially undoing the statelessness benefit you adopted JWTs for), or issuer-side generation/versioning per client.
Worked example
Consider a service mesh where an order service calls an inventory service, which calls a pricing service, on every checkout request. With opaque tokens, each of those two internal hops adds a full round trip to the issuer's introspection endpoint before the call is even allowed to proceed, meaning a single external request now pays for multiple serial introspection calls stacked on top of its own logic. With signed JWTs, each hop verifies the caller's token locally against a cached public key, no extra network dependency introduced by authentication itself. This qualitative difference, not a specific millisecond figure, is why introspection-per-call does not scale cleanly as call chains get deeper.
Recommendations for a hybrid approach
- Default to short-lived signed JWTs (minutes, not hours, since machine-to-machine calls do not need a human to reauthenticate) so the common case stays local and fast.
- Pair that with a lightweight, narrow deny-list checked only for the rare case that actually needs it (a compromised service account, a discovered key leak), not on every single request; expire each deny-list entry once the underlying JWT would have expired anyway, so the extra state stays bounded rather than growing forever.
- Support issuer-side token-family versioning (bumping a minimum-issued-at cursor per client) so you can cheaply invalidate every future token for a specific caller, checked at the same low frequency as the JWKS cache refresh, without a per-request lookup.
- Reserve opaque tokens plus introspection for genuinely high-stakes, low-volume paths, such as issuing a brand-new elevated-privilege credential, where the extra round trip is an acceptable cost for tighter control.
Trade-offs & pitfalls
Choosing JWTs everywhere and ignoring the revocation gap is a common answer that sounds clean but quietly assumes a compromised credential is an acceptable risk for its full remaining lifetime. Choosing opaque tokens everywhere under-appreciates that introspection becomes the single most-called, most latency-sensitive endpoint in the whole system as call volume grows. A subtler pitfall: forgetting that JWT claims are readable, not encrypted, and putting anything genuinely secret into a claim, where it is visible to every intermediary that ever sees the token.
Sketch out a zero-trust authentication model for internal microservices spanning multiple clusters: include mutual TLS for service identity, short-lived JWTs for delegated downstream requests, an automated certificate/key rotation plan, and how to perform token exchange when cross-account or cross-tenant permissions are needed.
Sample Answer
Direct answer
Layer two distinct credentials that answer two distinct questions. Mutual TLS (mTLS) proves which service is calling, a machine identity established at the transport layer via a cluster-local certificate authority. A short-lived JSON Web Token (JWT) proves on whose behalf, and with what permissions, an application-layer, delegated credential. Crossing a cluster or tenant boundary adds a third step, token exchange, where a service presents both its own mTLS identity and the inbound JWT to receive back a new, narrower-scoped token valid only for the target boundary.
Structured elaboration
Mutual TLS for service identity
Every service gets a short-lived X.509 certificate issued by an internal certificate authority (CA), typically via a service mesh sidecar or a workload-identity system. The TLS handshake becomes mutual, the server verifies the client's certificate too, so "which service is this" is answered cryptographically at the connection level, before any application logic runs, and does not depend on a bearer credential that could simply be copied out of a running process.
Short-lived JWTs for delegated requests
Once mTLS establishes that service B is really service B, service B still needs to prove it is acting on behalf of a specific end user or upstream caller when it calls service C. That is carried as a short-lived JWT, minutes, not hours, issued at the edge from the original authentication event and propagated down the call chain, so service C can authorize based on the original caller's identity and scopes, not just "some internal service asked for this."
Automated rotation plan
Certificates rotate frequently and automatically, often on the order of hours, managed entirely by the mesh or CA infrastructure, never manually copied files, so a compromised certificate has a short useful life and rotation is a routine non-event rather than an outage. JWT signing keys rotate on a separate, slower cadence using a kid (key ID) header plus JSON Web Key Set (JWKS) caching: publish the new key alongside the old one, sign new tokens with the new key, and retire the old key only after every token signed with it has naturally expired.
Token exchange for cross-account or cross-tenant permissions
When a call needs to cross a boundary the original token was not scoped for, a different cluster, a different tenant's data, the calling service presents its own mTLS identity plus the inbound token to a token-exchange endpoint (the pattern standardized as OAuth 2.0 Token Exchange, RFC 8693) and receives back a new, narrowly scoped token valid only for the target boundary and the specific downstream call being made. This avoids two worse alternatives: minting one all-clusters "god token" up front, or having the receiving cluster simply trust whatever claims arrive without independently verifying that the calling service is who it claims to be and is actually allowed to ask on the original caller's behalf.
Worked example
sequenceDiagram
participant U as User
participant GW as Gateway (cluster 1)
participant A as Service A (cluster 1)
participant TX as Token Exchange
participant C as Service C (cluster 2)
U->>GW: Request (authenticates)
GW-->>U: Short-lived JWT
GW->>A: Forward request + JWT (mTLS)
A->>TX: Present own mTLS identity + inbound JWT
TX-->>A: New, narrowly scoped cluster-2 token
A->>C: Call service C (mTLS + exchanged token)
Service A never forwards the user's original token as-is into cluster 2. It exchanges it for a new token scoped only to the specific downstream call it needs to make, so service C sees exactly the permission it needs to check and nothing broader.
Trade-offs & pitfalls
Operating an internal CA and rotation infrastructure is a real ongoing cost, which is why most teams adopt an existing service mesh to get this largely for free rather than hand-rolling it. Propagating the original user's JWT unchanged through a long call chain leaks the full token to every hop along the way, each service sees everything, token exchange also solves this by minting a narrower token per hop instead of forwarding one token everywhere. A common production mistake is trusting mTLS identity alone as authorization, "service B connected, so it must be allowed to do this", when mTLS answers identity, not permission; the JWT and token-exchange layer is what actually carries the authorization decision, and conflating the two is a real, exploitable design flaw.
Propose a security architecture for public and internal APIs covering mutual TLS, JWTs, token rotation and revocation, attribute-based access control (ABAC), and audit logging. Describe where enforcement should happen in the layered stack, how to manage and rotate secrets/keys, and operational steps when credentials are compromised.
Sample Answer
Layer enforcement so each layer does the check it's best positioned to do cheaply: mutual TLS (mTLS) and coarse authentication at the edge gateway, service-to-service mTLS plus lightweight authorization in the mesh between services, and fine-grained attribute-based access control (ABAC) decisions at the application layer where the actual resource context lives. Wire audit logging and a rehearsed compromise-response runbook underneath all three, so a breach in one layer doesn't also blind you to what happened.
Enforcement points in the layered stack
The edge (API gateway) terminates mTLS for external clients, validates the JSON Web Token (JWT, a signed, self-contained access token) signature and expiry, and enforces coarse route-level allow/deny and rate limits, the cheapest place to reject the largest share of bad traffic. The service mesh (sidecars, internal service-to-service traffic) enforces mTLS between every internal service, so a compromised service can't silently impersonate another, and performs a fast, cached authorization pre-check before forwarding. The application layer is the only place with full resource context, this is where ABAC runs, evaluating attributes of the caller, the specific resource, the action, and the environment against policy, for decisions the gateway and mesh can't make with only a token in hand.
flowchart TD
Client -- mTLS plus JWT --> GW[API Gateway: authn, coarse authz, rate limits]
GW -- mTLS --> Mesh[Service Mesh: service identity, cached authz]
Mesh --> App[Application: ABAC policy decision]
App -- policy query --> OPA[(Policy Engine / OPA)]
GW -.audit event.-> Audit[(Immutable Audit Log)]
Mesh -.audit event.-> Audit
App -.audit event.-> Audit
(In the diagram, "authn" is authentication, confirming who the caller is, and "authz" is authorization, deciding what that caller is allowed to do; the gateway makes only the coarse version of that second decision.)
JWTs and token lifecycle
Short-lived signed JWTs, minutes rather than hours, with signing keys rotated via a published JWKS (JSON Web Key Set) endpoint using overlapping key IDs, so in-flight tokens don't break mid-rotation. Refresh tokens rotate on use; opaque reference tokens (random reference strings with no embedded data, so the server must look them up on every call) with introspection (a live network check with the issuer asking whether the token is still valid) are reserved for flows that need instant revocation over raw speed.
Attribute-based access control
A central policy store (for example, Open Policy Agent) evaluates attributes: caller role or department, resource owner and sensitivity, action, and time-of-day or geography. Cache decisions at the mesh layer with a short TTL, invalidated on policy change via an event rather than waiting out the TTL.
Secrets and key rotation
Every signing key, TLS certificate, and service credential lives in a KMS (Key Management Service) or HSM (Hardware Security Module), never in application config or source control. Automate rotation on a fixed schedule, for example certificates quarterly, signing keys monthly with an overlap window, and test the rotation process itself in staging, so it isn't the first time you find out rotation is broken.
Audit logging
Structured, append-only logs at every layer, gateway, mesh, and application, each event carrying enough context (principal, resource, decision, policy version) to reconstruct who did what, under which policy, and why it was allowed or denied. Stream these to a central store separate from the services being audited, so a compromised service can't also erase its own trail.
Operational steps when credentials are compromised
- Immediately revoke the specific compromised certificate, key, or token, pushing the revocation to the cache and pub/sub layer rather than waiting for a scheduled rotation.
- Rotate the signing key itself only if the private key, not just one issued token, is suspected compromised, since that invalidates every token ever signed with it, confirm the scope of compromise before taking this much larger step.
- Isolate affected systems (for example, pull a service out of the mesh) if the compromise looks systemic rather than a single leaked credential.
- Pull the audit trail for the affected identity and time window to scope what was actually accessed, not just what could have been accessed.
- Notify affected customers or partners per contractual and regulatory obligations, and roll forward with newly rotated credentials in a phased rollout rather than a single flag-day cutover that risks breaking every legitimate client at once.
Worked example
A service account's mTLS client certificate is found on a public code-sharing site. Step 1: revoke that certificate's serial number via the CRL/OCSP path (publishing it to a certificate revocation list, or answering "revoked" to a live OCSP check) and push a revocation event so mesh sidecars reject it within seconds, not at the certificate's natural 90-day expiry. Step 2: because only this one certificate leaked, not the certificate authority's signing key, the root or intermediate signing key does not need rotation, the blast radius stays narrow. Step 3: pull audit logs for that service identity over the 30 days since the certificate's issuance to check for any anomalous access it might already have made. Step 4: issue a new certificate to the legitimate service through the automated rotation pipeline, rather than manually, closing the loop with the same tooling that would catch this earlier next time.
Trade-offs and pitfalls
Enforcing everything at the gateway is simple to reason about but can't express resource-level ABAC without pulling full application context into the gateway, defeating the point of a cheap, coarse check at the edge; enforcing everything at the application layer is fully expressive but lets obviously-bad traffic travel all the way through the stack before rejection, wasting capacity. Caching authorization decisions cuts latency but risks a stale allow after a policy change, always pair caching with event-driven invalidation, never rely on TTL alone for anything security-sensitive. Rotating the wrong scope during a compromise response, for example rotating a root signing key when only one leaf certificate leaked, causes a much larger, avoidable outage, confirm the actual blast radius before choosing how broad the rotation needs to be.
Architect a security model for a large-scale microservices platform (~1000 services) that uses a service mesh (e.g., Envoy/Istio) and an API gateway. Goals: enforce strong service-to-service authentication and authorization, minimize blast radius, centralize policy where sensible but avoid bottlenecks, ensure observability and incident response. Provide key components, identity model, policy enforcement points, rollout plan and scaling considerations.
Sample Answer
Direct answer
At roughly 1,000 services, service-to-service authentication and authorization has to be
enforced by infrastructure (a service mesh sidecar, such as Envoy, paired with a control plane
like Istio) rather than by each service's own application code, because you cannot reliably
audit or update security logic duplicated across a thousand codebases owned by many different
teams. The mesh's sidecar proxies handle mutual TLS (mTLS) and per-request authorization
uniformly, the control plane distributes identity and policy to every sidecar, and the API
gateway stays a separate, thinner layer that only handles edge concerns (external traffic
authentication, coarse rate limiting) rather than trying to be the single point enforcing every
internal rule.
Structured elaboration
Identity model. Every service instance gets a workload identity, most commonly a SPIFFE
(Secure Production Identity Framework For Everyone) identity encoded into a short-lived X.509
certificate, tied to what the workload is (its Kubernetes service account and namespace, for
example) rather than a static shared secret. The mesh's control plane (Istio's istiod, for
example) issues and continuously rotates these certificates automatically; no individual service
team manages its own certificate lifecycle.
Enforcing service-to-service auth and authorization. The sidecar proxy next to each service
terminates and originates mTLS transparently, so two services communicate over an encrypted,
mutually-authenticated channel without either one's application code implementing TLS itself.
Authorization (which services may call which other services, and for which operations) is
expressed as policy (Istio's AuthorizationPolicy resources, for example) and enforced by the
sidecar before a request ever reaches the application, giving every service the same
authorization enforcement mechanism regardless of what language or framework it is written in.
Policy enforcement points. At this scale there are exactly two places policy actually gets
enforced, and each has a distinct job: the API gateway is the enforcement point for traffic
entering the mesh from outside (external clients, partners), handling coarse checks like
authentication and rate limiting once at the edge; each service's own sidecar is the enforcement
point for everything after that, deciding, per call, whether one internal service may reach
another. Keeping these two enforcement points separate, rather than routing all internal traffic
back through the gateway, is what keeps the gateway from becoming a bottleneck for traffic that
never needed to leave the mesh.
Minimizing blast radius. Default-deny between services (a service can only call, or be
called by, the specific services its policy explicitly allows) turns a compromised service into
a contained incident instead of a pivot point to the rest of the fleet; without this, one
compromised service with network reachability to everything else effectively compromises the
whole mesh.
Centralizing policy without creating a bottleneck. Policy is authored and versioned
centrally (so the security posture is auditable in one place, as code) but distributed to
every sidecar so each one can make allow/deny decisions locally, at line rate, without a
synchronous call back to a central decision service on every request. This is the key design
move for enforcing at 1,000-service scale: centralize the authoring and distribution of
policy, not the evaluation of it.
Observability and incident response. Every sidecar can emit consistent access logs, metrics,
and distributed traces for the traffic passing through it, giving uniform visibility across all
1,000 services without depending on each service team to instrument request-level auth logging
themselves. This uniformity is what makes incident response at this scale tractable: a security
team traces a suspicious request across service boundaries using the mesh's own telemetry rather
than reconciling a thousand different logging formats.
Rollout plan. Introduce the mesh incrementally rather than flipping mTLS enforcement on
everywhere at once: start in permissive mode (the sidecar accepts both plaintext and mTLS
traffic while metrics show which callers have and have not migrated), onboard services namespace
by namespace or team by team, and only flip to strict mTLS enforcement for a given service once
its traffic is confirmed fully migrated. A big-bang cutover at 1,000 services risks a
simultaneous outage across the fleet if any meaningful fraction of callers have not yet adopted
the sidecar.
Scaling considerations. The sidecar's own resource footprint (CPU and memory per pod) and the
control plane's config-push fan-out both need capacity planning at this scale; a control-plane
change that pushes new policy to 1,000 sidecars simultaneously needs to be paced (canaried,
rate-limited) rather than broadcast all at once, since a bad policy pushed everywhere
simultaneously turns a policy bug into a fleet-wide outage instead of a contained one.
Worked example
graph TD
Ext[External Traffic] --> GW[API Gateway - Edge AuthN and AuthZ]
GW --> SM[Service Mesh Ingress]
SM --> SVA[Service A plus Envoy Sidecar]
SM --> SVB[Service B plus Envoy Sidecar]
SVA -->|mTLS plus SPIFFE ID| SVB
CP[Istio Control Plane] -.->|distributes policy and certs| SVA
CP -.-> SVB
SVA --> OBS[Telemetry: access logs, traces]
SVB --> OBS
The gateway handles only the edge boundary (authenticating and rate-limiting external traffic
before it enters the mesh at all); everything after that, service A calling service B, for
example, goes sidecar-to-sidecar over mTLS with an authorization decision made locally by
service B's own sidecar, based on policy the control plane already pushed to it. If the control
plane is briefly unavailable, existing sidecars keep enforcing their last-known policy and
certificates until they expire, since evaluation never depended on a live call to the control
plane; only new certificate issuance and policy updates pause during that window, which is
the direct payoff of "centralize distribution, not evaluation."
Trade-offs and pitfalls
- A service mesh adds real operational complexity and per-request latency overhead (an extra
network hop through the sidecar in each direction); this is a deliberate trade against the
alternative of every service reimplementing TLS and authorization independently, which does not
scale to 1,000 services being maintained correctly and consistently over time. The trade-off
is worth stating explicitly rather than presenting the mesh as free. - Permissive mode during rollout is a temporary state, not a target state. Leaving services
in permissive mode indefinitely (common when a migration stalls) means mTLS is not actually
being enforced for those services even though the infrastructure exists, which is easy to miss
in metrics that only measure "sidecar deployed" rather than "strict mode enforced." - Common wrong turn: routing all internal traffic back through the central API gateway to
reuse its authorization logic. This defeats the scaling argument for a mesh in the first place
and turns the gateway into both a latency bottleneck and a single point of failure for traffic
that never needed to leave the mesh's own service-to-service path. - Common wrong turn: pushing a policy change to all 1,000 sidecars simultaneously without a
canary. A syntactically valid but logically wrong authorization policy (an overly broad deny
rule, for example) pushed everywhere at once can cause a fleet-wide outage in the time it takes
the control plane to distribute the update, which is why staged rollout applies to policy
changes, not just to the initial mesh adoption.
Walk me through mutual TLS (mTLS): how does the handshake differ from standard one-way TLS, how do the client and server present and verify each other's certificates, and what are the practical options for certificate provisioning and rotation for service-to-service authentication in a microservice or service-mesh deployment?
Sample Answer
Direct answer
Mutual TLS (mTLS, where "TLS" is Transport Layer Security, the protocol that encrypts and
authenticates network connections) extends standard one-way TLS by having the client also
present a certificate that the server verifies, so both sides cryptographically prove their
identity to each other before any application data flows. In standard one-way TLS only the
server proves who it is; the client stays anonymous at the transport layer and any identity
checking happens later, in the application (a password, a bearer token).
Structured elaboration
How the handshake differs from one-way TLS. In a plain TLS handshake, the server sends its
certificate and the client verifies it against a trusted certificate authority (CA); the client
never presents one of its own. In an mTLS handshake, the server additionally sends a
CertificateRequest message, the client responds with its own certificate plus a
CertificateVerify message (a signature over the handshake transcript, proving the client
actually holds the private key matching that certificate, not just a copy of the public
certificate), and the server verifies the client's certificate against its own trusted CA
(commonly a private, internal CA for service-to-service traffic rather than a public one) before
completing the handshake. If either side's certificate fails verification, the connection is
refused before any request or response is exchanged.
What each side verifies. The client checks the server's certificate chain up to a trusted
root, the certificate's validity window, and that the certificate's subject matches the hostname
being connected to (the checks that already happen in ordinary HTTPS). The server does the
mirror image for the client: chain validity, expiry, and (this is the part unique to mTLS as an
authentication mechanism) that the certificate's identity (its Subject or a SPIFFE-style URI in
the Subject Alternative Name) matches an identity the server is willing to trust, and that the
certificate has not been revoked.
Provisioning and rotation options for service-to-service auth:
- Long-lived certificates issued manually or by a slow internal PKI (public key
infrastructure, the systems and processes for issuing and managing certificates), rotated
every 6 to 12 months. Simple to reason about but a compromised private key stays valid for a
long time, and rotation is often a manual, error-prone, outage-risking event precisely because
it happens rarely. - Short-lived certificates (hours, not months) issued automatically by an internal CA and
rotated continuously, often via a sidecar proxy that handles issuance and rotation
transparently to the application. This is the pattern service meshes like Istio or Linkerd
use, frequently paired with SPIFFE (Secure Production Identity Framework For Everyone, a
standard for representing workload identity as a URI) so identity is tied to what a workload
is (its service account, its namespace) rather than to a long-lived secret. Short TTLs shrink
the blast radius of a leaked key dramatically, since the certificate expires on its own within
hours even if revocation never fires. - A managed cloud CA or secrets-manager-backed issuance for teams that do not want to
operate their own internal CA, trading some control for less operational burden.
Worked example
sequenceDiagram
participant C as Client
participant S as Server
C->>S: ClientHello
S->>C: ServerHello plus Server Certificate
S->>C: CertificateRequest
C->>S: Client Certificate
C->>S: CertificateVerify (signed with client private key)
S->>S: Verify client cert against trusted CA, check chain and revocation
C->>S: Finished
S->>C: Finished
Note over C,S: Both sides now hold a mutually authenticated encrypted channel
The two extra round-trip messages compared to one-way TLS are CertificateRequest (the server
asking) and the client's Client Certificate plus CertificateVerify pair (the client proving
it holds the matching private key, not merely presenting a public certificate it copied from
somewhere). Everything after Finished on both sides is identical to ordinary TLS: an encrypted
channel, just one where the server now also knows, cryptographically, which specific
service-identity it is talking to, without needing an application-layer credential to establish
that.
Trade-offs and pitfalls
- mTLS proves connection identity, not user identity. It tells a server which service or
workload is calling, which is exactly the right primitive for service-to-service traffic in
a microservice or service-mesh deployment; it is the wrong tool for authenticating an
individual end user, since a human does not carry a private key the way a workload's sidecar
does. OAuth 2.0 or session-based authentication remains the right layer for user identity, and
the two are often combined (mTLS between services, a user token passed through inside that
channel). - Short-lived automated certificates need working automation, not just working crypto. If
the sidecar or agent responsible for rotation fails silently, certificates expire and every
connection using them starts failing at once, an outage that a slower manual rotation schedule
is less exposed to (at the cost of a much larger blast radius if a key leaks). Automated
rotation needs its own monitoring and alerting on issuance failures, not just on the
certificates' expiry dates. - Common wrong turn: skipping revocation checking because "the certificates are short-lived
anyway." Short TTLs reduce how long a compromise matters, but do not eliminate the window
entirely; a certificate stolen minutes before use is still valid until it expires, so
revocation checking (or, more commonly in practice, simply re-issuing all workload identities
and rotating the internal CA's trust) still matters for a confirmed compromise. - Common wrong turn: terminating mTLS at a load balancer and trusting an internal header for
identity afterward. If the load balancer is not itself inside the trust boundary you are
defending, or if an internal service can be reached directly without going through it, an
attacker who reaches the internal network can forge the identity header the same way they
would forge any other unauthenticated claim.
Unlock Full Question Bank
Get access to all 28 API Security, Authentication and Authorization interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.