Summary
When a REST API method uses a Lambda REQUEST authorizer (as opposed to TOKEN), the Lambda function receives an event containing only type and methodArn. Real AWS sends the full APIGatewayRequestAuthorizerEvent shape including requestContext, headers, multiValueHeaders, queryStringParameters, pathParameters, stageVariables, etc.
Reproduction
- Create a REST API + resource + method with a CUSTOM authorizer (REQUEST type,
--identity-source method.request.header.x-api-key) — provisioned via aws apigateway create-authorizer --type REQUEST ....
- Deploy and invoke the route.
- Inspect the event delivered to the authorizer Lambda.
Observed event:
{
"type": "REQUEST",
"methodArn": "arn:aws:execute-api:eu-west-3:000000000000:<apiId>/local/POST/api/v1/integration"
}
Expected (matches AWS production):
{
"type": "REQUEST",
"methodArn": "...",
"resource": "/api/v1/integration",
"path": "/api/v1/integration",
"httpMethod": "POST",
"headers": { "x-api-key": "...", "host": "...", ... },
"multiValueHeaders": { ... },
"pathParameters": null,
"queryStringParameters": null,
"multiValueQueryStringParameters": null,
"stageVariables": null,
"requestContext": {
"requestId": "...",
"identity": { "apiKey": "...", "apiKeyId": "...", "sourceIp": "...", "userAgent": "..." },
"path": "/api/v1/integration",
"accountId": "...",
"resourceId": "...",
"stage": "local",
"domainName": "...",
"resourcePath": "/api/v1/integration",
"httpMethod": "POST",
"apiId": "..."
}
}
Impact
- Authorizers cannot read the API key value or any header from the request.
- Authorizers cannot read
requestContext.requestId for logging/tracing/correlation.
api-key-required on the method is not enforced before the authorizer runs (AWS docs state that the key must be validated by API Gateway before invoking a REQUEST authorizer).
This is currently the only blocker preventing a drop-in replacement of LocalStack for a NestJS monorepo using a REQUEST authorizer + API key + AWS_PROXY integration to a Lambda validator. Everything else (SQS, S3, KMS, API Gateway routing, AWS_PROXY integration, Lambda lifecycle, usage plans) works correctly.
Source pointer
ApiGatewayExecuteController#toAuthorizerEvent only handles the TOKEN case:
private String toAuthorizerEvent(Authorizer auth, HttpHeaders headers, ...) {
ObjectNode node = objectMapper.createObjectNode();
node.put("type", auth.getType());
node.put("methodArn", buildMethodArn(...));
if ("TOKEN".equals(auth.getType())) {
String headerName = auth.getIdentitySource().replace("method.request.header.", "");
node.put("authorizationToken", headers.getHeaderString(headerName));
}
return node.toString();
}
A REQUEST branch should serialize at least headers, requestContext.requestId, and requestContext.identity (sourceIp, userAgent, apiKey if --api-key-required).
Environment
- Floci
floci/floci:latest (pulled May 2026)
- Standalone Docker Compose deployment (host: macOS Docker Desktop)
- AWS CLI v2
Happy to PR if you want — looks like a localized change to toAuthorizerEvent + reusing the proxy event builder for the shared parts.
Summary
When a REST API method uses a Lambda REQUEST authorizer (as opposed to TOKEN), the Lambda function receives an event containing only
typeandmethodArn. Real AWS sends the fullAPIGatewayRequestAuthorizerEventshape includingrequestContext,headers,multiValueHeaders,queryStringParameters,pathParameters,stageVariables, etc.Reproduction
--identity-source method.request.header.x-api-key) — provisioned viaaws apigateway create-authorizer --type REQUEST ....Observed event:
{ "type": "REQUEST", "methodArn": "arn:aws:execute-api:eu-west-3:000000000000:<apiId>/local/POST/api/v1/integration" }Expected (matches AWS production):
{ "type": "REQUEST", "methodArn": "...", "resource": "/api/v1/integration", "path": "/api/v1/integration", "httpMethod": "POST", "headers": { "x-api-key": "...", "host": "...", ... }, "multiValueHeaders": { ... }, "pathParameters": null, "queryStringParameters": null, "multiValueQueryStringParameters": null, "stageVariables": null, "requestContext": { "requestId": "...", "identity": { "apiKey": "...", "apiKeyId": "...", "sourceIp": "...", "userAgent": "..." }, "path": "/api/v1/integration", "accountId": "...", "resourceId": "...", "stage": "local", "domainName": "...", "resourcePath": "/api/v1/integration", "httpMethod": "POST", "apiId": "..." } }Impact
requestContext.requestIdfor logging/tracing/correlation.api-key-requiredon the method is not enforced before the authorizer runs (AWS docs state that the key must be validated by API Gateway before invoking a REQUEST authorizer).This is currently the only blocker preventing a drop-in replacement of LocalStack for a NestJS monorepo using a REQUEST authorizer + API key + AWS_PROXY integration to a Lambda validator. Everything else (SQS, S3, KMS, API Gateway routing, AWS_PROXY integration, Lambda lifecycle, usage plans) works correctly.
Source pointer
ApiGatewayExecuteController#toAuthorizerEventonly handles the TOKEN case:A REQUEST branch should serialize at least
headers,requestContext.requestId, andrequestContext.identity(sourceIp, userAgent, apiKey if--api-key-required).Environment
floci/floci:latest(pulled May 2026)Happy to PR if you want — looks like a localized change to
toAuthorizerEvent+ reusing the proxy event builder for the shared parts.