How to bypass authorization in internal lambda call - aws-lambda

I've implemented two lambda's (let's call A and B) behind api gateway. Assume A is called from "outside" and B is being called from outside and also from A.
I've also implemented lambda Authorizer (token-based; cognito) as auth layer. Everything is working as expected.
Is there a way to bypass authorizer process for B, for calls coming from A only?
Tnx

There are multiple possibilities I have explored myself in the past for the exact same issue.
Change the calls to lambda:Invoke
Assuming you're generating some client code for your micro-services, you can create two versions of these clients:
external to call your service via HTTP API
internal to use lambda:Invoke operation straight to your micro-service.
Create a mirrored VPC-private API
This is probably feasible if you're deploying your infrastructure using CDK (or a similar alternative). Essentially, you keep your existing API where it is, and you create another internal version of it that does not have the authorizer. (Note that you may still want some sort of authorization process happening depending on the nature of your project.)
From this point on, you can pass the endpoint of your internal HTTP API to the Lambdas as environment variables and have them call that.
You can find more info about this, here. As a perk you should probably get lower latencies when talking to API Gateway as traffic through the VPC endpoints will only flow through AWS network, instead of going out on the internet and back in.
Move your workloads to ECS
This is perhaps a major change to your project, but one worth mentioning.
You can create true micro-services using ECS. You can run these services in private subnets of your VPC. In order not to have to deal with IP addresses yourself, you can explore multiple options:
have a VPC-internal Route53 Hosted Zone (more on this here). See more on ECS Service Discovery here
create Network Load Balancers in the private subnets of your VPCs and pass their endpoints to your services.

Related

How can I make authorized requests to secured API endpoint from cronjobs?

I have a golang application which has API key authorization via the JWT token
I am using Kubernetes. So, this golang app is in a pod.
Now, I want to create another application for cronjobs to hit golang endpoint once a week.
What I need:
How to do / skip the authorization?
skip: Ingress is not required here as I can simply call it internally. Can that help this case?
What I Tried:
I tried keeping the cronjobs and api in the same application so I can simply call the service instead of the endpoint, But that also has a drawback.
I am not able to create replicas as they will also replicate the cronjobs and the same endpoint will be hit 1*no of replicas times
I want to call "abc.com" endpoint once a week. It requires a token and I cannot simply pass a token.
I hope there is some way around this.
If you just have to call them internally without exposing them, it can certainly help.
Provided both Pods (and therefore Deployments) are running under the same Cluster you can use Kubernetes' internal DNS.
K8s automatically creates DNS records for Services you create that can be used for internal communication by following this specific format: <service-name>.<service-namespace>.svc.cluster.local
More information from the official docs here: DNS for Services and Pods
If it sounds weird or if it can help understanding the gist of it, try to think of the "endpoint" as a rule you add to your system's hosts file: it boils down to basicly adding a rule where <service-name>.<service-namespace>.svc.cluster.local points to your pod's IP address, except it's done automatically
E.g.
Your golang app is running inside a Pod.
You created a Service pointing to it, named go-api and under the namespace go-apps.
If your cron-job worker is running in a Pod inside the same cluster, you can use go-api.go-apps.svc.cluster.local[:<port>] to reach your app without using an Ingress
The authorization is up to you, since you're usually handling it either directly or by using specific frameworks.
You could, for example, add a custom endpoint path inside your app where you make sure that the only accepted clients come from the same, private IP subnet of your cluster, either without a token (not recommended) or with a specific semi-fixed one that you generate and control, so that you would send a request to something like this from your crons: go-api.go-apps.svc.cluster.local:8080/api/v1/callWithNoAuth
I am creating a new answer as I feel I have more points to contribute to this.
So, what I eventually did end up doing is creating a middle-ware for internal API calls. Inside this middleware, I authorize the caller in middleware i.e. check whether it is from "xyz-service:port".
I found that the need to use a 3rd party authenticator was overkill and using a token in code was riskier.
Since all the services except for the ingress is ClusterIP, No one can access it from outside directly.
Thanks to #LeoD's answer. I gained confidence using this method.
P.S. Simply service-name:port can suffice
eg: http://myservice:4000/api

How does functions as a service ( FaaS) hosting work under the hood?

hypothesis
Suppose I want to roll out my own FaaS hosting, a service like Lambda, not on Lambda.
analogy
I have an abstract understanding of other cloud services as follows
1. Infrastructure as a service (IaaS): Create virtual machines for tenants on your hardware.
2. Platform as a service (PaaS): Create VM and run script that loads the required environment.
The above could also be achieved with docker images.
What about FaaS?
AWS uses firecracker VM for Lambda functions. But what's not clear is how the VMs are triggered on and off, how they're orchestrated on multiple pieces of hardware in a multi-tenant environment. Could someone explain how the complete life cycle works?
The main features of AWS Lambda and Cloud Function can be found in
https://cloud.google.com/docs/compare/aws/compute#faas_comparison
I can include the information of what I know, that is Google Cloud Functions.
Triggers
Cloud Functions can be triggered in two ways: HTTP request or Event-triggered. Events and Triggers. The events are things that happen into your project: A file is updated in Cloud Storage or Cloud Firestore. Other events are: a Compute Engine instance (VM) is initialized or the source code is updated in your repository.
All these events can be the trigger of a Cloud Function. This function, when triggered, is executed in a VM that will receive a HTTP request, and context information to perform its duty.
Auto-scaling and machine-type
If the volume that arrives to a Cloud Function increases, it auto-scales. That is that instead of having one VM executing one request at a time. You will have more than one VMs that server one request at a time. In any instance, only one request at a time will be analyzed.
If you want more information, you can check it on the official documentation.

East/West communication in a AWS serverless microservice architecture

I am well aware of the fact that east/west, or service to service synchronous communication between services is not the gold standard, and should only be used sparingly in a microservice architecture. However, in every real world implementation of a microservice architecture, I have seen some use-cases which require it. For example, the user service is often needs to be communicated with by other services to get up the millisecond details on the user (I'm aware that event based sharing of that data is also a possibility, but in some cases that isn't always the right approach).
My question is, what is the best way to do function to function, service to service communication in a Lambda + API Gateway style architecture?
My guess is that making an http request back out on the domain name is not ideal, since it will require going back out over the internet to resolve DNS.
Is it using the SDK to do an invoke on the downstream function directly? Will this cause issue if the downstream function depends on an API Gateway Proxy Event structure?

Global borderless implementation website/app on Serverless AWS

I am planning to use AWS to host a global website that have customers all around the world. We will have a website and app, and we will use serverless architecture. I will also consider multi-region DynamoDB to allow users closer to the region to access the closest database instance.
My question regarding the best design to implement a solution that is not locked down to one particular region, and we are a borderless implementation. I am also looking at high traffic and high number of users across different countries.
I am looking at this https://aws.amazon.com/getting-started/serverless-web-app/module-1/ but it requires me to choose a region. I almost need a router in front of this with multiple S3 buckets, but don't know how. For example, how do users access a copy of the landing page closest to their region?, how do mobile app users call up lambda functions in their region?
If you could point me to a posting or article or simply your response, I would be most grateful.
Note: would be interested if Google Cloud Platform is also an option?
thank you!
S3
Instead of setting up an S3 bucket per-region, you could set up a CloudFront distribution to serve the contents of a single bucket at all edge locations.
During the Create Distribution process, select the S3 bucket in the Origin Domain Name dropdown.
Caveat: when you update the bucket contents, you need to invalidate the CloudFront cache so that the updated contents get distributed. This isn't such a big deal.
API Gateway
Setting up an API Gateway gives you the choice of Edge-Optimized or Regional.
In the Edge-Optimized case, AWS automatically serves your API via the edge network, but requests are all routed back to your original API Gateway instance in its home region. This is the easy option.
In the Regional case, you would need to deploy multiple instances of your API, one per region. From there, you could do a latency-based routing setup in Route 53. This is the harder option, but more flexible.
Refer to this SO answer for more detail
Note: you can always start developing in an Edge-Optimized configuration, and then later on redeploy to a Regional configuration.
DynamoDB / Lambda
DynamoDB and Lambda are regional services, but you could deploy instances to multiple regions.
In the case of DynamoDB, you could set up cross-region replication using stream functions.
Though I have never implemented it, AWS provides documentation on how to set up replication
Note: Like with Edge-Optimized API Gateway, you can start developing DynamoDB tables and Lambda functions in a single region and then later scale out to a multi-regional deployment.
Update
As noted in the comments, DynamoDB has a feature called Global Tables, which handles the cross-regional replication for you. Appears to be fairly simple -- create a table, and then manage its cross-region replication from the Global Tables tab (from that tab, enable streams, and then add additional regions).
For more info, here are the AWS Docs
At the time of writing, this feature is only supported in the following regions: US West (Oregon), US East (Ohio), US East (N. Virginia), EU (Frankfurt), EU West (Ireland). I imagine when enough customers request this feature in other regions it would become available.
Also noted, you can run Lambda#Edge functions to respond to CloudFront events.
The lambda function can inspect the AWS_REGION environment variable at runtime and then invoke (and forward the request details) a region-appropriate service (e.g. API Gateway). This means you could also use Lambda#Edge as an API Gateway replacement by inspecting the query string yourself (YMMV).

Does Serverless Framework support any kind of multi-cloud load balancing?

Does Serverless Framework support the ability to deploy the same API to multiple cloud providers (AWS, Azure and IBM) and route requests to each provider based on traditional load balancer methods (i.e. round robin or latency)?
Does Serverless Framework support this function directly?
Does Serverless integrate with global load balancers (e.g. dyn or neustar)?
Does Serverless Framework support the ability to deploy the same API to multiple cloud providers (AWS, Azure and IBM)
Just use 3 different serverless.yml files and deploy each function 3 times.
and route requests to each provider based on traditional load balancer methods (i.e. round robin or latency)?
No, there is no such support for multi-cloud load balancing
The Serverless concept is based on trust: you trust that your Cloud provider will be able to handle your traffic with proper scalability and availability. There is no multi-cloud model, a single Cloud provider must be able to satisfy your needs. To achieve this, they must implement a proper load-balacing schema internally.
If you don't trust on your Cloud provider, you are not thinking in a serverless way. Serverless means that you should not worry about the infra the supports your app.
However, you can implement a sort of multi-cloud load balancing
When you specify a serverless.yml file, you must say which provider (AWS, Azure, IBM) will create those resources. Multi-cloud means that you need one serverless.yml file per each Cloud, but the source code (functions) can be the same. When you deploy the same function to 3 different providers, you will receive 3 different endpoints to access them.
Now, which machine will execute the Load Balance? If you don't trust that a single Cloud provides enough availability, how will you define who will serve the Load Balance feature?
The only solution that I see is to implement this load-balacing in your frontend code. Your app would know the 3 different endpoints and randomize the requests. If one request returns an error, the endpoint would be marked as unhealthy. You could also determine the latency for each endpoint and select a preferred provider. All of this in the client code.
However, don't follow this path. Choose just one provider for production code. The SLA (service level agreement) usually provides a high availability. If it's not enough, you should still stick with just one provider and have in hand some scripts to easily migrate to another cloud in case of a mass outage of your preferred provider.

Resources