Your service should not run as root
generally. Using a separate user to store the secret is a wise precaution, but storing files with root
ownership is no better for secrecy than using another dedicated user for this. As long as your secret file has permissions 600
or less it will be safe from other non-root
users. Anything running root
has full access anyway. (unless you are running some complex SELinux setup)
It may be helpful to use two users for this single application to isolate secret management from normal operation. Either have two daemons running with real-time communications, or have utility commands to operate on the secret, gaining the necessary privilege (user or group-based) via sudo
.
You should consider potential attack vectors.
SQLi if properly configured does not grant filesystem access, but Path Traversal attacks could. There are other types of attacks on your application that you should secure against.
Exploits in C libraries (i.e. OpenSSL running your HTTPS encryption, image processing, etc.) might be possible. Using a separated user on network-exposed processes can help limit the scope or add difficulty to an attack.
Break-ins from other attack vectors could be an issue. (SSH, other services on the machine) Make sure anything with the potential for root
access is well secured.
All of these considerations should help you to secure the secret itself. Now the question is, does the secret really need to be stored in plain?
At the most basic level, yes, the secret must be stored somewhere for it to be usable. It at least has to be stored in Memory, but also permanent storage of some kind is necessary.
Beyond of user separation we've discussed, it could be helpful to off-load secrets to a separate Hardware Security Module, or even a separate mini-computer. (i.e. Raspberry Pi) There is some discussion of physical separation here.
There are very few cases where the secret can be encrypted itself in permanent storage.
If your concern is hard drive theft, (leaving the rest of the machine behind) then you could have a boot-up script that queries some of the other hardware for unique identifiers, and derives an encryption key using a good Password-Based Key Derivation Function; to decrypt the secret.
If the client can provide a portion of the secret, that would be the helpful. I've outline a way to derive decryption keys from user passwords and session tokens here. This is an elaborate yet effective system which focuses on limiting the amount of time a secret is stored, even in Memory. (assuming you do not require an automated password reset)