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.
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.
Your platform needs to expose both internal and external APIs, and engineering is weighing several authentication approaches (API keys, a couple of OAuth2 flows, mTLS, token introspection) with real differences in developer friction, security posture, and how hard each is to walk back if it goes wrong. As the PM, how would you drive that decision, and how would you sequence the rollout and migration so partner integrations don't break?
Sample Answer
Direct answer
A strong PM answer treats this as a decision-and-migration problem, not a pure technology pick. Segment by trust boundary first: internal service-to-service traffic and external partner-facing traffic almost never need the same mechanism, so this is usually two decisions bundled into one question. Run the choice through a short written framework scored on security posture, developer friction, and reversibility (how expensive it is to undo if the pick is wrong), with security and platform engineering as required co-owners, not reviewers of a finished plan. Then sequence the rollout so the new mechanism runs in parallel with the old one until usage data, not a calendar guess, says it is safe to cut over.
Structured elaboration
How I would drive the decision
- Put it in writing as a short decision document, not a meeting debate: state the problem, the options, and any non-negotiables up front (for example, "no new integration ships on a static secret that cannot be rotated").
- Segment the surface area instead of forcing one answer everywhere. (OAuth 2.0 is an authorization framework: it lets one service grant another a limited, revocable token to act on its behalf without ever handing over a password.)
- Internal, high-trust, service-to-service calls: favor mTLS (mutual TLS, where both the client and the server present certificates to authenticate each other) if you already run internal certificate infrastructure, or OAuth 2.0's client_credentials grant (a machine-to-machine, M2M, flow with no human in the loop) if you do not want the added operational weight of a certificate authority yet.
- External, partner-facing calls acting purely machine-to-machine: OAuth 2.0 client_credentials is usually the right default, short-lived, centrally issued, easy to scope per partner.
- External flows acting on behalf of an end user: the authorization_code grant with PKCE (Proof Key for Code Exchange, an extra verification step that protects clients like mobile or single-page apps that cannot hold a secret safely).
- Legacy or low-risk partners: API keys can stay acceptable short-term, but only behind a gateway enforcing rate limits and short expiry, never as the long-term answer for anything sensitive.
- Score every option against the same four criteria so the comparison is not vibes-based: security posture (how hard to compromise, how much damage if compromised), partner/developer friction (how much integration work this creates), reversibility (an API key is one field to revoke; mTLS means certificates already distributed into every partner's infrastructure, which is far harder to unwind), and operational cost to your own team (does this require new infrastructure, such as token introspection, a live check-in with the authorization server asking "is this token still valid right now," which matters when you need same-second revocation that a self-contained signed token cannot give you).
- The PM's actual job here is forcing the trade-off onto one page, setting a decision deadline, and acting as tie-breaker when security wants maximum lockdown and partner-success wants zero friction.
How I would sequence rollout and migration without breaking partners
- Inventory every current consumer, internal and external, and tag each by risk tier and engineering maturity (dedicated eng contact vs. a small partner running unmaintained code).
- Ship the new auth path dual-stack: the gateway accepts both the old mechanism and the new one at the same time. Nothing old is removed yet.
- Migrate the lowest-risk, highest-maturity consumers first as a pilot. Publish a migration guide and client SDKs, and open a sandbox environment partners can test against without touching production credentials.
- Track migration by actual gateway-logged usage of each auth mechanism, not by partner self-report, so stragglers surface early instead of on cutover day.
- Set and communicate a firm deprecation date well in advance, with reminders at fixed intervals, but keep a short, individually agreed grace period available for the partners who are genuinely behind.
- Retire the old mechanism only once usage is at or near zero for that endpoint class, not on the calendar date alone.
Worked example
This is an illustrative walkthrough of the sequencing logic, not a reported metric. Say the platform has 30 external partner integrations on static API keys and 10 internal services calling each other with no consistent auth today.
- Month 0: decision document approved. Internal services begin moving to mTLS using an existing lightweight internal certificate authority; external partners get a new OAuth 2.0 client_credentials path stood up alongside the existing API keys.
- Months 1 to 2: the gateway accepts both the old API key and the new OAuth 2.0 token on every external endpoint. Migration guide, SDK, and sandbox ship. The 5 partners with dedicated engineering contacts pilot the new path first; gateway logs confirm all 5 fully cut over with zero remaining API-key traffic.
- Months 3 to 4: the remaining 25 partners get a firm cutover date, staged reminders, and office hours. By the deadline, logs show 22 have migrated and 3 have not touched it.
- Month 5: the 3 holdouts get direct, individual outreach and a short, named extension rather than an indefinite one, because breaking a live partner integration outright is a worse outcome than a two-week schedule slip. Once those 3 migrate, API keys are disabled for that endpoint class entirely.
The pattern worth naming: nothing is switched off on a calendar date by itself. The date is the forcing function; the usage data is the actual trigger.
Trade-offs & pitfalls
| Mechanism | Security posture | Partner friction | Reversibility if wrong |
|---|---|---|---|
| API keys | Weak: static secret, easy to leak, coarse revocation | Lowest | Easy: rotate or revoke one key |
| OAuth 2.0 client_credentials (M2M) | Good: short-lived, per-client scoped tokens | Moderate: partner registers a client | Moderate: revoke the client, tokens expire quickly |
| OAuth 2.0 authorization_code + PKCE | Strong for user-delegated access | Higher: redirect and consent flow | Moderate: revoke refresh tokens |
| mTLS | Very strong: mutual certificate-based identity | Highest: partner must manage certificates | Hard: certificates already distributed into partner infrastructure |
| Token introspection | Adds real-time revocation on top of any of the above | Transparent to the partner, adds a network hop of latency | Not a standalone choice, a capability layered on top |
Common mistakes to flag as a strong candidate:
- Treating this as one decision instead of two: internal and external traffic almost always deserve different answers.
- Defaulting to the "most secure" option (mTLS) everywhere without weighing that it is also the hardest to reverse once partners have provisioned certificates against your system. This is close to what OWASP API Security Top 10 (2023 edition) tracks under API2:2023, Broken Authentication: the risk is not just choosing a weak mechanism, it is choosing one whose failure and revocation behavior was never stress-tested against real-world needs.
- Setting a hard cutover date with no dual-support window, which is what actually breaks partner integrations.
- Measuring migration by partner self-report instead of gateway-level usage data, which hides stragglers until cutover day.
- Leaving deprecation open-ended "until everyone migrates," which in practice means never. A named date with a short, explicit, individually granted extension path is what actually closes a migration out.
You're asked to stand up the security review program for a new public API platform ahead of its GA launch. Walk through how you'd structure it: which risks you'd prioritize first, what preventative controls you'd put in place before launch, and what you'd keep watching once it's live in production.
Sample Answer
Structure the program in three phases: pre-launch threat modeling and preventative controls scoped to the risks that cause the most damage per unit of attacker effort, a launch gate that blocks general availability (GA) until those controls are verified, and a production watch phase instrumented for the risks that can't be fully closed by design alone.
How I'd prioritize
I rank risks by two things: how directly they lead to unauthorized data exposure or account takeover, and how cheap the exploit is for an attacker. An authorization bug found by just changing an ID in a URL is far cheaper to exploit than social engineering, so it ranks higher even if it sounds less dramatic.
- Object-level and function-level authorization ("can user A act on user B's resource, or reach an admin-only endpoint?"), first, because it fails silently, no crash, no error, and is trivially automatable for an attacker who just increments an ID.
- Authentication weaknesses (weak token validation, no PKCE (Proof Key for Code Exchange, a mechanism that stops a stolen OAuth authorization code from being redeemed by anyone but the original app) for public OAuth clients, unrotatable long-lived API keys), second, because a break here undermines every other control.
- Injection and unsafe input handling, third, still critical, but usually caught by standard parameterization and ORM discipline and easier to test for automatically than authorization logic.
- Unrestricted resource consumption (no rate limits or pagination caps), fourth, usually an availability or cost risk rather than a data-breach one, but cheap for an attacker and easy to miss until traffic actually scales.
This ordering maps closely onto the current OWASP (the Open Web Application Security Project, the industry group that publishes this ranked list of API risks) API Security Top 10 (the 2023 edition, API1:2023 through API10:2023, a different and narrower list than the general OWASP Top 10 for web applications broadly): API1:2023 Broken Object Level Authorization and API5:2023 Broken Function Level Authorization sit at the top for the same reason I put authorization first, and API4:2023 Unrestricted Resource Consumption covers the rate-limit risk. I'd use the framework to sanity-check I haven't missed a category, not as a substitute for reasoning through this platform's own risk.
Preventative controls before launch
- Threat-model each resource: for every object identifier exposed in a URL or body, write down how ownership is proven server-side.
- Schema-first request and response validation (OpenAPI plus strict JSON Schema) that rejects unknown fields, closing both injection surface and over-posting in one control.
- Object- and function-level authorization checks written as automated contract tests in CI: "a user with role X, calling endpoint Y with someone else's ID, must get 403 or 404, never 200."
- Rate limiting and quotas enforced at the gateway before real traffic arrives, not bolted on after an incident.
- Secrets and signing keys in a managed vault or key management service (KMS) from day one, never in application config.
- A launch gate: GA does not ship until the CI authorization test suite and a manual penetration test both pass.
What I'd keep watching after GA
- Authorization failure rate (401/403 spikes) and anomalous ID-enumeration patterns, many requests, tightly sequential IDs, from one client.
- New endpoints shipped without going through the same contract-test gate, this is where teams regress once launch-week velocity pressure returns.
- Inventory drift: undocumented or shadow API versions still reachable (Improper Inventory Management, API9:2023), since a platform's real attack surface tends to grow beyond what's in the current OpenAPI spec.
- Outbound calls the platform itself makes to third-party APIs (Unsafe Consumption of APIs, API10:2023), since a compromised dependency can flow back through your own trusted service identity.
Worked example
Take GET /v1/orders/{orderId}. Before launch, the CI-blocking contract test suite includes:
- Authenticated as
user_A(owns order 501):GET /v1/orders/501expects200. - Authenticated as
user_A, requesting order 502 (owned byuser_B): expects403or404, never the order body. - Unauthenticated:
GET /v1/orders/501expects401. - Authenticated with an expired token: expects
401.
If test 2 ever starts returning 200, the pipeline blocks the deploy automatically, converting broken object-level authorization from a manual-review risk into a mechanically-enforced gate. After launch, the same request shape becomes the monitoring signal: alert if a single token issues more than, say, 50 distinct orderId lookups in a minute, since that traffic shape is a strong enumeration signature regardless of whether any individual call succeeds.
Trade-offs and pitfalls
Strict schema validation catches a lot for free but can break legitimate clients mid-transition, version and stage the enforcement. Automated authorization tests only catch what you thought to write, this is why periodic manual penetration testing stays necessary even with a mature suite. A launch gate that's too heavy slows GA and invites teams to route around it under deadline pressure, keep the blocking checklist short and non-negotiable (authorization tests, secret scanning, rate limits) and push deeper anomaly-detection tuning to the post-launch watch phase instead.
That is every published API Security, Authentication and Authorization question for Technical Product Manager so far. Browse the other topics in this category, or practice this one interactively.