skip to content

You are choosing how Amazon API Gateway will authorize callers of a new API. Compare IAM (SigV4) authorization, a Cognito user pool authorizer, an HTTP API JWT authorizer, and a Lambda authorizer — what decides which one you pick?

level: middleimportance: must knowfreq 66%

answer

  1. start from the credential the caller holds
  2. AWS principals sign, users carry tokens
  3. built-in validators mean no code
  4. Lambda authorizer is the escape hatch
  5. gateway authz is not object-level authz

basics

~20 s

Pick by who the caller is. AWS principals get IAM SigV4. End users with tokens from an OIDC issuer get the built-in JWT authorizer on an HTTP API, or a Cognito user pool authorizer on a REST API. Anything else needs a Lambda authorizer.

solid answer

~50 s

Start with the credential the caller already holds. If callers are AWS principals — other services, other accounts, internal tooling — use `AWS_IAM`: they sign with SigV4 and access is decided by `execute-api:Invoke` permissions plus the API's resource policy, with no code and no token plumbing. If callers are end users carrying an OIDC-issued JWT, use a built-in validator: an HTTP API's JWT authorizer, configured with an issuer URL and audience, works with any compliant issuer and can enforce scopes per route; a REST API's Cognito user pool authorizer does the equivalent but only against a Cognito user pool. Reach for a Lambda authorizer when neither fits — opaque or third-party tokens, decisions that depend on several headers or the source IP, per-request context you want to hand to the backend, or dynamic policies. The tradeoff is that a Lambda authorizer is code you own and an extra invocation on the request path, which is why its result caching matters.

go deeper

for a junior

Be able to name the four options and say who each is for: AWS callers sign requests, end users bring tokens, and a Lambda authorizer covers anything custom.

for a middle

Explain what each built-in actually validates — SigV4 signature and execute-api:Invoke versus signature, issuer, audience, expiry and scope — and what pushes a design to custom code.

for a senior

Justify a choice against latency, operational ownership and blast radius: an extra invocation on the hot path, cold starts, and a hand-written verifier as a security liability you now maintain.

for a principal

Own the standard across many APIs — one issuer or many, whether teams may write their own authorizers, and what identity contract the platform guarantees to every backend behind the gateway.

## The question behind the question Interviewers ask this to see whether you reason from the caller's existing credential rather than from a favourite service. Every option below is a way of answering "what evidence does this caller already have, and who can check it?" ## IAM authorization (SigV4) Setting a method's authorization type to `AWS_IAM` means the caller must sign the request with AWS Signature Version 4 using AWS credentials, and API Gateway then evaluates whether that principal is allowed the `execute-api:Invoke` action on the method's ARN. **Choose it when the caller is an AWS principal**: another service in your account, an EC2 instance or Lambda function using its role, a partner account, an internal CLI. You write no authorizer code, credentials are short-lived when they come from a role, and every AWS SDK signs automatically. It also unlocks the API's **resource policy**, which lets you condition access on things an identity policy cannot express — source IP ranges, a specific VPC endpoint, an organization ID. **Do not choose it for the general public.** Handing AWS credentials to end users of a web or mobile app is the wrong shape (the exception being an identity broker that mints scoped short-lived credentials, which is a Cognito identity-pool pattern rather than something you build ad hoc). ## Cognito user pool authorizer (REST APIs) You attach an authorizer that points at a Cognito user pool. The client sends the pool-issued token in the `Authorization` header; API Gateway validates the signature and expiry against the pool before your integration runs, and exposes the token's claims to the backend as `$context.authorizer.claims`. No code, no key fetching, no verification logic in your services. The constraint is in the name: it validates tokens from **Cognito user pools only**. It also has a subtlety worth knowing — the plain configuration accepts the ID token, whereas configuring authorization scopes on the method requires an access token, because scopes live there. ## JWT authorizer (HTTP APIs) HTTP APIs ship a built-in JWT authorizer configured with two things: an **issuer** URL and one or more **audience** values. API Gateway discovers the issuer's signing keys and validates the token's signature, expiry, issuer and audience before invoking the route. You can additionally list required scopes per route, so a read route and a write route on the same API can demand different scopes. The reach is broader than Cognito's: any standards-compliant OIDC issuer works, including a Cognito user pool addressed as an issuer. The constraint is that it is an **HTTP API feature** — a REST API does not have it, and if you need REST-only features you are back to a Cognito authorizer or a Lambda authorizer. ## Lambda authorizer Your own function receives the request (a single header for a TOKEN authorizer, the full request for a REQUEST authorizer), decides, and returns an IAM policy plus a `context` map that API Gateway passes to the integration. **Choose it when nothing built-in fits**: an opaque token that must be introspected against a remote service, a legacy header scheme, mutual-TLS-derived identity, a decision combining the token with the source IP or the path, or a need to enrich the request with tenant and entitlement data that the backend should trust. It is the only option that lets you return a *dynamic* policy — allow these paths, deny those — computed per caller. **The costs are real.** It is code you write, test, patch and page on. It adds an invocation to the request path, with a cold start on the first call after idle. Its result is cached to amortise that, and the cache introduces its own behaviour you must design for. And because it is your code, a bug in it is a security hole with no vendor to blame. ## A decision order that survives follow-ups 1. Are callers AWS principals? → `AWS_IAM`, and use the resource policy for network-shaped conditions. 2. Do callers hold an OIDC-issued JWT? → HTTP API JWT authorizer if you can use an HTTP API; Cognito user pool authorizer if you are on a REST API and the issuer is a user pool. 3. Neither, or the decision needs more inputs than a token? → Lambda authorizer. 4. Public and genuinely unauthenticated? → authorization `NONE`, and put the controls elsewhere — a resource policy, WAF, and per-client limits. ## Two things to say out loud First, these are not exclusive across an API: different methods or routes can carry different authorization types, so an internal admin route can require IAM while public routes take JWTs. Second, none of them removes the need for authorization *inside* the service. The gateway decides whether the caller may reach the endpoint; whether this caller may see *this record* is an object-level check your code still owns.

  • Can different methods on the same API use different authorization types?
    Yes. Authorization is configured per method on a REST API and per route on an HTTP API, so an internal `/admin` method can require `AWS_IAM` while public methods use a JWT authorizer, and a health check can be `NONE`. That is a common and legitimate shape — just make sure the open routes really are safe to leave open.
  • The API validates a JWT at the gateway. Does the backend still need to check anything?
    Yes. The gateway answers "may this caller reach this endpoint". It cannot answer "may this caller read invoice 4821", which depends on data the gateway never sees. Object-level authorization stays in the service, driven by the verified identity the authorizer passed through — not by an identifier the client supplied.
  • What pushes you from a built-in JWT authorizer to a Lambda authorizer even when callers do hold JWTs?
    Needing inputs the built-in cannot see or actions it cannot take: introspecting an opaque or revocable token remotely, combining the token with source IP or path, mapping claims into enriched backend context, or returning a per-caller policy that allows some paths and denies others. Anything beyond signature, issuer, audience, expiry and scope.

saying these in an interview costs you the question

  • Proposes handing AWS credentials to public mobile users
  • Thinks a Cognito user pool authorizer validates any OIDC issuer's tokens
  • Assumes the JWT authorizer is available on REST APIs
  • Writes a Lambda authorizer to re-implement standard JWT validation
  • Treats gateway authorization as sufficient object-level authorization

context