What’s the best practice to differentiate the api calls from internal and external gateway. Is it recommended to create two api methods (secured and not secured)
Use the same Auth header as you do for external consumers and check the permissions for the actual consumer. Another way is just having two APIs.
Related
Lets say I have 2 Microservices (customer and payment), both consume APIs of external system (e.g. Stripe).
API Authentication
Assume that before consuming any business API of Stripe, API Consumer (in my case Customer & Payment Service) has to first authentication itself using API Keys (AppId and secret).
Stripe provides access token which must be passed into HTTP header into subsequent API calls to Stripe.
below can be possible approaches,
Approach1
https://drive.google.com/file/d/1BGn-hiNwZT4u3BIBmEv-HkJC0w0dk5CB/view?usp=sharing
Approach2: https://drive.google.com/file/d/1JA1hFq7l7-4Ow3b32XNyb2co4tqxKZQ6/view?usp=sharing
Approach1
Multiple auth token though Stripe account is single (per service instance)
Each service to manage auth token expiration/renewal
Approach2
Single auth-token exists with all services.
dependency on auth service.
auth token expiration/renewal managed by single service (Auth Service)
would like know which should be best fit in Microservice architecture? Any other suggestion?
Approach 2 is slightly more scalable and maintainable if more services will require API access to external APIs.
However the correct implementation would be an egress gateway for all your external API calls.
If your going to spend the time to build an Auth service, you might as well go all the way and centralize your external API routing as well.
Benefits:
Single internal endpoint for external APIs, reduces duplication.
Handles all authn and authz with external APIs for your services.
Centralizes all logging, auditing, disaster recover, load balancing etc....
Most gateway products like kong can be used for egress as well.
I have a Single Page App application which is working based on RESTful APIs. Generally, all APIs have a route access which can be found while inspecting web application.
Although I have authentication mechanism based on user tokens, a hacker can find the API routes and use his given token to send many requests to APIs directly.
What is the best solution to prevent such behavior? I was thinking about CSRF, but as APIs are based on REST, and the project is a SPA, I think I should have another mechanism.
May you help me please?
You cannot authenticate the client application, it is not possible. If a user can send a request from an spa, because they have the credentials and the endpoints to send them to, they can use whatever client from Burp through ZAP or Postman to curl or whatever else to send the request.
Your API must be resilient, you should have rate limiting, user quotas, monitoring and secure operation practices in general on the server side based on your threat model to mitigate this risk.
In practice this might mean hosting the API in a way that's resilient to DoS on the network level, having a per-user request rate limit, identifying functionality that is a burden for the server for some reason (calls external services, sends email and so on) and protect/monitor those even more carefully. There is no one size fits all solution.
We are trying to build an API gateway in front of our application (we may split the application to micro services ASAP), and we meet some problems.
1 - different API types.
There are two kinds APIs in our application, most of them will be used by ourselves(user login/logout, news add/remove), we call them Self-used API here. And some of APIs will be allowed to used by third party, we call them Open API here.
Should all of them get through the gateway?
2 - different authentication
Self-used API may require the user login-ed or have related permissions, the Open API will require the third-party app take a key which we will use to identify and limit the request rate.
Should all kinds of authentication completed in the gateway? If yes, the Self-used api authentication is business related, does it mean that this api gateway can not be shared by other application?
Furthermore, the third-party developer will create their application and get a key back, they can also update/remove the apps(Something like Google API Console).
I am not sure if this should be put in the gateway or another micro-service. IMO, I prefer to put these features in a new service, but the validation and rate limit is done in gateway, that means for each request, gateway will have to query the user, rate limit and other information by the key from the service, this will make the gateway coupled with the business again.
There are quite a few ways of implementing an API Gateway. You can use different endpoints with a single API gateway. Here are a few links that are relevant
Serverless blog "How to deploy multiple micro-services under one API domain with Serverless" https://serverless.com/blog/api-gateway-multiple-services/
Nginx "Do You Really Need Different Kinds of API Gateways? (Hint: No!)" https://www.nginx.com/blog/do-you-really-need-different-kinds-of-api-gateways-hint-no/
Sentialabs.io "Amazon API Gateway types, use cases and performance" https://www.sentialabs.io/2018/09/13/API-Gateway-Types-Compared.html
AWS API Gateway FAQs https://aws.amazon.com/api-gateway/faqs/
Think about the types of features you are trying to accomplish with your approach, and how API Gateway will help you address them.
We have a package that we share with out customers. In the package, we have a chunk of code that does HTTP Request callouts to our central API Gateway. As of now, our API Gateway is open and accepts requests from everywhere, which is not good. I want to limit access to our users who would be using our software. The only solution I have found is using IAM and providing authorization that would require us to include our Access Keys in the package. Our users can install our package in any environment they want and we have no control over that environment. So I think a viable option is to create a generic user policy with minimal access to allow our users to call our API Gateway. However, putting access key in the code doesn't seem like a good idea. Another option is to provider our customers with access keys but that also has overhead. What is a better alternative that is more secure and easy to maintain?
You can use built-in API Gateway API Key functionality when IAM policies aren't possible.
So long as your clients could be on any infrastructure, versus limited to AWS, the API Gateway service provides a generic API key solution, which allows you to restrict client traffic to your API Gateway by enforcing that client requests include API keys. This API key interface is part of their "API Usage Plan" feature.
This document explains how to use the console to set up an API Gateway to enforce that client traffic bears an API key:
To set up API keys, do the following:
Configure API methods to require an API key.
Create or import an API key for the API in a region.
Your clients can implement a "secret storage" solution, in order to avoid putting their API keys into their source code.
For sure it isn't wise for your clients to store their API Keys plain-text inside their source code. Instead, they could use a secret storage solution, to store the API keys outside of their codebase, but still give their applications access to the secret.
This article describes an example solution for secure secret storage (e.g. secure API key storage) which grants an application access to the application secret without putting the unencrypted secret into the source code. It uses Amazon KMS + Cryptex, but the same principle can be applied with other technologies: http://technologyadvice.github.io/lock-up-your-customer-accounts-give-away-the-key/
To ensure a REST API is accessed only by known consumers, client applications use to sign each HTTP request with a secret and then send the resulting signature togheter with the API key to the server.
In case of JavaScript clients the API key and secret are hardcoded in the script itself... so how does this mechanism ensure a client sending the request is really the client it is supposed to be? I'm asking because if the secret is hardcoded in the JavaScript, everybody could look at it, steal the secret, and use it in other applications.
Is there a safer way to expose an API to consumers? I know there are other posts in Stackoverflow covering this topic... but what is not clear to me is how to deal with both consumer authorization and user authorization. In my case, consumer authorization determintes whether or not a third party is allowd to access my API and has nothing to do with business logic, while user authorization is at application level (i.e. after the consumer has been identified and authorized).
You can check the domain and provide a SOP setting to restrict to only known domains.
You can drop requests by origin ip if the ips are going to be constant.
Moreover you can have a secret generator on your server which client need to call from there on servers and pass it on their js code, from there it can be attached to api call. This way client with SOP can make sure that their js is not injected. You can check on the clients IP before providing the response.
Basically, it would depend on the type of consumers you going to serve. Are they enterprise customers, etc.
After some googling I found this great article and just implemented the solution it describes ;-)