Problem Statement 😬:
When developing an application, we require external dependencies, for example, a database, cache store, an object storage (AWS S3) and so on. Often times, these services contain private data and should never be exposed to the public, making handling credentials to these external services securely a priority. You don't want your credentials to your database sitting in plain sight in your codebase which is checked in to your code repository, available for anyone who has access to your codebase (or just about anyone if your repository is set to public) to view. So setting your application's configurations as simple constants in your codebase is never a good idea.
There are a couple of ways to solve this problem.
Storing configurations in a separate file
This approach has you creating a file, separate from your main codebase (config.yml
for example) and storing it in a private server or a private repository, accessible only by those who are responsible for setting up and maintaining these external dependencies.
But there are also some problems with this approach!
It is easy to mistakenly check in the config file to your repository!
In a microservice architecture, these configuration files could be scattered everywhere and doesn't follow a standard format making it difficult to manage
Storing configurations in environment variables
With this approach, we simply set our credentials in the environment. All we have to do then, is to reference these variables in our codebase
package main
conn := os.getEnv("POSTGRES")
db, err := sql.Open("postgres", conn)
This approach can potentially solve some of the problems mentioned in the previous step (Storing configs in separate files)
There is little chance that these credentials will be checked into our repository and definitely safer than storing them as constants.
We may have a single point of managing these credentials, but still has the potential for human error with no standard naming format.
Other solutions...
AWS Secrets could be a good fit if you are already hosting on AWS. They provide APIs to manage, retrieve, and rotate database credentials, API keys, and other secrets throughout their lifecycles
A more "advanced" way of handling application configuration is to use ETCD as our main storage for credentials. ETCD is a key/value store and is highly available by design. We could expose a user interface for developers to configure these credentials, which would store them in our ETCD clusters where our application would read from.
Although this step requires some development time, it should reduce the problems mentioned above.
But as always, we have to identify the trade-offs present in all scenarios and based on our requirements, choose the solution that fits us best.
These are a few options I have used to handle application configuration and i hope you find it useful!
Please add a comment if you see anything that can be improved!👍
Top comments (0)