Secure way of encrypting payload in Javascript for user authentification

I have created a login flow that authenticates a front end application (written in Vue.js) to retrieve the user_api_key of a Discourse user, following the guidelines written by @sam here.

The authentification works, however the concern I have is with storing the private key safely. At the moment the private key is stored locally in the .env file and used for the encryption/decryption of the payload. Is this a secure way of encrypting the payload, and if not - what alternatives are there for a front end javascript application?



As in an Electron/Tauri app? I have no idea what you would choose, I assume they have some mechanism for secure storage, maybe if you are lucky you can use keychain on mac and something similar on windows.


It’s a web application, hosted on a server. The concern is that somehow the payload could be intercepted if the private key is exposed. I’m aware this is a more general concern with javascript encryption, but asking in case there is a more secure practice for authenticating a web app from Discourse.

The user api key system is not designed for this use case, if you go through the dance of generating a private key and then go ahead and store it on the server on behalf of the user, why bother with all this dancing, just generate the keys server side.

Super hard for me to provide any guidance without me fully understanding what the actual problem is in much more detail. Why not simply provide proxy end points on your web app and handle all auth in your app?


After talking with my colleague @owengot, here is a more detailed description of the problem.

There is a Vue.js based web application that does not have its own active server-side component. It rather is a standalone web application that uses the Discourse API, so in a way Discourse is the server. Use cases include standalone polls or forms, where the content is posted to Discourse topics under the user’s account. Being able to create such a software without custom server-side components seemed like a nice architecture for these uses, so ideally we’d want to avoid doing anything “server side”.

Now, obtaining a User-API key works as intended, but @owengot discovered that the step of generating a private key in JavaScript takes a long time (up to 10 seconds, it’s just inefficient in JavaScript …). Then he discovered the hack that the same private key can be used for multiple users, so he stored it in a file on the web host that also serves the other static files of the web application (JS, CSS etc.). That makes it fast … but now that private key is (1) a shared one and (2) stored out in the open, with a publicly accessible URL. That seems, umh, frightening :fearful:

So I said, we have to ask the Discourse team about the security implications are of this hack. I see two basic alternatives:

  • If that private key is “only” used for payload encryption then we could live with this because we also have the communication encrypted via SSL / HTTPS.

  • But if knowing that private key somehow allows to compute the resulting User-API key that is later used for posting under somebody’s Discourse account, it would of course make this hack unacceptable.

I’m also curious about this, as I’ve started to use the software developed by @owengot. Based on what @tanius, do you think this is a safe way to do it @sam?

Yeah don’t do this. Private key is intended to be private per client.

The 10 second key generation is a price you need to pay. There are some js crypto apis that can make it faster.