Where do you store you credentials like secret key , mail passwords, db passwords?
I made a post on https://security.stackexchange.com/questions/19785/security-conce
ad. 3: In Play application.conf
is not accesible via any route
or other kind of path
so it can not be considered as 'placed in webroot'. Terry's advice is proper in PHP, but doesn't fit to Play (he warned, that he don't know the framework of course). He gives a sample of PHP script, but believe me, the diffrence between access to http://somdomain.tld/config.php
and Play's conf/application.conf
is huge. They can't be compared directly.
Storing credentials in application.conf
is the safest (and fastest) way for now, I can't imagine a way to decompile the file in browser even if parser would die (which isn't possible as it's not PHP). If you'll decide to store credentials in some distant location, you'll gain the new risk, as you will need to additionally check if client has permissions to get the config, time required for application's start will rise etc, etc.
Update 1:
Using environment variables is not a secure way - as Marius pointed, it will appear in the process list, so you will show your credentials to each admin and I'm pretty sure that you don't want do that with ie. your email.
In Heroku of course it's a way for passing their DB connection URL, but other credentials should be stored in config file. Finally remember that Procfile command length is limited to 255 chars, so placing all credential in it will cause, that your app won't start some day.
Resolution in this case is using alernative configuration files, scenario is quite simple
application.conf
keep an URL to your production database If it's Heroku most probably db.default.user
and db.default.password
should be commented as common heroku URL contains credentials in it.conf/local_postgres.conf
include application.conf at the beginning and override/add all required configuration keys like credentials to your local Postgres DB. Additionally you can set there other things, change logging levels, enable smtp.mock
, etc.Run your app locally with this conf. (note, I had some problem with -Dconfig.resource
so I had to use -Dconfig.file
syntax instead, you have to find which method will be working good in your system) ie.
play -Dconfig.resource=local_postgres.conf "~run 9123"
Tip: Using non default port is the easiest way to "demonstrate" that you're working with local config. If you'll forget that you have alternative config and will start your app with common play ~run
command, your app in location http://localhost:9123
will be just unavailable.
Create a bash script run-local
(or run-local.bat
file in Windows) and place there command from previous point. Ignore it in .gitignore
file.
From now you'll be running the application for local development with the script from point 4. While pushing to Heroku it will deploy your app with values from application.conf
as you don't set alternative config in the Procfile. What's more with some other combinations you can run locally your application with Heroku's SQL to perform evolutions without pushing it to deployment, or check newest fix-pack. Of course you have to always make sure that you're developing on the local version of database, otherwise there's a risk that you accidentally change/destroy your life data.
Update 2:
Finally using *.conf
files is better than storing it in separate classes in case when you have to change configuration for different locations (as mentioned yet, team working on the same code, dev/prod environments etc.)
Of course can be shortened to:
import play.Configuration;
import play.Play;
// ...
Configuration cfg = Play.application().configuration();
cfg.getString("smtp.password");
cfg.getBoolean("smtp.mock");
cfg.getInt("smtp.port");
application.conf
supports environment variables, e.g. db.default.user=${DB_USER}
. You can pass it as a console parameter (which is not safe since it appears in ps
), or more safely set it as an environment variable.
On Heroku, set the environment variable via heroku config
, e.g. heroku config:add DB_USER=MyDBAdmin
.
Locally you can set them via export DB_USER=MyDBAdmin
, or add them to your ~/.bash_profile
(if you use bash).