This "random symmetric encryption key" sounds like it performs a similar role to the "passphrase" you'd normally use with GPG - except that because it's chosen at random rather than selected by the user, it's not vulnerable to offline brute force attacks.
I guess it doesn't harm to review the threat model:
1. In the current system, people post their private key in the clear with every request, and the responses contain decrypted secrets. If an attacker has access to either the incoming requests or outgoing responses, you are toast.
2. You're adding a cache of private keys, and you're trying to protect against an attacker who has access to the cache, but not to the requests/responses
3. An attacker might also obtain access to private keys on the client endpoint. If so, they'd also need the user's netbox login to use it. And if they have sufficient access to the client machine, they could intercept decrypted secrets there anyway.
It does make me nervous that Netbox is repeatedly receiving users' private keys, in plain text. (I'd never trust a server with my real private key and passphrase, so I'd always generate a separate single-use key for Netbox)
It also makes me nervous that there is a single system-wide master key, even if that is never persisted on the server side.
I note that GPG has an analogous shared access mechanism built-in. You can encrypt a file to multiple recipients, i.e. multiple public keys. A single random session key is created, and the document encrypted with a symmetric cipher. That session key is then encrypted with each of the public keys, and the whole blob forms the encrypted file. It can be decrypted by a holder of any one of the corresponding private keys.
If this mechanism were used:
* the API for "fetch secret" would just be a GET of the encrypted secret
* the decryption could be done entirely browser-side (e.g. with openPGP.js)
* there would be no single master key to worry about
* different secrets could be encrypted to different groups of people
* the encrypted secrets could be cached client side and made available even when off-line
You'd still have to trust your browser with your private key and passphrase, but it would never leave your machine.
When adding new secrets, I'd still probably POST them to the server to deal with, so the clients don't need to learn all the other GPG public keys. But the server would store only public keys, and would never handle a private key.
To me, this feels much stronger - although we can argue forever about server security versus browser security :-)
Specific limitations:
1. The encrypted secrets would be larger, depending on the number of keys they are encrypted with, and these larger objects would be sent back to the browser (typically a few KB per secret). But I don't see that as a problem; since they are plain GET objects, they would cache easily just like large javascript files.
2. If you need to add or remove a member from your team, you'd have to decrypt and re-encrypt all the secrets to the new set of keys. This requires implementing a new bulk operation. If it were done entirely server-side it would mean the server *would* need a private key for the duration of that operation - or it would need assistance from a client.
General weaknesses:
3. If you encourage client-side caching of encrypted material, arguably it opens it to client-side brute-force attacking of passphrases etc.
Of course, at the moment nothing stops people copy-pasting the unencrypted secrets into a local plain text file. You just *hope* that by making them easily available via the web, they will not feel the need to do so. Making them available encrypted off-line may actually reduce the need for people to store local unencrypted copies.
Regards,
Brian.