Rodi
Rodi

Reputation: 151

Where do you store secrets in Phoenix/Elixir and where is it recommended?

Do you use environmental variables or prod.secret.exs for storing passwords, api keys, etc? What's a rule of thumb for this? I feel like they're more or less the same, hence confusion of which one to use.

Note that I don't want to make it complicated by incorporating a third-party library in my code. I want a solution out of the box, preferably.

Upvotes: 7

Views: 5263

Answers (3)

Kociamber
Kociamber

Reputation: 1155

So quick and simple - for small mix / Phoenix projects I'm usually using dev/test/prod.secret.exs files and then just fetching the stuff I need with Application.get_env(:key, :value), for example - my {env}.secret.exs file could look like this:

config :my_app, api_key: "1234567890"

and then somewhere in the code:

def do_stuff do
  api_key = Application.get_env(:my_app, :api_key)
end

and of course main config file should contain an import:

import_config "#{Mix.env}.secret.exs"

What is really important - don't forget to add your secret files to .gitignore

For bigger projects where I need more security - I would go with env variables. Please check this guide.

Upvotes: 12

Kevin Thompson
Kevin Thompson

Reputation: 2506

For me it's a mix of both, and is going to depend on whether I expect that value to change during runtime. For things that stay pretty static, like API keys, I use prod.secrets.exs. The reason I use that is because then I can be consistent in the way I'm configuring my app. For everything else, I'm using the config files, and I want to do the same with my secrets. I can also put the secrets file into a different revision control system so that I've got a history of changes made to the file and by whom. I can also make it so that people who write the code don't require read access to the secrets file. At deploy time, someone who has permission to do deploys can run a script that pulls the secrets file in, and then creates a release. The release gets deployed to Amazon and the secrets are hidden. There are also error conditions that can result in an app dumping it's environment to your logging system, and all your secrets are out there in plain text.

The downside to that is that the configuration is static. Any change to the secrets means running another release. If you have a feature flag, like say DEBUG=true you don't want to run another release just to turn on debugging. That's where environment variables shine. Just change the env and your app will start debugging. BUT, if you're going to use environment variables you should put the call to System.get_env in the module where you're going to use it. I've been bitten where I put a call to System.get_env into my prod.secrets.exs file and the result is that my app is compiled with the environment variables as they existed at the time, and changes are not dynamically applied.

Upvotes: 2

Noel Llevares
Noel Llevares

Reputation: 16037

Environment Variables.

Whether it is Phoenix/Elixir or not doesn't matter.

According to a set of best practices called The Twelve-Factor App,

The twelve-factor app stores config in environment variables (often shortened to env vars or env). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard.

Reference: https://12factor.net/config

Upvotes: 7

Related Questions