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.
What is an API gateway, and what security responsibilities does it typically take on for the services sitting behind it?
Sample Answer
Direct answer
An API gateway is a single entry point that sits in front of a set of backend services and handles cross-cutting concerns, routing, traffic management, and security, before a request ever reaches business logic. On the security side, its main value is enforcing cheap, universal checks exactly once, instead of every individual service having to duplicate that logic.
Structured elaboration
Typical security responsibilities a gateway takes on:
- Transport security: terminating TLS (Transport Layer Security) and enforcing HTTPS-only, including a minimum supported TLS version.
- Coarse authentication: validating a token's signature and expiry, or checking an API key, before forwarding the request at all.
- Coarse authorization: confirming this identity is allowed to call this route in general, not the fine-grained "does this caller own this specific record" check, which still belongs inside the service.
- Rate limiting and throttling: protecting the whole platform from abuse or an accidental traffic spike from any single caller.
- Request validation: rejecting malformed, oversized, or wrong-content-type requests early, before they cost any downstream service compute.
- IP allow/deny lists and basic filtering: blocking known-bad sources or request patterns before they reach anything meaningful.
- Centralized audit logging: one place to see every request that entered the system, useful for both security review and debugging.
- Identity propagation: injecting a verified identity (for example, a user-id header) into the forwarded request, so downstream services trust the gateway's verification rather than each re-parsing raw tokens themselves.
Worked example
A POST /orders request arrives with no authentication token. The gateway rejects it with a 401 response before the orders service, inventory service, or payment service ever see it, so none of them spend any compute on traffic that was never going to be allowed. A validly authenticated request for the same endpoint is forwarded along with an X-User-Id header the gateway added after verifying the token, so the orders service can trust that identity without re-validating the raw token itself.
Trade-offs & pitfalls
A gateway should take on responsibilities that are universal and cheap to check without business context, not fine-grained, per-resource authorization, which needs domain knowledge only the service actually has. The most common pitfall is treating the gateway as the only layer of defense: it is a first filter that removes obviously bad traffic early, not a substitute for a service independently checking that a specific caller is allowed to touch a specific resource.
You operate a mixed monolith + microservices environment. For security controls (authentication, authorization, rate limiting, input/schema validation, transport security), decide which responsibilities should be enforced at the API gateway/proxy and which should remain inside services. Justify choices with availability, security, and performance trade-offs and propose testing and observability to validate enforcement.
Sample Answer
Direct answer
Push the checks that are cheap, universal, and identity-only to the gateway (authentication verification, transport security, coarse rate limiting, structural request validation), and keep the checks that need business or ownership context inside the service (fine-grained authorization, business-aware rate limiting, semantic validation). Never treat the gateway's decision as the only check: services should still re-verify authorization even for traffic they assume already passed the gateway, because a bypass or misconfiguration at the gateway should not be the single point of failure for data access.
Structured elaboration
| Control | At the gateway | Inside the service | Why the split |
|---|---|---|---|
| Authentication | Verify token signature and expiry once, forward a verified identity to downstream services | Trust the forwarded identity, do not re-parse raw credentials | Cheap and identical for every route; centralizing it avoids every service wiring its own token validation |
| Authorization | Coarse: is this identity allowed to call this route at all | Fine-grained: does this specific caller own this specific resource | The gateway has no idea which record ID belongs to which user; that context lives only in the service |
| Rate limiting | Global/per-key throttling to protect the whole platform from volume abuse | Business-aware limiting (e.g. failed login attempts per account) that needs domain state | The gateway can count requests; it cannot reason about "too many wrong passwords for this specific account" |
| Input/schema validation | Structural: does the payload match the declared shape, reject malformed junk early | Semantic: is this SKU real, is there enough stock, do these fields make business sense together | Structural checks are cheap and universal; semantic checks require the service's own data |
| Transport security | TLS termination for client-to-gateway traffic | Mutual TLS or a service mesh for gateway-to-service and service-to-service hops | Encrypting only the outer hop leaves the internal network unauthenticated between services |
Worked example
A checkout request hits the gateway without a valid token: the gateway rejects with 401 before the order service, inventory service, or payment service ever see it, saving three services from processing traffic that was never going to be allowed. A validly authenticated request for PATCH /orders/482 is forwarded with a verified user-id header; the order service still checks that the caller actually owns order 482 before applying the patch, because the gateway only confirmed "this is a real, authenticated user," not "this user owns this specific order." If that service-side ownership check were removed on the assumption the gateway already handled it, any authenticated user could edit any order by changing the ID in the URL, which is exactly the Broken Object Level Authorization pattern, one of the most reliably tested authorization failures in API interviews at any level.
Trade-offs & pitfalls
Availability: a gateway that is horizontally scaled and stateless is not a bigger single point of failure than any other tier, but a gateway that grows to hold business logic becomes a deploy bottleneck for every service behind it, so keep it thin on purpose.
Performance: the extra hop at the gateway adds latency, but it is repaid by filtering malformed or unauthenticated traffic before it costs any downstream service compute, which is a net win under load.
Security: defense in depth means the service re-checks authorization even though the gateway already made a coarse allow decision. A common pitfall is deleting service-side authorization checks because "the gateway already checks it," which turns a misrouted internal call, a compromised adjacent service, or a gateway misconfiguration into a full authorization bypass.
Testing and observability: run contract tests that assert the gateway's allowed routes and the service's own authorization rules agree, so they cannot silently drift apart. Run synthetic BOLA probes directly against services in a staging environment, bypassing the gateway entirely, to confirm services do not rely on the gateway as their only defense. Correlate logs across the gateway and every service hop with a shared request ID, track 401/403 rates and rate-limit rejections per route as standing metrics, and alert when the gateway's allow decision and a service's deny decision disagree for the same request, since that disagreement is itself a signal of policy drift between the two layers.
Propose detection and mitigation strategies for abusive API usage and credential theft at scale. Cover techniques such as per-key behavioral baselines, anomaly detection, per-key throttling and freezing, ephemeral credential issuance, credential rotation, fingerprinting, and forensics-ready logging while balancing privacy and performance.
Sample Answer
Build a per-key behavioral baseline, normal request rate, endpoints touched, geography, for every API key, score each new burst of activity against its own history rather than a single global threshold, and respond with graduated actions, soft throttle, then freeze, then full revoke, so a false positive costs a legitimate client a slowdown, not a hard outage.
Per-key behavioral baselines
Track, per key, over a rolling window (for example, 7 days): request rate, endpoint mix, typical payload size, source IP or geography, and time-of-day pattern. Use a decaying window, weighting recent activity more, so a key's baseline adapts as legitimate usage genuinely changes, without being so reactive that an attacker can slowly retrain the baseline toward their own behavior, cap how fast the baseline itself is allowed to shift per day.
Anomaly detection
Combine simple rules, an absolute rate ceiling, or a geographically impossible gap between two consecutive requests, with a statistical or machine-learning layer, unsupervised outlier detection (flagging unusual activity by comparing it to the shape of normal data, with no need for pre-labeled examples of "bad") over the same behavioral features, so you catch both obvious abuse and subtler drift. Score risk as a combination of signals rather than one metric alone, as shown in the worked example below.
Per-key throttling and freezing
Use a graduated response: soft throttle (a reduced rate limit) at a moderate anomaly score, freeze (block new requests, let existing sessions time out) at a high score, and full revoke only after freeze plus either automated corroboration or human review, so a single noisy signal doesn't take down a legitimate integration outright.
Ephemeral credential issuance and rotation
For high-privilege operations, issue short-lived, single-purpose credentials, minutes rather than months, rather than relying solely on the long-lived key. Rotate long-lived keys on a fixed cadence automatically, with a grace overlap so rotation itself never causes an outage.
Fingerprinting
Collect signals that aren't tied to a person's identity. A TLS client fingerprint is the common starting point, since it's cheap to capture at the TLS layer with no application changes; an HTTP header ordering fingerprint and a hashed device signal are rarer, higher-effort additions worth reaching for only once TLS fingerprinting alone isn't separating attackers from genuine clients. The goal is to distinguish "the same script hitting us from many rotated IPs" from genuinely independent clients, without needing to know who the human behind it is.
Forensics-ready logging, balancing privacy and performance
Keep an append-only, tamper-evident log of every mitigation decision, the score, the signals that fired, the action taken, so an incident can be reconstructed after the fact. Store raw request bodies only when a risk threshold is crossed, sampled or fully captured once triggered rather than captured for every request by default, so both storage cost and privacy exposure scale with actual risk.
Worked example
Key partner-key-77 has a 7-day baseline of 150 requests/hour, 95% from a stable IP range, touching a consistent mix of 4 endpoints. In one hour it makes 900 requests (6 times baseline), from a new IP range, hitting a 5th endpoint it has never called before. Define a risk score:
score = rate_ratio + new_ip_flag + new_endpoint_flag
rate_ratio = 900 / 150 = 6
new_ip_flag = 2 (a range never seen before)
new_endpoint_flag = 1 (one never-seen endpoint)
score = 6 + 2 + 1 = 9
Thresholds: score >= 4 triggers a soft throttle (halve this key's rate limit); score >= 8 triggers a freeze (block new requests, page security on-call); score >= 15 triggers auto-revoke pending review. At a score of 9, the key is frozen and a human is paged, but not auto-revoked, since a new endpoint plus an IP change could still reflect a legitimate deployment change on the partner's side. The human reviewer's job is to distinguish that from theft within the freeze window before deciding whether to restore or revoke.
Trade-offs and pitfalls
Graduated response reduces false-positive damage but adds an operational cost, someone has to staff the review queue between freeze and revoke, size that team for your expected alert volume before relying on it. Behavioral baselines that adapt too quickly can be gamed by an attacker who ramps up slowly, capping the daily rate of baseline drift bounds this risk. Full-fidelity request logging aids forensics but raises both storage cost and privacy exposure if applied to every request, trigger deeper capture only once risk crosses a threshold, and document the retention window for that captured data separately from normal logs.
You're asked to architect a zero-trust setup for a hybrid environment exposing APIs to internal services, external partners, and mobile clients. Cover identity and access management, device posture checks, short-lived credentials, conditional access policies, service identity, TLS/mTLS, API gateway and enforcement points, and how to support clients in intermittent connectivity scenarios.
Sample Answer
Direct answer
A zero-trust design for a hybrid environment treats every caller, whether it is an internal
service, an external partner, or a mobile client, as untrusted by default and re-verifies
identity and context on every request, rather than granting broad access once a caller is
"inside the network." The core building blocks are strong identity for both users and services
(short-lived credentials instead of static secrets), device and context signals evaluated at
request time (conditional access), and a small number of well-defined enforcement points (an API
gateway plus per-service checks) that consistently apply policy across on-prem, multiple clouds,
and partner networks rather than each environment inventing its own rules.
Structured elaboration
Identity and access management. Every principal (human user, service, and partner
integration) needs a durable, centrally-managed identity, issued by a single identity provider
(or federated set of providers) rather than per-environment local accounts. Users authenticate
via OpenID Connect (OIDC, an identity layer built on OAuth 2.0) with the resulting token carrying
verified claims about who they are; services authenticate to each other using workload identity
(certificates or signed tokens tied to what the service is, not a shared secret it holds).
Device posture checks. For flows that originate from a device (a partner's engineer, a
mobile client), the access decision should factor in device state; whether it is managed,
patched, has disk encryption enabled, is not jailbroken/rooted, rather than trusting the network
location it is calling from. A request from a fully-patched, managed corporate laptop and one
from an unknown personal device should not receive the same default trust even if both present a
technically valid user token.
Short-lived credentials. Replace long-lived static API keys and passwords with
short-lived, automatically renewed tokens wherever the calling pattern allows it: OAuth access
tokens with lifetimes of minutes to a couple of hours, backed by refresh flows, and short-lived
certificates for service identity (paired with automated rotation, discussed further under
mTLS). A short lifetime bounds how long a leaked credential remains useful even if revocation is
delayed.
Conditional access policies. Access decisions combine identity, device posture, and context
(is this request from a location or pattern consistent with the user's history, is it during a
plausible time window, is the requested action unusually sensitive) into a policy evaluated at
request time, not just at login time; a session that started low-risk can be required to
step up (re-authenticate, add MFA) if its behavior later looks anomalous.
Service identity and enforcement points. Between services, mTLS (mutual TLS, where each side
proves its identity with a certificate) paired with a workload-identity standard like SPIFFE (Secure Production Identity Framework For Everyone, a standard for automatically issuing short-lived, verifiable identities to services)
gives every service a verifiable identity independent of network location, which matters
specifically because "hybrid" means you cannot rely on network topology (a private subnet, a VPN
tunnel) as a trust signal the way a single-cloud, single-network design sometimes does. An API
gateway sits at the edge for external and partner traffic as the primary enforcement point for
coarse-grained checks (authentication, rate limiting, gross authorization); internal
service-to-service calls enforce their own finer-grained authorization at each service, since a
single central gateway cannot see or safely encode every service's specific business rules.
Trust boundaries across on-prem, multi-cloud, and partner networks. Segment the environment
into explicit trust zones rather than assuming one flat network, and make every crossing between
zones go through an identity-checked enforcement point instead of being implicitly allowed by
network routing. For the cloud-side permissions surface specifically, CIEM (cloud infrastructure
entitlement management, tooling that inventories and right-sizes the often-sprawling permissions
granted to cloud identities and roles) is the practical mechanism for keeping the
identity-to-permission mapping from drifting into over-privilege as the environment spans
multiple cloud providers, each with its own IAM (Identity and Access Management, the system that governs who or what can access cloud resources) model; operationalize boundary changes with
automated testing (a policy change is deployed through the same CI/CD pipeline as code, with
automated checks that a proposed change does not accidentally widen an existing trust boundary)
rather than manual firewall-rule edits.
Supporting intermittent connectivity. Mobile and some partner clients cannot always reach the
identity provider or policy decision point in real time. Support this with short-lived cached
decisions (a token that remains valid, and whose validity can be checked locally via signature,
for a bounded window even if the issuer is briefly unreachable) rather than a hard requirement
that every single request round-trip to a live policy check; balance that against the same
short-lived-credential principle by keeping the cached window short enough that a revoked
credential is not usable for long after revocation.
Worked example
graph TD
C1[Internal Service] -->|mTLS plus SPIFFE identity| GW[API Gateway - PEP]
C2[External Partner] -->|OAuth token plus mTLS| GW
C3[Mobile Client] -->|short lived token plus device posture| GW
GW --> PDP[Policy Decision Point]
PDP -->|check identity, posture, context| IAM[Identity Provider]
IAM --> PDP
PDP -->|allow or deny| GW
GW --> BE[Backend Services]
The gateway is the policy enforcement point (PEP): it never decides trust on its own, it forwards
the identity and context signals it collected (which credential type, what device posture, what
network origin) to the policy decision point (PDP), which consults the identity provider and
returns an allow or deny. This separation is what lets the same enforcement logic apply
consistently whether the caller is an internal service crossing a cloud boundary, an external
partner, or a mobile client on an unreliable connection: the PEP's job (collect signals, forward,
enforce the verdict) does not change per caller type, only the specific signals available do.
Trade-offs and pitfalls
- A central policy decision point can become a latency and availability bottleneck. Cache
decisions locally at the enforcement point for a short, explicitly bounded window to absorb
brief PDP unavailability and reduce round-trip latency, rather than either making every request
block on a live PDP call or letting enforcement points make their own independent (and
potentially inconsistent) decisions. - Zero trust does not mean zero trust in the credential's assertions once verified, it means
not trusting network location as a substitute for verification; conflating the two leads teams
to over-engineer per-request re-verification for signals (like a properly-scoped, freshly-issued
short-lived token) that were already strongly verified moments earlier. - Common wrong turn: building the identity and policy layer first and treating multi-cloud
CIEM as a later cleanup task. Cloud IAM permissions sprawl quickly and independently of your
application-level zero-trust design; without CIEM-driven visibility from early on, the
"authorized" answer your policy layer gives can still be sitting on top of drastically
over-permissioned cloud roles underneath it. - Common wrong turn: applying identical policy rigor to every zone. A partner integration
handling low-sensitivity data does not need the same conditional-access strictness as an
internal service touching customer financial records; uniform maximum strictness everywhere
usually just produces friction that teams route around, rather than better security.
Explain the difference between authentication and authorization in the API context. Describe two common authentication methods (JWT bearer tokens and OAuth2 Authorization Code flow) and two authorization models (role-based access control RBAC and attribute-based access control ABAC). For each, give a short example of when it is appropriate.
Sample Answer
Authentication answers "who is calling?" and happens once, at the start of a request. Authorization answers "what is this caller allowed to do?" and gets checked on every action the caller attempts, even after authentication succeeds. In an API, a request must clear both gates, in that order, before it returns data.
Two ways to authenticate
JSON Web Token (JWT) bearer tokens. The server issues a signed token containing claims (who the user is, when it expires, sometimes their role). The client sends it as Authorization: Bearer <token>, and the server verifies the signature and expiry locally, without a database lookup. This is appropriate for stateless APIs and microservices where low latency and easy horizontal scaling matter more than instant revocation, for example a mobile app calling your own backend.
OAuth 2.0 Authorization Code flow. A standardized way for one application to get delegated access to a user's resources on another service, without ever seeing the user's password. The user is redirected to the authorization server's login page, authenticates there, and the calling app receives a short-lived code it exchanges (server-side) for an access token. This is appropriate when a third-party app needs to act on a user's behalf, for example a scheduling tool asking to read someone's calendar on a different platform.
Two ways to authorize
Role-Based Access Control (RBAC). Users are assigned roles, and roles carry a fixed set of permissions. It is simple to reason about and easy to audit ("who has the admin role?"). Appropriate for systems where permissions map cleanly onto job functions, for example an internal content tool with admin, editor, and viewer roles.
Attribute-Based Access Control (ABAC). The decision is computed from attributes of the user, the resource, the action, and the environment, evaluated against a policy at request time. Appropriate when access depends on runtime context a role alone can't express, for example "an employee may view a customer record only if that customer is in their assigned region."
Worked example
Request: GET /api/invoices/482 with a bearer JWT.
- Authentication: the API verifies the JWT's signature against the issuer's public key and checks
exp(the expiry timestamp). If either check fails, the response is401 Unauthorizedand processing stops here. If both pass, the caller's identity is established, saysub: "user_9fa2",role: "billing_viewer". - Authorization under RBAC: role
billing_viewercarries the permissioninvoice:read. A naive RBAC check only asks "does this role haveinvoice:read?" and answers yes, it never asks whether invoice 482 actually belongs touser_9fa2. - Authorization under ABAC: the policy instead evaluates
action == "read" AND resource.owner_id == subject.customer_id. If invoice 482 belongs to a different customer,resource.owner_id != subject.customer_id, and the policy returns deny,403 Forbidden, even though the same user'sbilling_viewerrole would pass a plain RBAC check.
This is the concrete difference between "can this role read invoices in general" (RBAC) and "can this specific caller read this specific invoice, right now" (ABAC).
Trade-offs and pitfalls
A common mistake is treating a passed authentication check as if it were also an authorization decision, that gap is exactly how broken-authorization bugs happen. RBAC is cheap to evaluate and simple to audit, but it is coarse: it cannot express "only your own records" without an added object-level check. ABAC is expressive enough to capture exactly that, but policies are harder to test exhaustively and can hide the real rule set inside a policy engine instead of a readable role list. Many production systems use both: RBAC for coarse feature access, ABAC (or a simpler ownership check) layered on top for record-level ownership.
Unlock Full Question Bank
Get access to all 24 API Security, Authentication and Authorization interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.