AWS api gateway upstream authentications - amazon-web-services

I have a question about aws api gateway and it's possibility about upstream authentication.
We come from a monolithic approach and we try to slice into multiple services. We introduced SSO a few weeks ago.
There are some legacy services in place with basic auth credentials or api keys used for machine to machine communication.
Now we want to introduce an api gateway to have a single entrypoint for our clients.
The gateway needs to pass multipart/form-data in form of files and simple json requests as well. The plan is to validate the users in the API Gateway and passthrough the requests to the upstream services.
The services as mentioned above have unfortunately different ways of authentication.
I tried to use AWS API Gateway HTTP API to authenticate against ab backend API secured with basic auth credentials.
The HTTP Api has the advantage that you already have a jwt authroizer in place and you don't need to build your own lambda function for that. Unfortunately you can't set the Authorization header in the HTTP API but you can do in the REST API. I'm also not sure if the REST API will handle multipart/form-data passing through to the destination service.
I already know, that the file limit is 10MB for this requests.
Alternatives like kong, krakend, tyk or others are also welcome when the provide this capabilities as easy as possible.
Thanks a lot.

Related

How to securely access API Gateway from a frontend application hosted in AWS amplify?

I have the following:
A Vue.js frontend app hosted in AWS Amplify.
An API Gateway that triggers several Lambdas that make changes in a MongoDB hosted in an EC2 instance.
My idea is that the frontend approaches the API Gateway and GET/POST data.
The problem is that I would like to make the API Gateway accessible only from my App (nobody could make requests without authorization).
How should I handle it?
If I provide API Keys to the API Gateway, how do I inject them securely in the frontend app? Those will be accessible to anyone, right? If so, where should I put that API Key? Inside an .env file? Would that be secure enough?
Using API Gateway authorizers?
I've seen some examples where people place an intermediate backend in Amplify in order to do so, but I'd like to avoid that if possible.
This answer isn't prescriptive, but hopefully has enough detail and buzzwords to start you on your journey.
Your front-end requests will should an Authorization header with a JWT token from Cognito or your auth provider.
API Gateway can wire-up to Cognito (or you can wire-up a "custom authorizer") and only pass-through requests that have a valid token.
Your Lambda will know the user is validated (as a known user or guest) but must still determine if they are authorized to perform the action they're attempting. If using something like AppSync, you can pass the user's Authorization header though to the AppSync API and the resolvers can allow/reject based on the authorization rules in your schema. I'm not familiar with EC2 hosted MongoDB, but imagine you'll need to wire it up to your auth so it can behave similarly.
I wouldn't recommend API keys. You can't put them client-side, they need to be managed and rotated, you're letting the "lambda" have permissions instead of the "user", etc.
I do recommend Amplify. You may be able to ditch MongoDB and the EC2 (yuck, you don't want to manage that) for AppSync backed by DynamoDB. And if you also use Cognito, you can do much of the above with very little effort.
EDIT To address your comment:
While your website may be hosted on your servers (or your account on a cloud provider's servers), it runs on people's personal devices. The HTTP requests (e.g. REST) your server receives don't indicate they originated from your website and there is no 'link' that ties YOUR front-end to your backend. HTTP does have a Referer Header that indicates the webpage the request is associated with, but you can't trust it.
Because your site is public, your API will receive requests from anywhere and everywhere. There is no way to prevent that. You can put less expensive request handlers in front of your API handlers to catch and discard invalid requests (or return cached responses when appropriate).
Your server could require requests include a special header (e.g. an API-KEY) that only your website will include in requests. But anyone can look at your website code and/or the network traffic (even simply via the browser debugging tools) and learn about that secret header.
You can look into XSRF tokens. This is where the front-end provides a unique token when serving a page (usually in conjunction with a form), and it must be included when sending data back to the server or the data will be considered invalid.
Cognito / Amplify will generate tokens for GUEST/un-authenticated users as well. So they can be used for what you want. It doesn't guarantee the requests are coming from your websites's javascript, but it'd be annoying to work around.
You can use CORS in your server responses. That prevents other websites from directly calling your APIs. Your server would still be called and return data, but an unmodified browser will see the CORS header and throw away the data before making it available to the calling javascript.
At the end of the day if your APIs are on the public internet, anyone and everyone can poke them.

is ok to choose AWS HTTP API gateway for a mobile application?

I am trying to decide which aws apigateway version choose for my application (HTTP vs REST API gateway).
I am experimenting with AWS HTTP API gateway to see if it works fine for my use case.
These are my requirements:
The only client is a mobile application
The rest API can be accessed only from logged in users
I want to use cognito with cognito authorizer
My backend is a mix of lambda services and HTTP rest services exposed via an internal application load balancer
Everything seems to be supported, the only concern is that I would have used an api key, but this feature is not currently supported on HTTP API gateway.
Are there any security concern if I go for HTTP without any api key?
What would be the right way to restrict the access only to requests coming from my mobile app?
Everything seems to be supported, the only concern is that I would have used an api key, but this feature is not currently supported on HTTP API gateway.
HTTP APIs support OpenID Connect and OAuth 2.0 authorization
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html
If you have any custom api-key, you can still have an authorizer lambda to authenticate and authorize the client.
Are there any security concern if I go for HTTP without any api key?
What do you mean by the api-key? API-key is usually static shared secret used mostly in the backend application. Claiming the users need to be authenticated and using the mobile app, having a hardcoded api-key is not the best idea (read - it is a terrible idea)
Under these requirements the default option is using OAuth2/OIDC for user authorization and passing the user's access token along the API requests.
What would be the right way to restrict the access only to requests coming from my mobile app?
I want to use cognito with cognito authorizer
The simplest and built-in way is using the access token from Cognito and built-in JWT API authorizer. Yet you may configure any other option.

Authenticate session with AWS API Gateway

Situation: I have an app (Next.js/React on Vercel) running on example.com. I have an api (AWS API Gateway) on api.example.com. Currently the application on example.com supports login using Auth0 as authentication provider.
Problem: I would like to be able to make authenticated requests from the application (example.com) to the api (api.example.com).
Architecturally, I was hoping for a way for the API Gateway (api.example.com) to handle the authenticated session from the app/Auth0 cookie (example.com). I thought the browser could share the cookie (since api.example.com is trusted) and the API could validate it.
But I don't see a standard way to do it. I think I could try to create some custom lambda authorizer for AWS' API Gateway. But since we're dealing with authentication, I would prefer to outsource as much as humanly possible and avoid any custom code. I just can't seem to piece together the way for API Gateway to handle the sessions, which I assumed would be a pretty common problem to solve.
Sidenote: Previously, I used the pages/api that's baked into Next.js to directly call Lambdas on AWS and expose them. With this, authentication natively works. That's the experience I'm now trying to recreate, but without the user having to take a roundtrip.
When you want to protect APIs it’s better to use JWT tokens to carry over necessary claims e.g. id of authenticated user. OpenID connect and Oauth2.0 are the standards to look into.
Auth0 has documentation of recommended authentication flow: https://auth0.com/docs/flows/authorization-code-flow
as well as example with Api Gateway’s HTTP apis: https://auth0.com/blog/securing-aws-http-apis-with-jwt-authorizers/
AWS documentation has more info about Http Apis and JWT token authorizers: https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-jwt-authorizer.html
If your Api gateway is using Rest apis instead of more light-way Http apis then token based Lambda authorizers are the right solution: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

Inject AWS Secrets Manager secret into API Gateway integration

I'm maintaining an API Gateway which proves its identity one of its upstream API (HTTP) proxy integrations using an API key in a GET parameter. (Certain limitations prevent a more robust client SSL certificate at this time.)
Currently this API key is supplied as a static value in the URL Query String Parameters section of the HTTP Proxy integration.
It's time to rotate keys and we need a more centralized / integrated solution to this problem --- for the client and the back-end.
What's the most direct, straight-forward way of injecting secrets from AWS Secrets Manager into an API Gateway integration?
I can imagine loading the relevant secret onto the request context from the respective authorizer lambda, but this seems wrong: a mingling of separate concerns.
Thanks in advance for any tips!

AWS Api Gateway / AWS ALB / Kong Api Gateway

I have a task to replace current CA layer 7 with new API gateway.
New API gateway should be able to handle
1. Rate limiting
2. Authentication
3. Version handling etc.,
After researching i found we could use AWS api gateway or Kong api gateway or AWS ALB with Cognito for authentication support.
This is so overwhelming to understand the basic differences, could you please give some insight on basic concept in simple words and some pointers or link that i should refer to start with.
API Gateway keep track of every deploy you make in the Deployment History tab. There you will find all versions of your API and you can change to any of them whenever you want.
You can also create your api gateway from a Swagger file.
For every method that you create for a resource you need to configure the Method Request, the Integration Request, the Integration Response and the Method Response.
The Integration Request is where everything happens. You will set there how you are going to handle your requests, if you are going to integrate with any aws service like firehose or if you are going for a lambda integration or with an existing HTTP endpoint.
Mapping Templates uses Apache Velocity Template Language (VTL). http://velocity.apache.org/engine/1.7/vtl-reference.html
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
Getting started with REST apis:
https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started.html
API GATEWAY INTEGRATION TYPES:
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-integration-types.html
How to import a rest api:
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html
Limits and known issues:
https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html
Deploying:
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api.html
Publish:
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-publish-your-apis.html
AWS API Gateways supports lambda authoriser for authentication which is integrated with any identity provider - Azure AD, Cognito pool etc. It supports both Client Credentials (service to service) authentication and Authentication code(user based authentication) but AWS ALB don't support client credentials authentication flow.
AWS API Gateway also provides caching, request & response mapping, customise handling for each response type, request validation, throttling where AWS ALB is yet to be improved for all these feature.
Kong api gateway also provide similar feature as AWS API Gateway with added features
If all the backend services are deployed in AWS and you don't need
complex API gateway then go for AWS API Gateway. It is pay per use service and you don't need to pay for extra support for API gateway assuming your services are already deployed in AWS.
If you need api gateway solution with complex requirement and extra features then Kong API gateway can be considered. But you will need to either pay for Kong API gateway support or need extra effort in coding when used open source.
AWS ALB can be used only for specific scenarios and it is getting matured day by day.