neosmart / SecureStore

A .NET implementation of the cross-platform SecureStore (symmetrically-encrypted secrets) protocol
MIT License
96 stars 15 forks source link

Question - keyfile & key store on production - setup #21

Closed LeoJHarris closed 5 months ago

LeoJHarris commented 6 months ago

Hi there πŸ‘‹ first of all thanks for providing this amazing project! We have just added this to our console application that runs on premise of a clients VM. We have a few secrets and this seemed like the perfect without having to setup azure key vault etc.

In any event we have been able to perform the following to create both the secrets.json and secrets.key as per the documentation

SecureStore create secrets.json --password --keyfile secrets.key Password: ****

We want to be able to deploy to the clients production VM so with regards to the keyfile, are we able to seek clarity on this part:

While secrets files (e.g. secrets.json) are encrypted and may be included in source control, the keyfile must be handled with extreme care and should be securely moved to the production servers or a key store and then deleted locally!

Apologies for my ignorance but is this to say we can put the keyfile on the production VM but it must be in secure location on the VM? Also I wasn't entirely sure on the key store part either? Is there a method of retrieving the key store from the keyfile I assume?

Again apologies for all the questions but I have already populated the secrets.json with secrets and with a strong password setup, mainly we are keen to deploy an application on premise to the clients VM but want to ensure we set this up correctly on their end, its all running smoothly on my local machine with using the secrets.key but I'm guessing we cant just copy this over like the secrets.json and put it anywhere on the host machine?

LeoJHarris commented 6 months ago

@mqudsi Sorry to bother but would it be possible to provide us a bit more guidance on this?

mqudsi commented 6 months ago

Hi Leo,

It all depends on your security model. In our case, we deploy the keys as part of the payload to our production IIS servers via the regular "web publish" feature and the path the keys are deployed to is only accessible (read/write permissions) to the iis worker process. If an attacker were to gain a non-admin, non-worker-process foothold on the server, theoretically the key file would remain secure as it would be inaccessible to other accounts on the same machine.

If you are bundling the key file with your app and deploying it to client hardware under client control, you'd want to treat it the same way that you would an api secret key in the first place (i.e. probably not a great idea unless you are using a secure computing feature to run encrypted code in a secure enclave on their machine). So it all depends on who has access to what and what level of security you are comfortable with, how much you trust the client, etc. but generally when you need authenticated access from a client machine that's when you're supposed to use oauth tokens or something else like that instead of an api key.

LeoJHarris commented 5 months ago

@mqudsi thanks for the response! We opted to put the password (used for LoadKeyFromPassword) on Google Cloud Secret Manager which only the application can access, but out of curiosity can the private key be used without using a file containing the key? The LoadKey always expects path to the .key file so guessing only option is running with the password method.

mqudsi commented 5 months ago

You can store the key in the code as binary, encrypted, encoded, etc or in a project resource or whatever then use LoadKeyFromStream().

But again, of course there are security considerations regardless of where you are storing the key or even retrieving it over the network so long as the binary or the machine running it is not under your control.

LeoJHarris commented 5 months ago

You can store the key in the code as binary, encrypted, encoded, etc or in a project resource or whatever then use LoadKeyFromStream().

If the key can be stored in code, that could work better. Is there any examples of how this can be done? As a binary or encrypted? Wouldn't we still need to somehow decrypt it and potentially expose the key anyway? Wouldn't something like Google Secrets Manger be safer to manage the key?

mqudsi commented 5 months ago

I'm not comfortable providing more answers here as this scenario is only recommended when the binary is under your control (i.e. a web server) and not when it's being distributed to clients.

LeoJHarris commented 5 months ago

@mqudsi not a problem, we will be running with Google Secrets manager so we are looking good, thought we could cut that out but in any event thanks for the assistance.