WSO2 identity server is really slow with 2000 policies - wso2

I am trying to benchmark WSO2 identity server 4.5, using postgresql, to measure how many policies can be supported without having a too bad decision time.
I have java program to upload all my policies using EntitlementPolicyAdminServiceStub from org.wso2.carbon.identity.entitlement.stub-4.2.0.jar:
adminStub.addPolicy(myPolicy)
After the 100 first policies there is an important degradation of upload time (more than 2 sec for each policy) and it gets worse with time.
For 3000 policies, WSO2 is no more responsive and, when I have a look to database statistics I can see there are more than 10^12 Tuples Returned for the all the database and 10^11 Sequential Tuples Read for the reg_resource_property table.
Is it something normal or is there a mistake in my WSO2 configuration?

Yes.. there can be some limit.. In your case, it seems to be an issue with policy storing.. By default identity server stores XACML policies in the wso2 registry.. You could see such database statistics due to that.. Because it is not like just putting policy as a database entry in a table.. As it is governance registry, there are lot things happened behind that... If you need more performance with policy storing, I guess it is better to implement a new policy store by extending the default behavior. Basically you can write a policy store to persist policies in a simple database table or even in file system. You can find the source of the Registry policy store from here.
Also, In runtime, all policies are loaded in to the memory, normally this is happened when entitlement engine is initialized.. or less any update is happened.. When number of policies are large there can be delay in retrieving policies from registry (but registry itself as caching and indexing...so may be not as slow as we think). As runtime, all policies are kept in the memory, we may need to consider about the memory footprint of the server. You can increase it using wso2server.sh file.
Also, there are some doc that has been mentioned about performance test with WSO2IS, Please refer it for more details

Related

Cache JWKS in Lambda memory vs in temp

I currently am retrieving a JWKS keys using the Auth0 JWKS library for my Lambda custom authoriser function.
As explained in this issue on the JWKS library, apparently the caching built into JWKS for the public key ID does not work on lambda functions and as such they recommend writing the key to the tmp file.
What reasons could there be as to why cache=true would not work?
As far as I was aware, there should be no difference that would prevent in-memory caching working with lambda functions but allow file-based caching on the tmp folder to be the appropriate solution.
As far as I can tell, the only issues that would occur would be from the spawning of containers rate-limiting JWKS API and not the act of caching using the memory of the created containers.
In which case, what would be the optimal pattern of storing this token externally in Lambda?
There are a lot of option how to solve this. All have different advantages and disadvantages.
First of, storing the keys in memory or on the disk (/tmp) has the same result in terms of persistence. Both are available across calls to the same Lambda instance.
I would recommend storing the keys in memory, because memory access is a lot faster than reading from a file (on every request).
Here are other options to solve this:
Store the keys in S3 and download during init.
Store the keys on an EFS volume, mount that volume in your Lambda instance, load the keys from the volume during init.
Download the keys from the API during init.
Package the keys with the Lambdas deployment package and load them from disk during init.
Store the keys in AWS SSM parameter store and load them during init.
As you might have noticed, the "during init" phase is the most important part for all of those solutions. You don't want to do that for every request.
Option 1 and 2 would require some other "application" that you build do regularly download the keys and store them on S3 or a EFS volume. That is extra effort, but might in certain circumstances be a good idea for more complex setups.
Option 3 is basically what you are already doing at the moment and is probably the best tradeoff between simplicity and sound engineering for simple use cases. As stated before, you should store the key in memory.
Option 4 is a working "hack" that is the easiest way to get your key to your Lambda. I'd never recommend doing this, because sudden changes to the key would require a re-deployment of the Lambda, while in the meantime requests can't be authenticated, resulting in a down time.
Option 5 can be a valid alternative to option 3, but requires the same key management by another application like option 1 and 2. So it is not necessarily a good fit for a simple authorizer.

Is the content on disk in cloud (Azure, AWS) zeroized prior to re-releasing to other users?

Wanted to know if cloud based platforms such as Azure and Amazon zeroize the content on the hard disk whenever an 'instance' is 'deleted' and prior to making it available for other users?
I've tried using 'dd' command on an Amazon-LightSail instance and it appears that the raw data is indeed zeroized. However was not sure if it was by chance (i just tried few random lengths) or if they actually take care to do that.
The concern is, if I leave passwords in configuration files, then someone who comes along would be able to read them (theoretically). Same goes for data in a database.
Generically, the solution to your concern typically used by Azure is storage encryption.
Your data is encrypted by default at the platform level with a key specific to your subscription; when the data or resource is removed, whether or not the storage is zeroed, it is effective inaccessible to a resource deployed on the same storage in another subscription.

General guidance around Bigtable performance

I'm using a single node Bigtable cluster for my sample application running on GKE. Autoscaling feature has been incorporated within the client code.
Sometimes I experience slowness (>80ms) for the GET calls. In order to investigate it further, I need some clarity around the following Bigtable behaviour.
I have cached the Bigtable table object to ensure faster GET calls. Is the table object persistent on GKE? I have learned that objects are not persistent on Cloud Function. Do we expect any similar behaviour on GKE?
I'm using service account authentication but how frequently auth tokens get refreshed? I have seen frequent refresh logs for gRPC Java client. I think Bigtable won't be able to serve the requests over this token refreshing period (4-5 seconds).
What if client machine/instance doesn't scale enough? Will it cause slowness for GET calls?
Bigtable client libraries use connection pooling. How frequently connections/channels close itself? I have learned that connections are closed after minutes of inactivity (>15 minutes or so).
I'm planning to read only needed columns instead of entire row. This can be achieved by specifying the rowkey as well as column qualifier filter. Can I expect some performance improvement by not reading the entire row?
According to GCP official docs you can get here the cause of slower performance of Bigtable. I would like to suggest you to go through the docs that might be helpful. Also you can see Troubleshooting performance issues.

How to find the cache location for AWS Secrets Manager

I am using parameter store for storing the database credentials, and accessing them using a talend job. However, due to multiple jobs accessing these parameters at the same time; we are facing issue to scale the parameter store, as it reached threshold.
I have decided to go with the AWS Secrets Manager, and so far I am able to successfully create/fetch these secrets using an AWS Lambda function (Python); and I am using Python client side caching library SecretCache and SecretCacheConfig.
Had the below queries regarding the same:
Is it possible to know the location where my lambda function is caching these secrets?
If the secrets changes while my talend job is executing, how to make sure that the talend job uses the updated value for a secret?
How to make sure that the latest value for a secret is being used.
The SecretCache implementation is an in-memory only cache so you will not be able to find the cache on disk anywhere.
Questions ii) and iii) are somewhat related and depend on how the secret is used. In order to have a highly available rotation strategy you must be able to have two active secrets or users and alternate between them. By ensuring the cache is refreshed at more than twice the rotation rate, the cache will switch to the latest user password before the current one is over-written.
For example, if you are using a database, you could setup multi-user rotation and rotate once a day. Since the default cache refresh rate (secret_refresh_interval) is 1 hour, the cache will pick up the latest version of the secret before the next rotation.

Highly granular access control of non-AWS resources in AWS Cognito

I've got an ASP.NET Web API that is using AWS Cognito for authentication and resource access control. We've been using user pool groups up until this point to define certain entities users have access to (non-aws resources in a DB).
The problem is, now that our requirements for access control are more detailed, we are hitting the group cap of 25 per pool. I've looked into alternatives within Cognito, such as using custom attributes, but I've found that there are also limits on the number of custom attributes per pool, as well as they only support string & number types, not arrays.
Another alternative I've explored is intercepting the token when it hits our API, and adding claims based on permissions mapped in the DB. This works reasonably well, but this is only a solution server side, and I'm not entirely thrilled with needing to intercept every request to add claims with a DB call (not great for performance). We need some of these claims client side as well, so this isn't a great solution.
Beyond requesting a service limit increase to the amount of groups available per pool, am I missing anything obvious? Groups seem to be the suggested way to do this, based on documentation from AWS. Even if we went for a multi-tenant approach with multiple pools, I think the 25 group cap is still going to be an issue.
https://docs.aws.amazon.com/cognito/latest/developerguide/scenario-backend.html
You can request limit increases for nearly any part of the service. They will consider. Sometimes this is more straightforward than building side systems, as you point out. See https://docs.aws.amazon.com/cognito/latest/developerguide/limits.html