API Gateway REST Authorizer Caching: Match the Key to the Policy
Review REST API REQUEST authorizer caching through ordered identity sources, method policy scope and a synthetic request sequence before changing access.
Primary sources checked
Diagnose the cache contract before widening the policy
When one API method works and a second method fails for the same caller, compare the Lambda authorizer's cache key with the complete policy it returned. A cached policy permitting only the first method can leave the second method without an Allow. Expanding that policy to every resource can remove the symptom while authorizing operations the caller should never perform.
The useful decision is whether each cached result remains correct for every request that can reuse it. Review three things together: the ordered identity-source values, the policy's permitted and denied method resources, and the period during which the result may remain usable. Keep current object-level authorization at the service that owns the object.
This guide covers Amazon API Gateway REST APIs using a REQUEST Lambda authorizer and IAM-policy responses. It helps an API engineer and security reviewer explain a suspected cache-scope mismatch and choose a bounded correction. It excludes HTTP API simple Boolean responses, Cognito authorizers, IAM-only methods, WebSocket APIs, cross-account policy combinations and response caching. Their configuration and evaluation rules need separate review.
All identities, methods and request outcomes in the worked sequence are constructed teaching inputs. No AWS account, deployed API, token, request log or customer data was inspected or invoked. The default task is review of already authorized configuration and sanitized evidence. A future isolated exercise needs its own approved scope.
Separate authorizer execution from policy evaluation
The Lambda function produces a principal identifier and policy. API Gateway evaluates the returned policy to decide whether the method can be invoked. With caching enabled, later requests can reuse that policy without another Lambda authorizer invocation. A new API request therefore does not necessarily produce a new authorizer decision. AWS describes these separate steps in its REST Lambda authorizer workflow.
That distinction explains a diagnostic pattern: a successful first call appears in the authorizer's logs, a later method fails, and there is no corresponding second authorizer execution. This pattern is consistent with reuse, but an absent log alone does not establish a cache hit. Logging might be incomplete, the method might use another authorizer, or an earlier control might have rejected the request. Bind the evidence to the actual method, stage and authorizer before changing anything.
A configuration read also cannot reconstruct the policy held under one key at an earlier instant. Use a protected reference to the relevant returned policy, a deliberately redacted decision record or a separately authorized isolated reproduction. If none exists, retain the policy-content question as UNKNOWN rather than claiming to have read the cache itself.
The returned policy contains statements about execute-api:Invoke and method resources. The authorizer output contract describes that response, including its principal and optional context. The policy is more than a Boolean approval for the first request. Review every relevant statement, including Deny entries and wildcard expansion, rather than looking for one Allow line.
A backend receiving trusted authorizer context still has to authorize its business operation. Permitting GET /invoices says nothing by itself about which invoices may be returned. A cache fix that makes a method reachable can expose a missing application check that the earlier accidental denial concealed.
Write down exactly which requests share a result
For a cached REQUEST authorizer, AWS derives the key from all configured identity sources and preserves their order. Missing, null or empty required sources can produce a 401 response before the Lambda function runs. When caching is disabled, the request is passed to the authorizer without that caching prerequisite. These are documented REQUEST-authorizer behaviors, not evidence that a supplied header represents a trusted identity.
Record the ordered source expressions from the actual deployed configuration. Then describe the values for two requests without storing their raw credentials. For example, an internal fixture label can represent the same synthetic bearer value in both requests. A support report should retain a protected evidence reference or suitably handled opaque correlation, not copy Authorization headers into a ticket or screenshot.
An additional tenant header makes two cache keys different only if it is included in the configured sources and its value differs. It does not prove membership in that tenant. The authorizer must validate requested scope against trusted identity and policy; the backend must enforce object access. Otherwise a caller could choose which cached permission set to request by changing an untrusted label.
Use the input contract precisely. The REST authorizer input documentation distinguishes caller-supplied headers, query strings and path parameters from deployment stage variables and request context. Path parameters are available to the function, but cannot themselves be identity sources. Do not propose method.request.path.invoiceId as a supported caching fix because the function can read an invoice identifier.
AWS's configuration guide describes $context.path and $context.httpMethod for method-specific policy. Preserve the distinction between a documented context variable and its expression in the selected console, OpenAPI or infrastructure configuration. Read back the deployed source expressions instead of copying syntax from another API type. The separate HTTP API authorizer guide uses $context.routeKey; its simple-response behavior is outside this REST guide.
Evaluate the returned resources with the other policy controls
A policy resource identifies an API execution scope, including API, stage, verb and path. The API execution policy reference documents that format and wildcard behavior. Compare the expanded set of reachable methods before and after a proposed change. A wildcard inserted to repair one denied read can also cover a write or administrative method.
There is a further trap when interpreting an implicit denial. AWS evaluates Lambda-authorizer policy together with an API resource policy when one is attached. Its authorization workflow and Table A show that a same-account resource-policy Allow can combine with an authorizer policy that is silent for the request. An explicit Deny behaves differently. A narrow authorizer Allow is therefore not universally equivalent to an API-wide deny list.
For the worked sequence below, assume there is no API resource-policy grant, explicit denial or other control changing the simplified result. The two methods have the stated authorizer attached, both use an inert integration, and the selected environment supports them. Those assumptions isolate one mechanism. If a real resource policy is present, include its applicable statements and conditions before classifying the outcome.
Keep the classifications separate: missing identity source, authorizer authentication failure, no matching policy Allow, explicit policy Deny, invocation/configuration error, and backend denial. A client-visible 403 is not enough to distinguish them, particularly where gateway responses are customized. The operator needs the response category, method configuration, policy reference and available invocation evidence.
Worked example: first-method success and second-method denial
Consider one fictional REST API, stage review, and synthetic principal reader-a. Its business permission allows two collection reads: GET /reports and GET /invoices. It must not permit POST /invoices. These paths contain no real records. Every request in this example occurs within a deliberately stipulated unexpired cache interval; no production TTL or exact execution timing is claimed.
Configuration C1 uses only the bearer header as its cache-key input. The illustrative authorizer validates that synthetic credential but returns an Allow for the incoming method only. For the first GET /reports, policy P1 consequently permits only that exact method resource. There are no other statements or grants in this fixture.
| Request in C1 | Stipulated cache state | Expected authorizer work | Expected edge result under the fixture assumptions |
|---|---|---|---|
First GET /reports with fixture credential A | Empty for A | Produce P1, allowing only GET /reports | Allow the reports method |
Then GET /invoices with the same A | P1 retained for the same key | No new Lambda authorizer invocation | No matching Allow for invoices, so implicit denial |
Then POST /invoices with the same A | The same P1 retained | No new Lambda authorizer invocation | No matching Allow for the write, so implicit denial |
GET /reports without the required bearer source | Required source missing | Lambda authorizer is not invoked | 401 before the function, not a policy-scope observation |
- First
GET /reportswith fixture credential A - Stipulated cache state: Empty for A
- Expected authorizer work: Produce P1, allowing only
GET /reports - Expected edge result under the fixture assumptions: Allow the reports method
- Then
GET /invoiceswith the same A - Stipulated cache state: P1 retained for the same key
- Expected authorizer work: No new Lambda authorizer invocation
- Expected edge result under the fixture assumptions: No matching Allow for invoices, so implicit denial
- Then
POST /invoiceswith the same A - Stipulated cache state: The same P1 retained
- Expected authorizer work: No new Lambda authorizer invocation
- Expected edge result under the fixture assumptions: No matching Allow for the write, so implicit denial
GET /reportswithout the required bearer source- Stipulated cache state: Required source missing
- Expected authorizer work: Lambda authorizer is not invoked
- Expected edge result under the fixture assumptions: 401 before the function, not a policy-scope observation
Constructed C1 comparison. Both reads are permitted by the business rule, but the first request's cached policy permits only reports. An API resource-policy grant or another denial changes the combined evaluation; inspect it separately.
The first synthetic GET reports request arrives with fixture credential A and an empty cache entry. The authorizer returns P1, which permits only the reports method. A later GET invoices request presents the same credential while the stipulated interval remains unexpired. Because C1's key contains only that value, it reuses P1 without another Lambda authorizer execution. P1 contains no invoices Allow. Under the explicit assumption that no other grant or Deny changes either result, reports is permitted and invoices is implicitly denied. The business permission allows both reads. The discrepancy is the reusable policy's scope, not evidence that the second credential is invalid. No AWS request or deployment was observed.
These are expected distinctions derived from the documented mechanism and stated policy, not captured AWS responses. In a real exercise, record observed results separately. Confirm the first allowed control reaches the inert integration, so that an unavailable target cannot make every later test look safely denied.
Now consider correction C2. Keep the header-only key but return a policy that covers this principal's complete permitted method set: the two named reads and no write permission. A new result must first be established in the isolated configuration; do not assume a source-code edit replaces an already cached P1. Once the stipulated complete policy is the reused result, both reads have an Allow and the write remains outside it. Check for any separate resource-policy grant before treating that omission as a real denial.
Correction C3 uses a separately reviewed key with the bearer value, request path and HTTP method, while the authorizer produces a policy for that particular request. Changing from reports to invoices then changes the key, so the second read needs a separate result. A request for the write also needs its own result; the authorizer must reject it according to the business rule. Adding key dimensions creates separation, not permission correctness. An authorizer that returns Allow for every incoming method remains unsafe under C3.
Use a denied-first sequence too. Establish a denied result for POST /invoices, then request an allowed read with the same credential. A cached denial that is too broadly scoped can reject the read. A broad Allow can do the opposite. Preserve the actual statement resources and ordering of requests when reproducing an incident; changing the first request can change which policy gets reused.
Choose the smallest correction that remains correct on reuse
Three approaches deserve comparison. They change authorizer work and operational responsibility in different ways; none removes the backend's object checks.
| Approach | Suitable condition | Review cost or remaining risk |
|---|---|---|
| Return the complete authorized method policy for the reusable identity key | The permitted set can be computed correctly and remains suitable for the accepted interval | Policy construction, broad patterns, growth and changing permissions need review |
| Partition REQUEST results by approved context such as path and HTTP method | The decision intentionally differs by method and those inputs identify the necessary boundary | More key variants and authorizer work; object state and credential freshness still need controls |
| Disable authorization caching | The workload requires a fresh function decision and accepts the measured dependency/load consequences | The function and its dependencies need to sustain the request pattern; its own caches can still be stale |
- Return the complete authorized method policy for the reusable identity key
- Suitable condition: The permitted set can be computed correctly and remains suitable for the accepted interval
- Review cost or remaining risk: Policy construction, broad patterns, growth and changing permissions need review
- Partition REQUEST results by approved context such as path and HTTP method
- Suitable condition: The decision intentionally differs by method and those inputs identify the necessary boundary
- Review cost or remaining risk: More key variants and authorizer work; object state and credential freshness still need controls
- Disable authorization caching
- Suitable condition: The workload requires a fresh function decision and accepts the measured dependency/load consequences
- Review cost or remaining risk: The function and its dependencies need to sustain the request pattern; its own caches can still be stale
Do not select the second option using a route template without checking which requests it groups. AWS defines $context.path as a request path and $context.resourcePath as the resource path in its context-variable reference. They are not interchangeable names. A proxy resource can group many concrete paths under one resource declaration. Inventory the actual values under the deployed mappings and decide whether that grouping fits the policy.
Similarly, including an entire sensitive query string or attacker-controlled unbounded value can create unwanted disclosure or many distinct entries. Choose only the necessary supported identity sources, keep their meaning explicit and inspect the operational impact. This guide makes no cache-capacity, hit-rate, latency or cost forecast. Measure the selected traffic mix before expanding a configuration that invokes the function more often.
Keep cache lifetime separate from credential lifetime
The REST Authorizer API contract defines authorizerResultTtlInSeconds: zero disables caching, the omitted default is 300 seconds, and the maximum is 3600 seconds. Those are service configuration limits, not recommended security settings. An omitted field in a configuration template is not proof that the deployed authorizer uses the value the reviewer intended.
A returned policy's reuse interval is different from a credential's expiry or a membership change. If the custom function performs those checks only when it runs, a cache hit does not rerun that code. The design must establish how the required freshness rule is enforced on reused requests. Do not assume that writing an expiry value into custom authorizer context creates a new API Gateway cache-expiry rule.
For example, if an application requires a revoked membership to stop an operation immediately, an earlier cached permission cannot establish current membership. Choose a current enforcement point or a separately reviewed containment design. If the application accepts a bounded authorization age for a particular harmless read, document who accepted it and which actions remain excluded. No universal cache TTL follows from this guide.
Disabling the gateway cache also does not eliminate a stale entitlement cache inside the function or its provider. Follow the full decision path. Keep provider key caching, token validation, API authorizer-result caching, response caching and backend authorization state as distinct records. Their names all include caching, but changing one does not necessarily invalidate another.
Retain an evidence record without retaining credentials
Begin with existing, explicitly authorized reads. GetAuthorizer exposes configuration such as the type, identity sources and TTL. GetMethod exposes the method's authorization type and authorizer ID. Have the owner bind those reads to the API, resource, stage deployment and Lambda revision that served the request. A current editor configuration alone cannot reconstruct an earlier deployment.
Use this worksheet for one configuration revision and its permitted request set. Attach restricted evidence by reference rather than placing tokens, full policies containing sensitive identifiers, or payloads in a public incident document.
| Evidence group | Record before choosing a correction |
|---|---|
| Serving configuration | API type, account/Region reference, API and stage, deployment evidence, method attachments and authorizer/function revision |
| Reuse boundary | Ordered identity-source expressions, opaque fixture value labels, actual path/context interpretation and configured TTL |
| Effective permission | Complete authorizer policy reference, expanded method resources, applicable API resource policy and other denial controls |
| Business rule | Allowed principal/method combinations, backend object checks and accepted freshness requirement |
| Request sequence | Order, warm/cold premise, native request references and each intended method |
| Observations | Client response category, covered authorizer invocation evidence and independent inert-integration observation |
| Decision | Which mismatch is supported, which fields remain UNKNOWN, chosen correction and responsible reviewer |
| Recovery | Approved stop control, cache-change or flush scope, retest cases, uncertain effects and reopening condition |
- Serving configuration
- Record before choosing a correction: API type, account/Region reference, API and stage, deployment evidence, method attachments and authorizer/function revision
- Reuse boundary
- Record before choosing a correction: Ordered identity-source expressions, opaque fixture value labels, actual path/context interpretation and configured TTL
- Effective permission
- Record before choosing a correction: Complete authorizer policy reference, expanded method resources, applicable API resource policy and other denial controls
- Business rule
- Record before choosing a correction: Allowed principal/method combinations, backend object checks and accepted freshness requirement
- Request sequence
- Record before choosing a correction: Order, warm/cold premise, native request references and each intended method
- Observations
- Record before choosing a correction: Client response category, covered authorizer invocation evidence and independent inert-integration observation
- Decision
- Record before choosing a correction: Which mismatch is supported, which fields remain UNKNOWN, chosen correction and responsible reviewer
- Recovery
- Record before choosing a correction: Approved stop control, cache-change or flush scope, retest cases, uncertain effects and reopening condition
Do not fill observed invocation or integration fields from a desired result. If the evidence collector's coverage is unknown, a missing log remains an observation gap. API Gateway's built-in authorizer test is useful for the function response but is not a substitute for the real deployed method path or its cache history. The configuration guide also notes restrictions on modifying context values in that test.
Rehearse warm and cold requests in an isolated boundary
Any execution must use an explicitly authorized disposable stage, synthetic credentials and records, scoped identities, fixed request limits and an inert integration that cannot send notifications, charge money or mutate production. Verify the stop path and the observer's ability to inspect integration attempts before starting. Do not exercise a known overbroad Allow against a live protected API merely to make the failure visible.
Predeclare the permitted two reads and forbidden write, then retain the request order from C1. Add a cold allowed control for each read, a warm cross-method call, a denied-first sequence, missing source, a second synthetic principal and changed entitlement after cache population. Include direct or alternative backend entry points in the owning application's separate authorization review. That is necessary context, not proof that this cache exercise covered every path.
Capture gateway result, function execution and integration attempt independently. A Lambda invocation proves execution, not a correct policy. An edge Allow proves passage through that boundary, not a correct returned business record. A forbidden inert integration attempt should fail the intended edge restriction even if the inert target later refuses it. A transient configuration error should not count as a passed negative-authorization test.
Stop immediately if a real credential enters the worksheet, an unexpected target is reachable, configuration identity drifts, or effect observation is lost. Preserve the relevant references and hold new test requests. Do not retry an uncertain mutating operation. The fixture's write is inert, but production recovery still needs the service owner's effect reconciliation.
Recover the correct boundary, then close one decision
An authorized operator may need to change the key, disable caching or replace the returned policy. Read back the intended deployment and establish a new cold result under the corrected configuration before repeating warm requests. AWS documents cache-key changes with redeployment in its REST authorizer guide. Do not infer that editing a Lambda policy builder alone invalidates every cached result.
The separate FlushStageAuthorizersCache API flushes all authorizer entries for a stage and returns 202 with an empty body on success. It is not a per-user revocation control or the response-cache flush operation. Such a stage-wide change can increase fresh authorizer work and needs its own owner and capacity review. A response acknowledgement does not replace a post-change allowed/denied sequence through the affected methods. This guide supplies no flush command or authority to execute one.
Restoring an earlier configuration is appropriate only if its grants, identity assumptions and freshness rules remain valid. Do not recover availability by removing method authorization or replacing a narrow policy with unrestricted access. Reconcile any earlier effect separately: changing future authorization does not retract an already returned record or undo a committed write.
Close the review with one supported statement, such as: under configuration C1 and the stated policy combination, the two reads share a cache key but only the first has an Allow in the reused policy. Leave actual deployment observations UNKNOWN until collected. For the next action, choose the first missing configuration or evidence item and assign it to the API, identity or application owner. Use the broader gateway operating-contract paper for system-wide responsibilities, and the API security review for object and property checks. This guide owns the narrower REST authorizer cache contract.
Related services
API Development Services
API development services for REST, GraphQL and integrations. Design backend contracts, security, data integrity and operating controls around your existing systems.
Cloud Security Architecture Consulting
Cloud security architecture consulting for AWS and GCP. Review IAM, network boundaries and compliance requirements, then implement agreed security controls.