Simplifying Secrets for Go

Wouldn’t it be nice to store API keys, database passwords, and private keys directly in the source code?

Of course we can’t do that, since it’s horrifyingly insecure. In the hallmark paper How Bad Can It Git Meli et al. show how secrets committed to source code can be discovered in mere seconds after they are pushed publicly.

So why does it happen so much? Because our tools make dealing with secrets basically all kinds of awful. Often we don’t have access to good tools for managing secrets. Setting up Vault or a Key Management System (KMS) takes real effort and are difficult to use correctly.

The end result is that developers commit secrets to source code because it’s the path of least resistance. And all alternatives are paths of huge resistance. To fix this problem we need to make the secure path the easy one. So what’s the ideal workflow for dealing with secrets?

Simple secret management

It should be as convenient as putting them directly in the source, but as secure as storing them in Vault or a KMS.

What if we could declare the secrets we need as simple variables? And have them automatically populated at runtime with the latest secret values?

var secrets struct {
    SSHPrivateKey string    // ed25519 private key for SSH server
    GitHubAPIToken string   // personal access token for deployments
    DatabasePassword string // for our PostgreSQL database

Then we could use them in our code just as easily as if it were stored right there in the source code. And a nice bonus is that it’s trivial to find all usages of secrets (grep for secrets.Foo). And we get nice documentation associated with all the secrets for free.

Of course, our tools don’t work this way today. But why couldn’t they?

They could. But our tools are not designed to work together. The end result is that the effort to integrate them with each other is not worth the cost you perceive of committing a secret to source code. “We’ll change the database password later”, you say to yourself.

Then time passes and a year later you get an email when your AWS account has been compromised and the attackers have run up your monthly bill to $100k and counting.

Managing secrets with Encore

But our tools could work this way. And with the latest release of Encore that we’re rolling out, they do. We’re on a mission to simplify Software Engineering and this is just the beginning. Sign up for the beta today and give it a spin.

With Encore, you define what secrets you want directly in the source code, like above. To set a secret value, use encore secret set --dev <key> from your command line. We’ll store it securely in Vault and pass it directly to your app when it starts up.

That’s how simple it should be.