How to securely pass secrets to an application
I have an application exposing a REST API which needs some secrets to launch, like database password, p12 keystore password or HS512 secret for issuing tokens. Those values are extracted from application environment. I will be deploying the app to AWS EC2. I've come up with 4 options to pass those values:
- As environment variables passed with the switch to
java
command - this would be very inconvenient - Create a bash script with hard coded passwords stored in plain text which executes the
java
command - that would make them available for anyone who connects to the EC2 instance. - Same as above but instead of storing secrets in plain text, encrypt them with a symmetric key and make the script prompt for it and run the application with decrypted values.
- AWS secret manager - that seems to be an overkill for a simple web app and also introduces costs.
What is the right way to do this? Does option 3 even make sense?
-
Options 1 and 2 - it's never a good idea to have any secrets hardcoded or bundled with your application.
-
Option 3 - that's much better, but what are you going to do with the decrypted values? Store them to a properties file? Well then they become accessible to anyone who connects to the EC2 as well. Even if you pass the secrets through the environment vars they can still be read from
/proc/$PID/environ
by anyone who's got enough privs to open that file. -
Option 4 - although it comes with a small cost ($0.40/month) it's the best way. The app can talk directly to Secrets Manager to retrieve the secrets using EC2 instance role and can use them without storing them in any intermediate files or environment vars.
The trouble is that anyone who gets access to the instance can also use the same EC2 role to read the Secret from SSM.
The bottom line is - don't let anyone untrusted access the instance. If the app can somehow obtain the secrets so can anyone who's got admin (root) access to the instance. There's hardly any way around it.
There is an Option 5 - store them encrypted in Parameter Store if you think that the cost associated with Secrets Manager is too high.
Everything said my @MLu for Option 5 applies to Option 4 as well.
Secrets Manager comes with the option to automatically rotate the secrets every X days which could be also useful.
Some links on the topic:
- https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html
- https://aws.amazon.com/blogs/apn/how-helecloud-used-aws-secrets-manager-to-automate-credentials-rotation-of-ms-sql-on-amazon-ec2/