How do you manage config files containing secrets like passwords and API keys?

I’m curious how you handle secrets in your production Erlang/OTP application configuration. I do see this other thread about the configs in general, but I’m more curious about the secrets here. I would also like to know what libraries/dependencies/services/tools you use, especially if you pick one of the latter options, if you’re willing and able to share. Finally, feel free to share recommended best practices and associated tools in the comments too, even if you don’t currently follow them, but perhaps wish you did.

  • Secrets? What are those? Information wants to be free! I store everything plain text, then include everything needed in config files and ship it along with the release.
  • Secrets are stored encrypted elsewhere. Config file is a template. Secrets get retrieved, decrypted and substituted in the config file during the release process. Secrets are included in plain text with the release.
  • Secrets are stored encrypted elsewhere. They aren’t included in the release. They get retrieved, decrypted and stored on the host disk or elsewhere on the host before the application starts.
  • Secrets are stored encrypted elsewhere. They get retrieved and decrypted by the application during its startup or as needed. They are only decrypted in application memory and aren’t otherwise stored decrypted anywhere else.

0 voters

At various points, I’ve handled secrets in the following ways:

  • Retrieving from Hashicorp Vault, using a library I wrote: GitHub - rkallos/canal: HashiCorp Vault client written in Erlang. This was written at a previous job, and I haven’t really maintained it since. On the bright side, Vault was easy to work with, and it replaced N secrets with 1 secret (the credentials to retrieve secrets from Vault)
  • Generating a config file at release time that exists in plain-text on the server. Usually this config file would be a shell script that exports environment variables containing the secrets, and the Erlang application is started with those environment variables. It works well for secrets that rarely change.
  • Environment variables are created via orchestration software (e.g. k8s). What’s nice about this is that the secrets can be stored somewhere like AWS Secrets Manager, and the Erlang application doesn’t need to care; since it’s the orchestrator’s responsibility to fetch and provide the secrets. However, the use of environment variables means that pods ought to be restarted when the secret values change, which can be cumbersome for stateful applications.