AmazonWebService - Should i use AWS API Gateway or AWS SDK - node.js

I'm trying to call a lambda function from NodeJS. After research i know 2 ways to do it:
Assign Lambda function into AWS API Gateway and call that API.
Call Lambda function through AWS SDK
What are pros and cons of API Gateway and AWS SDK ? And when to use each way above?

It depends. API Gateway is mostly used to give temporary access to Lambda functions in environments that are not secure (i.e. browsers, desktop apps, NOT servers).
If your environment is secure, as in it runs on an EC2 instance with an IAM role, or another server with secure stored credentials, then feel free to use the SDK and call the Lambda function correctly.
If you need to expose your Lambda function to the entire internet, or to authorised users on the web, or to any user that has the potential to grab the access key and secret during transit, then you will want to stick API Gateway in front.
With API Gateway you can secure your Lambda functions with API keys, or through other authorisers such as Amazon Cognito so that users need to sign in before they can use the API endpoint. This way they only gain temporary credentials, rather than permanent ones that shouldn't be available to anyone.

I disagree with _DF about the security concern on invoking lambda directly through client. Over the 4 years I implementing Client + AWS SDK on my serverless approach. Direct hit to all microservices we have such as Lambda, DynamoDB, S3, SQS, etc.
To work with this approach, we have to strong understand about IAM Role Policy including its statements concept, Authentication Token, AWS Credential, and Token - Credential exchange.
For me, using SDK is better to implement serverless rather than API Gateway. Why I prefer to implementing SDK instead of API on my serverless infra?
API Gateway is Costly
Network hop-less
In fact, SDK is commonly contain an API to communicate with other applications Class base and simple call such as dynamodb.put(params).promise(), lambda.invoke(params).promise(), s3.putObject(params).promise(), etc. We can see a sample API call like fetch(URL).promise(), the term is not really different
API is more complex and some case can't or shouldn't be handled with
SDK is not scalable? No, I dont think so. Because it's class base, it's so scalable.
Slimming the infra and code writing, i.e to work with s3 no need deploy API+Lambda
Speed up the process, i.e storing data to dynamodb no need business logic through API+lambda
Easy maintaining, we only maintain our client code
Role Policy is more scalable; etc

Related

How to handle a Custom Connector that uses header authentication in each API call?

I have an Azure logic app that uses a Custom Connector that I've made from importing a Postman Collection. The RESTful API that my connector calls require 3 authentication headers in each request: UserName, Secret, ApiIntegrationCode. Because it takes three specifically named parameters, I don't believe that any of the authentication presets will work for me.
I know that I can protect the inputs and outputs of various connectors. I have been entertaining the idea of storing the sensitive information in a SQL table that I query in each run and storing the values in variables that I pass to each of my custom connector's API calls.
Would this be a viable way of protecting sensitive data from being seen by people that may have access to my logic app? What is the most secure way I can pass these headers in each call?
There are not too many options within a (consumption) Logic App in this regard.
Your options with Logic Apps
A first step into the right direction is to put your sensitive information into an Azure Key Vault and use the corresponding connector in your Logic App to retrieve the data from there. This is easier to implement and more secure than querying a SQL table for this purpose.
The second thing you can do is to activate secure inputs for the connectors that make the API calls. This makes sure, that the sensitive information passed to these connectors is obfuscated in the run history of your logic App and in connected services like Azure Log Analytics.
The problem with this approach is, that anyone who has more than just read permissions to your Logic App can just go ahead and deactivate the secure inputs setting or create a step that dumps the content of your Key Vault. You can use RBAC to control access to your Logic App but that means of course administrative overhead.
Alternative: API Management Service
If you want by all means to allow other developers to change the Logic App without exposing API secrets to them, you might consider using some sort of middle tier to communicate with the API. Azure API Management Service (APIM) is one of the options here.
You would manage your sensitive information in a Key Vault and inject them via "Named Values" into your APIM instance. You can then add your API as a backend in APIM and expose it towards your Logic App.
The advantage here is that you can secure access to your API with APIM subscription keys that you can cycle frequently. You can also restrict the access to the original API to only those calls, that need to be available to the Logic App.
If APIM is something for you depends on your use case, as it comes at a price. Even the developer plan costs about $50/month: https://azure.microsoft.com/en-us/pricing/details/api-management/
Alternative: Azure Function
You can use a simple Azure Function that serves as a middle tier between your Logic App and your API. This function can be configured to pull the sensitive data from a Key Vault and can also be secured via a function access key, that you can renew on a regular basis.
This is a dirt cheap option, if you are running the functions on a consumption plan: https://azure.microsoft.com/en-us/pricing/details/functions/

Azure SignalR Serverless and dotnet core API application

We are attempting to get Azure SignalR serverless to with a dotnet core API application. With "default" SignalR, we ran into scaling issues in Azure as server instances behind an API App would continue to receive socket connections even as its CPU increases. There is no way to currently to change load balancing behavior or to take an instance out of traffic. As such, we've looked to use "serverless", however, all documentation points to using Azure Functions. However, given that serverless uses webhooks and such, we should be able to use anything that can take an HTTP request. We already have our APIs setup so getting this to work against out APIs is preferred.
Update 1
Effectively, we're looking for support for serverless that Functions get but for APIs. Functions have triggers and Serverless Hubs to inherit from, etc etc. These things handle negotiate calls and deserialization of negotiation data and all the other things SigR has to do. We're looking for something similar for, I guess, API controllers.
Thanks!

Azure - Cosmos DB integration with API Apps

Is there any integration between CosmosDB and Api Apps? I'm kinda new in Azure and I don't really understand which is the best approach.
My problem is that I am working on an IoT Project which gets data from the IoT Hub, passes it to a Function that sends it to the CosmosDB which then would need to be consumed by a Frontend. A pretty standard case.
I would usually create a backend to place between the database and the frontend but I really can't understand which is the best way to do it in Azure. Should I use the Api Apps or the integrated SQL Apis that are provided with CosmosDB? Are the Api Apps comparable to "containers" for my backend or do they have any other use other than keeping my code in a cloud machine?
Thanks a lot in advance!
You can't (well, shouldn't) have your frontend to directly call the database so you need a middle layer of some sort.
Creating an API could be one of the ways you go about it but based on your use-case, I would go with an HTTP Trigger Azure Function which would be the API that exposes the data.
You can then use the Cosmos DB Input Binding to retrieve the object you want to return and simply return the JSON of it.

What are the best practices to securely store/access SaaS customer data on Amazon S3?

To all those SaaS engineers/developers out there ...
I am building a SaaS product which will store customer data on S3. I wonder what is the best approach regarding security?
Have a single IAM user with a bucket policy. That would be simple but data security is handled purely by the SaaS app. In case of a glitch, other users could have access to restricted material.
What about creating an IAM user (via IAM REST API) for each new customer account and having object specific ACL for each stored object? More complex but it adds a layer of security in S3 as well.
Any other way?
Also, to provide access to the material via the SaaS app. I plan to have each object 'readable name' replaced with a guid so that it cannot be easily guessed and use pre-signed urls with a time limit to see and download them. Is that a best practice? What time limit is considered safe and user-friendly?
Thanks
You should never generate AWS IAM Users for "end-users" of your application (option 2). IAM grants permission to call AWS APIs and the end-users of your application should never need to call an API.
Information stored in Amazon S3 should be available to your SaaS application via standard methods:
Create an IAM Role for your application
Select the IAM Role when launching Amazon EC2 instances that run your application
Any code running on the Amazon EC2 instances that uses the AWS SDK will know how to automatically access credentials via the EC2 instance metadata service
If you wish to serve content from Amazon S3 directly to users of the application, generate Amazon S3 pre-signed URLs, that provide time-limited access to objects stored in S3 buckets. A 15-minute expiry duration could be a good trade-off between security and users who pause to take a phone call, but that timing is up to you.
Your S3 bucket should not have a bucket policy because all access will be via permissions granted to the IAM Role, or via pre-signed URLs.
The use of randomized GUIDs as filenames is irrelevant because you will have proper security rather than obfuscation.
Recently AWS created a blog post about how to Partitioning and Isolating Multi-Tenant SaaS Data with Amazon S3 which I believe addresses you question very well.
Here is the link:
https://aws.amazon.com/blogs/apn/partitioning-and-isolating-multi-tenant-saas-data-with-amazon-s3/?ck_subscriber_id=553485768

Do I need to cache the IAM role credentials when using the AWS Node.JS SDK

We're using Role Based IAM credentials in our AWS VPC. This means that you never pass in keys to the client of the AWS SDK.
Previously we've used the PHP SDK. Amazon specifically recommends to cache the credentials when using role based authentication with the PHP SDK:
https://docs.aws.amazon.com/aws-sdk-php/guide/latest/credentials.html#caching-iam-role-credentials
I'm now writing a Node.JS application using the S3 client. I'm wondering if I need to cache the credentials (as per PHP SDK) or is this something that the Node.JS SDK automatically does for us?
The docs for the Node.JS SDK do not specifically mention anything about caching role based credentials:
http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html#Credentials_from_IAM_Roles_for_EC2_Instances
Thanks
No, you do not need to cache IAM role credentials when using the AWS Node.js SDK.
I believe that the recommendation to cache credentials when using PHP is related to the request/CGI model that PHP uses. Without caching, your per-request PHP process would have to call out to the EC2 instance metadata service to retrieve credentials. Not ideal if you're handling high load.
With Node.js, you have a node process constantly running and it can persist credentials so will only need to call out to the EC2 instance metadata service once to retrieve initial credentials and then periodically to renew credentials when they are auto-rotated (every few hours, I believe).
As far as I can work out, unless you keep the client object around, the SDK will go back to the instance metadata service when it's instantiated again (except in the case where you instantiate a bunch of clients at the same time, in which case they all use the same instance metadata request event - odd).
i.e. cache your Amazon client objects (but this is not PHP, so you don't need an on-disk cache :) ).

Resources