http://weblog.rubyonrails.org/2017/2/23/Rails-5-1-beta1/
> Encrypted secrets
> If you’re checking production passwords, API keys, and other secrets undisguised into your revision control system, you’re doing it wrong. That’s not safe and you should stop it! Now that’s an easy prescription, but without a coherent answer to what you should do instead, it’s also not that helpful.
> People have long been loading up the ENV to store these secrets or used a variety of other solutions. There are all sorts of trade-offs and drawbacks to the ENV-model, not least of which that you still need to store those secrets for real somewhere else.
> Inspired by Ara T. Howard’s sekrets gem, we’ve built encrypted secrets management into Rails 5.1. You can setup a new encrypted secrets file with bin/rails secrets:setup. That’ll generate a master key you’ll store outside of the repository, but allow you to commit the actual production secrets to your revision control. They’re then decrypted in production either through an injected key file or through RAILS_MASTER_KEY in the ENV.
I'm saying it's a fully loaded foot gun.
We're doing encrypted secrets in config that get decrypt by aws kms on application startup and it's been working quite well for us.
Keeping config entirely separate from app source is the way to go. Encrypted configs is a specific version of that general anti-pattern.
Encrypted configs (and configs in source code itself) seem like a good idea at first, "I don't have to configure anything and it works in prod!" but it also means you can't flip any switches or rotate config without pushing a new version.
This also makes it difficult to stand up a parallel environment, say for reproducing a defect, as the configs are expected to be baked internally. You can't just pull out the release build and run it in a different environment with one or two variables tweaked.
> We're doing encrypted secrets in config that get decrypt by aws kms on application startup and it's been working quite well for us.
Using KMS solves the problem of where do you keep the key that locks the configs but they should still be kept externally from the app code. Depending on the scale of how you're deploying that could be a local file, an external secrets server, or just a blob on S3 (accessible via EC2 IAM roles).
For parallel environments we simply have multiple configs in repository. One per env (env.toml.prod, env.toml.jenkins, env.toml.dev-docker, ...). If you want to test a specific env you can copy and modify it. Just like you'd do it if they were on s3. I'd even argue that it's easier to debug issues if you know what code ran with what env.
Yes, you have to create a new build for each config change, but in reality code changes are much more frequent than env changes so we didn't find this being an issue at all.
If they're part of your repo and built with the app, presumably they're baked into the final tarball or whatever artifact you're composing. Modifying them would require expanding out the package, replacing or adding a file, and packaging it up again.
Compare that to having an entirely externalized setup where the application knows nothing about where it's config comes from. Switching things out is purely externally. This means that setting up a new environment can be done using the exact build aritfact that was deployed to production.
> Yes, you have to create a new build for each config change, but in reality code changes are much more frequent than env changes so we didn't find this being an issue at all.
All the more reason to keep them entirely separate. Changing code shouldn't involve changing configs and the people who have access to them aren't necessarily the same set either.
One more point on this, is if you happen to support an enterprise / on-premises use case. It'd be pretty silly to have env.tom.on-premises-customer-A, env.tom.on-premises-customer-C, env.tom.on-premises-customer-C, ... checked into source control. Yes you can have a separate package step for on-premises that cleans it up but if it's not there in the first place, you don't have to.