aws-lambda
The aws-lambda plugin forwards requests to AWS Lambda function URLs and Amazon API Gateway endpoints. It can sign requests with AWS Signature Version 4 (SigV4) using IAM access keys or add an API Gateway API key to the request.
API Gateway API keys identify callers for usage plans and quotas; AWS does not recommend using them for authentication or authorization. Use IAM authorization, an AWS Lambda function that authorizes requests, or an Amazon Cognito user pool when the API requires access control.
Upstream responses with HTTP status 400 or higher are recorded at warning level in API7 Enterprise 3.9.20 and 3.10.7 and in APISIX 3.19.0. The gateway error log includes the response body, so review log access and retention if the AWS endpoint returns sensitive error details.
Examples
The examples show how to invoke an IAM-protected Lambda function URL, forward an API Gateway API key, and preserve sub-paths when proxying to API Gateway.
Create a Lambda function that returns Hello from Lambda! before starting.
Invoke a Lambda Function URL with IAM Authorization
The following example signs gateway requests with SigV4 before forwarding them to a Lambda function URL that uses the AWS_IAM authorization type.
Open the Lambda function, select Configuration → Function URL, and create a function URL with Auth type set to AWS_IAM. Record the function URL, function ARN, and AWS Region.
The IAM principal whose access keys are configured in the plugin requires both lambda:InvokeFunctionUrl and lambda:InvokeFunction. For a same-account IAM user, attach an identity policy that grants both actions for the function ARN. The following policy also limits lambda:InvokeFunction to requests made through the function URL:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "InvokeFunctionUrl",
"Effect": "Allow",
"Action": "lambda:InvokeFunctionUrl",
"Resource": "arn:aws:lambda:us-west-2:123456789012:function:apisix-docs-function",
"Condition": {
"StringEquals": {
"lambda:FunctionUrlAuthType": "AWS_IAM"
}
}
},
{
"Sid": "InvokeFunctionThroughUrl",
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-west-2:123456789012:function:apisix-docs-function",
"Condition": {
"Bool": {
"lambda:InvokedViaFunctionUrl": "true"
}
}
}
]
}
Replace the example ARN with the ARN of your function. Cross-account invocation also requires equivalent permissions in the function's resource-based policy.
The plugin accepts an access key ID and secret access key but does not accept a session token. Create a dedicated, least-privilege IAM user for the integration, rotate its access key regularly, and do not use root-user credentials.
In IAM, open the dedicated user, select the Security credentials tab, and select Create access key. Select Application running outside AWS as the use case.
Complete the credential creation and copy the access key ID and secret access key. AWS displays the secret access key only once.
The gateway can add X-Forwarded-Host, X-Forwarded-Port, and X-Forwarded-Proto to incoming requests. Remove these headers before aws-lambda signs the request; otherwise, AWS can reject the signature.
Create a route with the function URL and IAM credentials:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "aws-lambda-route",
"uri": "/aws-lambda",
"plugins": {
"proxy-rewrite": {
"headers": {
"remove": [
"X-Forwarded-Host",
"X-Forwarded-Port",
"X-Forwarded-Proto"
]
}
},
"aws-lambda": {
"function_uri": "https://your-lambda-function-url.lambda-url.us-west-2.on.aws/",
"authorization": {
"iam": {
"accesskey": "YOUR_IAM_ACCESS_KEY",
"secretkey": "YOUR_IAM_SECRET_KEY",
"aws_region": "us-west-2",
"service": "lambda"
}
}
}
}
}'
services:
- name: aws-lambda-service
labels:
docs-example: aws-lambda
routes:
- name: aws-lambda-route
uris:
- /aws-lambda
plugins:
proxy-rewrite:
headers:
remove:
- X-Forwarded-Host
- X-Forwarded-Port
- X-Forwarded-Proto
aws-lambda:
function_uri: https://your-lambda-function-url.lambda-url.us-west-2.on.aws/
authorization:
iam:
accesskey: YOUR_IAM_ACCESS_KEY
secretkey: YOUR_IAM_SECRET_KEY
aws_region: us-west-2
service: lambda
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Preview changes owned by this example and confirm that the diff contains no unintended updates or deletions:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=aws-lambda
Synchronize the reviewed service configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=aws-lambda
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
name: httpbin-external-domain
namespace: aic
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
protocol: TCP
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: aws-lambda-plugin-config
spec:
plugins:
- name: proxy-rewrite
config:
headers:
remove:
- X-Forwarded-Host
- X-Forwarded-Port
- X-Forwarded-Proto
- name: aws-lambda
config:
function_uri: https://your-lambda-function-url.lambda-url.us-west-2.on.aws/
authorization:
iam:
accesskey: YOUR_IAM_ACCESS_KEY
secretkey: YOUR_IAM_SECRET_KEY
aws_region: us-west-2
service: lambda
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: aws-lambda-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /aws-lambda
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: aws-lambda-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: aws-lambda-route
spec:
ingressClassName: apisix
http:
- name: aws-lambda-route
match:
paths:
- /aws-lambda
plugins:
- name: proxy-rewrite
enable: true
config:
headers:
remove:
- X-Forwarded-Host
- X-Forwarded-Port
- X-Forwarded-Proto
- name: aws-lambda
enable: true
config:
function_uri: https://your-lambda-function-url.lambda-url.us-west-2.on.aws/
authorization:
iam:
accesskey: YOUR_IAM_ACCESS_KEY
secretkey: YOUR_IAM_SECRET_KEY
aws_region: us-west-2
service: lambda
Apply the configuration:
kubectl apply -f aws-lambda-ic.yaml
❶ replace with your Lambda function URL
❷ replace with your IAM access key
❸ replace with your IAM secret access key
❹ replace with the AWS region of your Lambda function
❺ set to lambda when integrating with Lambda function
The ADC and Gateway API configurations include a conventional fallback backend. When aws-lambda handles the request, the gateway does not contact that backend; verify the Lambda response rather than treating a backend response as confirmation that the plugin ran.
Send a request to the route:
curl -i "http://127.0.0.1:9080/aws-lambda"
You should receive an HTTP/1.1 200 OK response with the following message:
"Hello from Lambda!"
Send an API Gateway API Key
The following example forwards an API key in the X-API-Key header to an API Gateway REST API that invokes the Lambda function. API Gateway uses the key to identify the caller and apply a usage plan; the key is not an authentication or authorization mechanism.
Open the Lambda function and select Add trigger:
Select API Gateway as the trigger and REST API as the API type. API keys are supported for REST APIs, not HTTP APIs. Complete the trigger configuration:

In the API Gateway console, configure the method to require an API key and deploy the API to a stage. Create a usage plan, associate the deployed stage with the plan, and create or attach an API key to the plan. Record the API key value and invoke URL.
Create a route with the API Gateway invoke URL and API key:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "aws-lambda-route",
"uri": "/aws-lambda",
"plugins": {
"aws-lambda": {
"function_uri": "https://your-api-id.execute-api.us-west-2.amazonaws.com/default/your-resource",
"authorization": {
"apikey": "YOUR_API_GATEWAY_API_KEY"
}
}
}
}'
services:
- name: aws-lambda-service
labels:
docs-example: aws-lambda
routes:
- name: aws-lambda-route
uris:
- /aws-lambda
plugins:
aws-lambda:
function_uri: https://your-api-id.execute-api.us-west-2.amazonaws.com/default/your-resource
authorization:
apikey: YOUR_API_GATEWAY_API_KEY
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Preview changes owned by this example and confirm that the diff contains no unintended updates or deletions:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=aws-lambda
Synchronize the reviewed service configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=aws-lambda
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
name: httpbin-external-domain
namespace: aic
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
protocol: TCP
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: aws-lambda-plugin-config
spec:
plugins:
- name: aws-lambda
config:
function_uri: https://your-api-id.execute-api.us-west-2.amazonaws.com/default/your-resource
authorization:
apikey: YOUR_API_GATEWAY_API_KEY
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: aws-lambda-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /aws-lambda
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: aws-lambda-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: aws-lambda-route
spec:
ingressClassName: apisix
http:
- name: aws-lambda-route
match:
paths:
- /aws-lambda
plugins:
- name: aws-lambda
enable: true
config:
function_uri: https://your-api-id.execute-api.us-west-2.amazonaws.com/default/your-resource
authorization:
apikey: YOUR_API_GATEWAY_API_KEY
Apply the configuration:
kubectl apply -f aws-lambda-ic.yaml
Send a request to the route:
curl -i "http://127.0.0.1:9080/aws-lambda"
You should receive an HTTP/1.1 200 OK response with the following message:
"Hello from Lambda!"
If your API key is invalid, you should receive an HTTP/1.1 403 Forbidden response.
Forward Requests to Amazon API Gateway Sub-Paths
The following example forwards the path suffix matched by the gateway route to a resource under the API Gateway stage. It continues with the REST API, usage plan, and API key from the previous example.
Complete Send an API Gateway API Key before continuing.
Open the Lambda function, select Configuration → Triggers, and open the API Gateway trigger:
Select Create resource to create a sub-path:

Enter the resource details and create the resource:

Select the new resource, then select Create method:

Select the HTTP method and the same Lambda function used by the preceding example. After creating the method, open Method request, select Edit, enable API key required, and save the change.
Select Deploy API to deploy the resource and method changes to the stage associated with the usage plan:
Create a route with the API Gateway stage URL and API key:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "aws-lambda-route",
"uri": "/aws-lambda/*",
"plugins": {
"aws-lambda": {
"function_uri": "https://your-api-id.execute-api.us-west-2.amazonaws.com/default",
"authorization": {
"apikey": "YOUR_API_GATEWAY_API_KEY"
}
}
}
}'
services:
- name: aws-lambda-service
labels:
docs-example: aws-lambda
routes:
- name: aws-lambda-route
uris:
- /aws-lambda/*
plugins:
aws-lambda:
function_uri: https://your-api-id.execute-api.us-west-2.amazonaws.com/default
authorization:
apikey: YOUR_API_GATEWAY_API_KEY
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
Preview changes owned by this example and confirm that the diff contains no unintended updates or deletions:
adc diff -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=aws-lambda
Synchronize the reviewed service configuration:
adc sync -f adc.yaml \
--include-resource-type service \
--label-selector docs-example=aws-lambda
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
name: httpbin-external-domain
namespace: aic
spec:
type: ExternalName
externalName: httpbin.org
ports:
- name: http
port: 80
protocol: TCP
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: aws-lambda-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: PathPrefix
value: /aws-lambda/
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: aws-lambda-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: aws-lambda-plugin-config
spec:
plugins:
- name: aws-lambda
config:
function_uri: https://your-api-id.execute-api.us-west-2.amazonaws.com/default
authorization:
apikey: YOUR_API_GATEWAY_API_KEY
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: aws-lambda-route
spec:
ingressClassName: apisix
http:
- name: aws-lambda-route
match:
paths:
- /aws-lambda/*
plugins:
- name: aws-lambda
enable: true
config:
function_uri: https://your-api-id.execute-api.us-west-2.amazonaws.com/default
authorization:
apikey: YOUR_API_GATEWAY_API_KEY
Apply the configuration:
kubectl apply -f aws-lambda-ic.yaml
❶ match all sub-paths of /aws-lambda/
❷ For Admin API, ADC, and APISIX CRD examples, the sub-paths matched by the wildcard * will be appended to the end of the function_uri. In the Gateway API example, PathPrefix matches requests under /aws-lambda/, so the forwarded request path continues after the configured function_uri prefix.
Send a request to the route:
curl -i "http://127.0.0.1:9080/aws-lambda/api7-docs"
The gateway forwards the request to https://your-api-id.execute-api.us-west-2.amazonaws.com/default/api7-docs. You should receive an HTTP/1.1 200 OK response with the following message:
"Hello from Lambda!"
If your API key is invalid or if the requested path is not associated with any method, you should receive an HTTP/1.1 403 Forbidden response.