wso2 api gateway token caching - wso2

I've been testing the api manager for a while, and currently I'm doing some performance testing on some machines, but noticed poor performance (like 20 req/s). After some checks (the machines are not reaching cpu/mem limits) I noticed a large amount of opened connections from the API Gateway to the Key Manager, even if I'm making the same request with the same token over and over again.
The docs refer to the Gateway Token Cache in the api-manager.xml file and <EnableGatewayKeyCache>true</EnableGatewayKeyCache> setting, but it's enabled by default, and I'm using the defaults in almost everything else.
Why are there so many connections to the Key Manager and how can I improve the performance?

For token caching to work successfully it's required to have caching enabled at Gateway and Resource level. If either one is disabled, it is possible for an API call to hit the Key Manager. By default, Gateway caching and Resource caching are set as enabled in APIM pack.
Could you please check if you have disabled resource caching? If so please make sure to enable resource caching and try again. You can enable resource caching by setting "EnableGatewayResourceCache" value as "true" in api-manager.xml file. You can find more information about API Manager caching in these documents [1][2].
[1] https://docs.wso2.com/display/AM1100/Configuring+Caching
[2] http://sanjeewamalalgoda.blogspot.com/2012/10/wso2-api-manager-advanced-validation.html

Related

What is the default cache policy of cloudfront (when regular lambda running calling by api gateway )

What is the default cache policy of "cloudfront" (when regular lambda running calling by api gateway )
It depends on what you configure for the TTL and whether you configure caching. Check out the "Does Amazon API Gateway provide API result caching" FAQ under Throttling and Caching:
https://aws.amazon.com/api-gateway/faqs/
You can add caching to API calls by provisioning an API Gateway cache
and specifying its size in gigabytes. The cache is provisioned for a
specific stage of your APIs. This improves performance and reduces the
traffic sent to your back end. Cache settings allow you to control the
way the cache key is built and the time-to-live (TTL) of the data
stored for each method. API Gateway also exposes management APIs that
help you invalidate the cache for each stage. Caching is available for
REST APIs in API Gateway.
If you enable this, then per https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html
The default TTL value for API caching is 300 seconds.
If you configure an Edge-optimized API endpoint then you can configure your own CloudFront distribution and manage that in the CloudFront settings. If you do that, CloudFront documentation states that
By default, each file automatically expires after 24 hours
Also see API Gateway Caching vs CloudFront

Attaching a usage plan to a public Api Gateway Endpoint

For learning purposes, I have developed a front-end application in Angular with AWS as back-end.
As this is a didactic project, I must prevent any possible costs explosion. Overall, for what concerns API Gateway calls.
At the moment, I have a single public GET endpoint for providing the information to the public homepage in the front-end.
I need to attach a usage plan to this endpoint for limiting the maximum number of calls to this endpoint. For example, max 10000 calls/week.
I already tried with an API-KEY:
Created the Usage Plan with "Quota: 10,000 requests per week"
Created the API KEY connected to the Usage Plan
Connected the API KEY to the authentication method of the endpoint
It works, but in this way I need to hard code the API KEY on the front-end.
I know that hard coding sensitive information on the front-end is a bad practice, but I thought that in this case the API KEY is needed only for connecting a Usage Plan, not for securing private information or operations. So I'm not sure if in this case it should be acceptable or not.
Is this solution safe, or could the same API KEY be used for other malicious purposes?
Are there any other solutions?
To add to the other answer, API Keys are not Authorization Tokens.
API Keys associated with Usage Plans are sent to the gateway on the x-api-key header (by default).
Tokens used by authorizers live on the standard Authorization header.
Use API Keys to set custom throttling and quotas for a particular caller, but you still need an Authorizer on any secure endpoints.
You can optionally set an API Key to be returned from the Authorizer when using a custom authorizer to be applied to the Usage Plan, which prevents you from having to distribute keys to clients in addition to their secrets.
APIG Key Source Docs
As the documentation says, generally you wouldn't want to rely on a hardcoded API key for authentication.
In addition, based on the information you provided, the usage plan limits are tied to the use by the user of the API key. So you could also set up throttling on the account or stage itself.
Finally, if it's possible, you could set up security group rules on your server or access control lists on your vpc that is serving your front end so that not everyone can access it.
Other ideas are to shut down the API gateway when you aren't using it and also rotate the API key frequently.
Obviously none of these are going to be enough if this were hosting sensitive information or doing anything remotely important. But as long as the only information in the client side is that API Key to access the API Gateway and that API Gateway itself doesn't interact with anything sensitive that's probably enough for a learning project.
But you should do all of this at your own risk as for all you know I'm the person who's going to try to hack you ;)

Errors when activating API Gateway’s cache on AWS: no CORS headers returned from CloudFront

We have a set of different APIs created by serverless (>= 1.18). They work nicely (with CORS) in production since months. Now we need to activate the API Gateway's cache but after that the API gives errors. Specifically I see this in browsers' Javascript console:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
When we press the "Flush cache" button in the API Gateway console, the first call to the API works (it doesn't go through the CloudFront cache), but as soon as the resource gets cached again, we immediately get the mentioned error again.
In summary, it seems that when activating the API Gateway cache, responses coming from CloudFront's cache "lose" the CORS headers.
For the moment we have disabled all API Gateway caches and everything is working back to normal, but this is going to create performance issues on the backend as usage of the API is increasing.
Has anybody else experienced this behavior or are we missing any configuration on serverless side? Is there any workaround?
Serverless Framework Version: 1.21.1

AWS API Gateway - Enable caching per-request

Is it possible to enable/disable caching a request through the AWS API Gateway in the response of the request?
According to this document: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html It appears that the most granular one can get in defining cache settings is enabling/disabling caching for a specific API function. What I am wanting to do is allow the response for the API request to dictate whether or not it is to be cached. (i.e. I want my end API program to be able to determine if a response for a given request should be cached).
Is this possible, and if so how can it be accomplished?
Configure your own CloudFront distribution, with the API Gateway endpoint as the origin server. CloudFront web distributions respect Cache-Control headers from the origin server. If you customize that response, this should accomplish your objective.
API Gateway, as you may already know, runs behind some of the CloudFront infrastructure already, so this might seem redundant, but this appears to be the only way to take control of the caching behavior.

WSO2 API Manager v1.8.0 - Clustering

I have a question on WSO2 API Manager Clustering. I have gone through the deployment documentation in detail and understand the distributed deployment concept where in one can seggregate the publisher, store, key manager and gateway. But as per my asessment, that makes the deployment architecture pretty complex to maintain. So I would like to have a simpler deployment.
What I have tested is to simply have two different instances of the WSO2 API Manager to run in two different boxes pointing to the same underlying data sources in MySQL. What I have seen is that, the API calls work perfectly and the tokens obtained from one WSO2 instance would work for API invocation on the other API Manager instance. The only issue with this model is that we need to deploy the APIs from individual publisher components for as many WSO2 API Manager instances that are running. I am fine to do that since the publishing will be done by one single small team. We will have a hardware load balancer in front having the API endpoint URLs and token endpoint URLs for both the API managers and the harware LB will do the load balancing.
So my question is - are there any problems in following this simple approach from the RUNTIME perspective? Does the clustering add any benefit from RUNTIME perspective for WSO2 API Manager?
Thank you.
Your approach has following drawbacks (there can be more which I do not know);
It is not scalable. Meaning - you can't independently scale (adding more instances of) store or publisher or gateway or key manager.
Distributed throttling won't work. It will lead to throttling inconsistencies since the throttling replication won't happen if you don't enable clustering. Lets say you define 'Gold' tier for an API. Doesn't matter how many gateway instances you are using, a user should be restricted to access no more than 20req/min to this API. This should have been implemented based on a distributed counter (not sure the exact implementation details). So if you don't enable clustering, one gateway node doesn't know the number of requests served by other gateway nodes. So each gateway node will have their own throttle counter. Meaning - a user might be able to access your API more than 20req/min. So this is one of the throttling inconsistencies. Further, lets say one gateway node is throttled out a user but the other gateway node is not. Now, if your LB routes the request to 1st gateway node, user will not be able to access the API. If your LB routes the request to 2nd gateway node, user will be able to access the API. This is another instance of throttling inconsistency. To overcome all these issues, you just need to replicate the throttling across all the gateway nodes by enabling clustering.
Distributed caching won't work. For example, API Key validation information are cached. If you revoke a token in one API Manager node, cache will be cleared in that node. So a user can't use revoked token via that API Manager node, BUT he is able to use the token via the other API Manager node until the cache is invalidated (I guess 15 min by default). This is just one instance where things can go wrong if you don't cluster your API Manager instances. To solve these issues, you just need to enable clustering, then the cache will be in sync across the cluster. Read this doc for more details on various caching available in WSO2 API Manager.
You will be having several issues if you don't have above features. WSO2 highly recommends distributed deployment in production.