I think that most discussion I see around protecting API keys, SSH certificates, token signing private keys seems to be in one of two focuses:
-
Avoiding having the private secrets shared accidentally in code backups like GitHub or when sharing your code with others for review or group work.
-
Ensuring an attacker on your server cannot steal these codes if they compromise your server.
Realistically from what I can tell though only #1 is all that meaningful in practical circumstances. And #1 is very easy to do just with basic caution. For example, if you put your keys and files in a /priv
folder and then just .gitignore
this. Plus just be mindful not to share it with anyone by accident.
Perhaps that is not an “organization level solution” but if you are solo or even likely small team developing it is simple enough.
Regarding #2, I am not sure what is practical to consider here. For example, you can instead set the keys/secrets into the configuration file of Elixir directly. You can set them into the DockerFile directly if using that. But in both cases, you are still hardcoding the keys in so what does it matter? Anything else I see that is not overly burdensome just seems to be adding more complexity for no objective improvement in safety.
If someone hypothetically completely hacks your server, ie. can (1) SSH into it and access the file structure say of Linux or whatever OS or (2) run any commands on Elixir due to some vulnerability, then what does it make a difference?
If they are running iex
style commands on your live server somehow, they could hypothetically navigate your file structure and read files easily enough. So this would not be good for stored files. Environmental variables would also not be good. Ironically, I think having things stored as private constants like @key
would actually be safest if this was the case, assuming no public getter functions on any modules.
If they have full file access to the entire system at the OS level, they can presumably copy off all your server code and analyze it. If so, whether things are coded into the DockerFile or the priv folder or the config, it makes no realistic difference at that point, right?
If that is the case, then the only way to truly improve security further is to not store any keys on the server in any form. In which case, if you want an automated start up, the server has to request the keys from somewhere. But then the server must have a key to request the keys from that place, and once that key to the keys is captured you are back to square one.
You can also manually enter the keys from command line when you start the server. Then they would live only in the Elixir memory which seems safest. But if there are 5-6 keys or more for various things, every time you start or restart a node you will have to manually copy and paste all these in. I would speculate that if someone has OS level access without your knowledge, they could perhaps hypothetically install and run a keylogger that would catch these anyway just the same, though this is getting abstract.
Either way, if you want the system to be able to handle automatic restarts (eg. if OS crashes or whatever) you have lost this now. If you are away from your computer when something goes wrong, who is going to copy and paste those codes in to restart it?
I am not used to working on servers or the security issues associated with them. I am just wondering what you all think about this or if I have it roughly correct. Some things increase security I think and some things just add more complexity for primarily the illusion of security. I feel it is not worth wasting time on the latter.
I suspect there is only so much that is meaningful and practical. What do you think?
What is the practical concern here and what are we actually accomplishing?