We have middleware which does KYC verification was associated documents to entities(deals/accounts/contacts) in freshworks_crm.
It uploads documents to freshworks and also sends to external API to validate. For these two operations we need respective API keys which is taken as an input from custom app configuration. API keys are not set to secure because we had to fetch them and send it to middleware.
We have submitted the app for review and received following comment
One of the things you can maybe try doing is make them secure and onAppInstall POST it the middleware. The payload passed as an argument to onAppInstallHandler(..) will have API keys that middleware requires. Can you use Axios request in server.js that way to send those API keys to middleware?
Middleware doesn’t store any values from custom_app and there is no database in place. These API keys will be specific to clients and to identify them based on requests is something difficult.
We are sending the documents as well as part of the request payload which will be in MBs, this cannot be sent to serverless method because of paylod size limitations and also FormData cannot be passed as well.
I am guessing API keys are saved to the custom app at the installation time.
The two operations handled by middleware will happen when the user chooses within the app’s UI after the installation within the specified placeholder.
At what point does the app talk to middleware? and How?
Yes, but we need them in middleware to call freshworks and Karza API’s.
Once the User selects documents and clicks “Upload” we call middleware with API keys and documents. Middleware associates the documents to freshworks entities , validates with Karza API and return back the result to custom app.
Where will we store the keys?
As I mentioned we don’t have a database in place to store the keys and we cant cache them because there could be multiple requests from different users.
I dont think so, tracking each requests and setting the expiry is something we have to try and check but at this stage its too much for us to do. If you suggest thats the only way then I have to check if the timelines can pushed.
On page load of configuration page (iparams.json or iparams.html), make a client.request.post(..) call with templated API keys to the Middleware.
Middleware will grab the API keys from the request to construct an Object (for example { "apikey1": "avengers", "apikey2":"eternals"} and then encrypt it — let encrypetedkeys = encrypt(apikeys);
Middleware responds to the app with encrypted keys. The user who would still be on the configuration page and might’ve just entered both the keys and hit ‘save.’
3.a App stores encrypted keys as an installation parameter by the time users hit “Install” button.
Here on app would use the encrypted API keys as non-secure installation parameters within Axios calls along with attachments to the Middleware. Although they are visible on the frontend, they are useless since only middleware and decrypt it.
This should also work with multiple apps since the encryption and decryption happen at the runtime.
Security wise, these API keys are still not stored with the middleware, it merely knows how to decrypt it at time of performing two operations and forgets it.
We are using iparams.json and not the custom installation, is it possible to listen for the page load event?
Lets says if we have to switch to the custom installation then on page load we wont have these keys entered, so should we act on the change event of input control?
Is it possible to keep the user blocked from clicking the “Install” button until the middleware responds with the encrypted key?
You can use iparams.js and iparams.json to listen for page load events.
Here’s example from Freshsales page, documentation is just missing for Freshdesk. You can try out.
You can make requests and get encrypted keys as soon as the user pastes API Keys and set as a iparam (may be invisible values). Install button is prevented if one of the validation checks fail. May be you can use that face to ensure encrypted values are stored?
You can use the API keys in the configuration page itself via iparams.json or custom installation page, whichever suits you to send the API keys for encryption before users install the app but enter them in their fields.
Since it is an Admin Session that’s logged in, your API keys are governed by the same level of security as a logged-in admin user at this stage.
You can use client.request with API keys in the header (marked secure in iparams) and other information in the body to make the API call from the app configuration page itself.