This plugin will sign a request with AWS SIGV4 and temporary credentials from sts.amazonaws.com
requested using an OAuth token.
The AWS SIGV4 signature enables secure proxying directly towards AWS services such as Lambda URLs.
At the same time it drives down cost and complexity by excluding the AWS API Gateway and allowing to use AWS Lambdas directly.
The required AWS setup to make the plugin work with your Lambda HTTPS endpoint is described below.
Note that this plugin cannot be used in combination with Kong upstreams.
aws_assume_role_arn - ARN of the IAM role that the plugin will try to assume
type = "string"
required = true
aws_assume_role_name - Name of the role above.
type = "string"
required = true
aws_region - AWS region where your Lambda is deployed to
type = "string"
required = true
aws_service - AWS Service you are trying to access (lambda and s3 were tested)
type = "string"
required = true
override_target_host - To be used when deploying multiple lambdas on a single Kong service (because lambdas have different URLs)
type = "string"
required = false
override_target_port - To be used when deploying a Lambda on a Kong service that listens on a port other than `443`
type = "number"
required = false
override_target_protocol - To be used when deploying a Lambda on a Kong service that has a protocol different than `https`
type = "string"
one_of = "http", "https"
required = false
return_aws_sts_error - Whether to return the AWS STS response status and body when credentials fetching failed.
type = "boolean"
default = false
required = false
sign_query - Controls if the signature will be sent in the header or in the query. By default, header is used, if enabled will sign the query.
type = "boolean"
required = true
default = false
preserve_auth_header - Controls if the bearer token will be passed to the upstream
type = "boolean"
required = true
default = true
preserve_auth_header_key - The header key where the bearer token will be saved and passed to the upstream. works only if 'preserve_auth_header' parameter above is set to true.
type = "string"
required = true
default = "x-authorization"
The plugin can be enabled on a per-service and per-route basis. When enabled for a route, the plugin will direct traffic to the service's upstream Lambda target, unless override_target_host
is specified.
If multiple Lambdas are needed for a single service, each route must have the plugin enabled with override_target_host
configured, so that requests are correctly routed to the right Lambda.
If override_target_host
is not specified and multiple Lambdas are used in the service, all routes will be served by the same service-level host.
You can also set the service protocol and host to something like http://example.com
and then use override_target_protocol
and override_target_host
to changed it on the path level.
There are two things necessary to make a custom plugin work in Kong:
- Load the plugin files.
The easiest way to install the plugin is using luarocks
.
luarocks install https://github.com/LEGO/kong-aws-request-signing/raw/main/rocks/kong-aws-request-signing-1.0.5-3.all.rock
You can substitute 1.0.0-3
in the command above with any other version you want to install.
If running Kong using the Helm chart, you will need to create a config map with the plugin files and mount it to /opt/kong/plugins/aws-request-signing
. You can read more about this on Kong's website.
- Specify that you want to use the plugin by modifying the plugins property in the Kong configuration.
Add the custom plugin’s name to the list of plugins in your Kong configuration:
plugins = bundled, aws-request-signing
If you are using the Kong helm chart, create a configMap with the plugin files and add it to your values.yaml
file:
# values.yaml
plugins:
configMaps:
- name: kong-plugin-aws-request-signing
pluginName: aws-request-signing
In case of requests containing a body, the plugin is highly reliant on the nginx configuration, because it needs to access the body to sign it. The behavior is controlled by the following Kong configuration parameters:
nginx_http_client_max_body_size
nginx_http_client_body_buffer_size
The default value for max body size is 0
, which means unlimited, so consider setting the nginx_http_client_body_buffer_size
as high as you consider reasonable, as requests containing a bigger body, will fail.
- You have a Lambda function deployed with
Function URL
enabled and Auth type :AWS_IAM
or you have an S3 bucket with public access disabled.
- Your OpenID Connect provider is added to AWS IAM
- You have a role with
arn:aws:iam::aws:policy/AWSLambda_FullAccess
and/orarn:aws:iam::aws:policy/AmazonS3FullAccess
permission (or any other permission that grants access to your desired AWS service ) and the trust relationship below:
Show JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "${arn_of_the_open_id_connect_provider_step_1}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${the_open_id_connect_provider_step_1}:aud": "${audience_of_the_lambda_given_by_your_open_id_provider}"
}
}
}
]
}
So if your provider is https://sts.windows.net/organization.onmicrosoft.com/
and your app identity is app_identity_1
, the trust relationship above will look like:
Show JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::300000000000:oidc-provider/sts.windows.net/organization.onmicrosoft.com/"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"sts.windows.net/organization.onmicrosoft.com/:aud": "app_identity_1"
}
}
}
]
}
About the code and differences from Kong Lambda Plugin
Some of the code was reused from Kong Lambda Plugin specifically the SIGV4 creation code and some parts for getting the temporary credentials from AWS STS. There are some considerable differences that will be outlined below:
- Unlike Kong-Lambda This plugin does not perform the Lambda invocation. But only signs the request coming from the consumer which Kong then forwards to the upstream that it is configured in the service that the plugin is bound to.
- The plugin works only with temporary credentials that are fetched from
sts.amazonaws.com
using AssumeRoleWithWebIdentity, this requires some configuration in AWS which can be found above. - This plugin has a low priority and is compatible with the rest of Kong plugins because as mentioned above, it only performs SIGV4 on the request and then appends the necessary headers to be authorized in AWS.