I’d guess, nearly every developer, who assisted on releasing and go-live of his software ran into the same issue: How to deal with sensitive configuration data such as passwords, keys and tokens? Hard-coding of passwords it out since the late ’90s. Writing passwords in plain-text into config-files is as well a security breach. Encrypted passwords within config files are much better but demand you to implement some kind of encryption. Still you have then the problem: Where to put the encryption key?
There are a few approaches, how to deal with sensitive configuration data:
- No security at all (storing plaintext passwords together with your code. Not good.)
- Encrypted data (good approach)
- Separate, secured configuration data repository (good!)
- Encrypted data stored within a separate repository (best!)
Why storing sensitive data at all?
When it comes to perform dry-runs, test-runs and debugging of your application, you have for sure dependencies to external systems such as databases, web services and so on. You don’t want to spend days for searching the right credentials, building up configuration files. You want to start quickly. Therefore I see it quite important to have a convenient, easy but secure way to access sensitive data.
Encrypted data stored along with your code
John Resig posted about an in-place encryption/decryption of sensitive data. His approach is: Encrypt the sensitive stuff and check in the encrypted file. Very hand, the most important pre-requisite is to have John available for asking him for the password.
Separate configuration data repository
Git and SVN repositories aren’t that expensive today. So why don’t you create a new repository where you can store sensitive data. Then you give access to a couple of people, which are privileged for accessing the sensitive data. Sounds quite easy and convenient. It is! This way even allows you to store even more data in it: BIND DNS zones, Apache and Tomcat config and lots more. Having a versioned configuration is very valuable within Continuous Delivery. You are able to roll forward and back at any time. You have always a version history and you can find out, what changed between two changes. Still passwords are not encrypted and this causes me to feel bad.
Encrypted data provided by the Configuration Server
So let’s combine every good aspect of the approaches mentioned above and get in touch with the Configuration Server. The Configuration Server uses a SVN or Git-Repository for data storage and provides the stored configuration using HTTP and DNS-reverse lookups. Since now the Configuration Server also supports transparent encryption. You simply add one or more encryption configurations (cipher and key), encrypt values within your config and that’s it.
A big advantage of this solution is, that you keep the encrypted data very far away from the encryption algorithm and the encryption keys. This adds maximum security from data storage perspective. Yet you have one central interfaces, which handles the encryption without having the client to know about it. And how does it look like?
config.properties
username=mark url=jdbc:somedb://host/database password={aes:fdf34SFds5FGD==}
Config.properties is stored within the configuration data repository. This file is encrypted and your application would use the password “{aes:….}” to authenticate against the database. This would fail since your application has no property value decryption builtin. Therefore we’ve got to pull the config from the Configuration Server. The server config has a set of encryptions configured. These configuration id’s have to be referenced within the config to create a relationship between encrypted value and the encryption mechanism:
config.xml
<repository>
...
<security>
<encryption id="aes1">
<cipher>AES/CBC/PKCS5Padding</cipher>
<key>BTwdBhcFJd5Ls7DW82oTuQ==</key>
<ivSpec>ZB0zQr9c9LbtMHS8fgkfKA==</ivSpec>
</encryption>
</security>
...
</repository>
Now, in case you access the configuration using the Configuration Server:
GET http://my.configuration.server/dns/myArtifact/1.0.0/config.properties
you’ll get:
username=mark url=jdbc:somedb://host/database password=my secret
Cool? Then git clone https://github.com/mp911de/config-server.git
and take a look at the Configuration Server
One thing, which is on it’s way is the authentication and authorization against the Configuration Server. This is a feature on it’s way into the code and will be added in future.