What is the best way to restrict access to an Application Load Balancer? - aws-api-gateway

Ideally, I'd like to lock down my ALB so that it can only be accessed by API Gateway.
I've looked into whether I can associate API gateway with an Inbound Rule - however, I have found that API Gateway cannot be associated with an IP address, or a security group. I've also looked into an Internal facing ALB, but I've been unable to get these working as VPC link only supports NLB.
Any help will be greatly appreciated - I've been looking in the Gateway Settings but cannot find this option.
What is the best way to approach this so that the ALB is as restricted as possible?

Use WAF to verify the custom HTTP Header value set at API GW
Inject a custom HTTP header at the Integration Request of a API GW HTTP Integration method. Use the static value as explained in Amazon API Gateway API request and response data mapping reference.
'STATIC_VALUE'. The STATIC_VALUE is a string literal and must be enclosed within a pair of single quotes.
As in the case with AWS documentations, it is confusing if we should use the "integration.request.header." format. If setting up in the AWS console, no need to type "integration.request.header." Just type the header name only. Make sure the header value is single quoted
However, when using a tool like CDK or CFN, then we need to use the "integration.request.header." part.
cdk_api_method: aws_apigateway.Method = cdk_api_resource.add_method(
http_method="post",
integration=aws_apigateway.HttpIntegration(
url=url,
http_method="post",
proxy=True,
options=aws_apigateway.IntegrationOptions(
request_parameters={
"integration.request.header.{}".format(HTTP_HEADER_X_VALIDATION_CLIENT_NAME): "'{}'".format(HTTP_HEADER_X_VALIDATION_CLIENT_VALUE)
}
)
)
)
Setup up WAF to verify the HTTP header value and associate the ALB to WAF ACL.
# https://github.com/aws-samples/wafv2-json-yaml-samples/blob/master/JSON/rule-001.json
aws_wafv2.CfnWebACL.RuleProperty(
name='header-x-validation-client',
action=aws_wafv2.CfnWebACL.RuleActionProperty(
allow={}
),
statement=aws_wafv2.CfnWebACL.StatementOneProperty(
byte_match_statement=aws_wafv2.CfnWebACL.ByteMatchStatementProperty(
field_to_match=aws_wafv2.CfnWebACL.FieldToMatchProperty(
single_header={
"Name": HTTP_HEADER_X_VALIDATION_CLIENT_NAME
}
),
positional_constraint="EXACTLY",
search_string=HTTP_HEADER_X_VALIDATION_CLIENT_VALUE,
text_transformations=[
aws_wafv2.CfnWebACL.TextTransformationProperty(
priority=0,
type="NONE"
)
]
)
),
visibility_config=aws_wafv2.CfnWebACL.VisibilityConfigProperty(
sampled_requests_enabled=True,
cloud_watch_metrics_enabled=True,
metric_name='waf-rule-header-x-validation-client'
),
priority=0
)

The API Gateway doesn't have a static IP and ALBs don't offer any authentication other than Cognito User Pools at this moment. Because of that I would say your best option is to use a VPC link with Network Load Balancer as you propose and tunnel the request via the NLB to your ALB.
Alternatively you could have a Lambda inside your VPC invoke the ALB but that would be a lot slower, but cheaper for low volumes because you skip the NLB.

Depending on the use case, one possibility is secure your backend instead of the ALB using client SSL certificates.
Generate and Configure an SSL Certificate for Backend Authentication

Related

serverless framework: configuring a pre-existing lambda authenticator for HTTP API Gateway routes in serverless.yml

I would like to add a preexisting lambda authenticator to the routes of a preexisting http api gateway using the serverless framework. I have followed the docs, whereby I have specified the authorizer details under provider.httpApi (lines 15 to 18), and I have referenced the authorizer on the route(s) below (line 27 & 28). Though I get the error message:
Cannot setup authorizers for externally configured HTTP API
What am I doing wrong here? It must be for a HTTP API gateway and not a REST API gateway as thats what the current infra is configured as. Thanks
It looks like you're using an externally configured HTTP API (I'm guessing from the id being set). In such a situation, you cannot configure authorizers in this manner, you can only do so when you're provisioning HTTP API as a part of your serverless service. What you can do there, is to setup a shared authorizer in a more manual way as described in docs here: https://www.serverless.com/framework/docs/providers/aws/events/http-api#shared-authorizer
I came across this post when researching how to use API gateway authorizers and serverless framework. I was terraforming the API gateway therefore needed to terraform the authorizer as well. When created, I stashed the authorizer ID in a parameter store entry. This is a 6 character alphanumeric value such as tw9qgj. I then referenced the parameter as follows:
custom:
authorizerId: ${ssm:api_gateway_authoriser}
Then added the following block to each API e.g.
- httpApi:
path: /protected
method: get
authorizer:
id: ${self:custom.authorizerId}

Public path for API Gateway configured to use Cognito Authorizer

I have a Lambda being exposed to the world through API Gateway. The default authorizer is configured as a Cognito user pool and everything works fine.
I need to be able to expose just one of the endpoints without requiring the client to provide an authorization.
I'm using AWS SAM for defining the API and I couldn't find a way to specify an exception for the default authorizer.
How could this be done?
As it turns out it is in fact possible to disable the authorizer for one of the endpoints.
Simply set:
Properties:
Auth:
Authorizer: NONE
More information here: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-api-apiauth.html

Metaflow: "Missing authentication token" when accessing the metadata/metaflow service URL in the browser

I’m currently experimenting on Metaflow. I followed the documentation and was able to deploy an aws setup with the given cloud formation template.
My question is why is that I’m always getting a:
message: "Missing Authentication Token"
when I access METAFLOW_SERVICE_URL in the browser, even if I made sure that the APIBasicAuth was set to false during the creation of cloudformation?
Shouldn’t this setting make the metadata/metaflow service accessible without the authentication/api key?
How can I resolve this? Or is this expected? That is, I cannot really view the metadata/metaflow service url via browser?
Thanks in advance
This was resolved under this github issue.
You still need to set the x-api-key header if you are trying to access the service url via the browser. To get the api-key you can go to the aws console
Api Gateway -> Api Keys -> show api key
Alternatively you can use the metaflow client in the sagemaker notebook which should be automatically setup for you via the template.
Also worth mentioning that there are two sets of endpoints: The one provided by the api gateway (which you seem to be hitting) and the one provided by the service itself. The api gateway forwards the requests the the service endpoints but needs the x-api-key to be set in the header. You can probably try hitting the service endpoints directly since you disabled auth.

Is it possible to configure AppId in Kubernetes Ingress with both types web and api at the same time?

So that a browser would show the login page if no authentication is provided, but the backend would accept calls with a valid bearer token header as well.
Is that possible? If so, how?
We have several kubernetes services in the same namespace behind an ingress and annotated the ingress with
ingress.bluemix.net/appid-auth: "bindSecret=binding-appidname namespace=somenamespace requestType=api serviceName=service-a"
requestType=web will work too, but requestType=api,web does not work, neither does adding the annotation twice with the respective request types.
The AppId Documentation (https://console.bluemix.net/docs/services/appid/tutorial-kubernetes-auth.html) states in the descriptino of "serviceName": To use multiple request types in the same cluster, configure an instance of App ID to use web and another to use api., so I got the impression it should be possible to use both at the same time.
You can protect multiple services with different requestTypes in the same namespace using Ingress annotation. The syntax is:
ingress.bluemix.net/appid-auth: "bindSecret=binding-appid-01 requestType=web serviceName=service1;bindSecret=binding-appid-01 requestType=api serviceName=service2;bindSecret=binding-appid-02 requestType=web serviceName=service3;"

Kong + JWT Excluding endpoints from authorization

I am using Kong and the JWT plugin to authenticate my upstream services. I have a use case where i would like to expose an endpoint in one of the services without having Kong authenticate against it. I was wondering if there is any way to specify exclusion patterns to let Kong know to ignore authentication for this endpoint?
Thanks in advance for any help!
Kong looks at the configured APIs in order of length. So it should be possible (without have tested it) that you use a longer uri (the one you want to make publicly accessible) without the JWT plugin, while keeping your current endpoint with the JWT plugin.
For example, if your current configuration is on /myApi and the path you want to make public is /myApi/login, then add an API on the latter without configuring the JWT on it.