Golang: Using secret environment variables in TOML

Date: 2019-01-07 | tutorial | toml | golang | environment-variables |

Problem

I'm creating a Golang project that relies on an api key to function properly. I want my code to be public so that others can use it, but want to keep my api key hidden so that I'm not paying for random people's usage. How can I do this?

Solution

To get both the common functionality of your code while retaining obscurity for your sensitive api key, the standard is to create and maintain a separate environment variable file that your program reads in as part of execution. This does mean that there will be a necessary piece of your program that exists outside of source control, but proper documentation (in-code and in-repo) should make recreation of the file from scratch relatively easy in the event of deletion/loss.

Directory structure:

  • my-project/
    • secrets.toml - holds secrets in TOML
    • my-program.go - reads in the secrets

We'll be using the TOML file type as it's super simple and hard to get wrong. The package BurntSushi/toml will help us read in these files and is open source if you want to take a look under the hood.

// secrets.toml

secret_api_key = "manysecretthingshere"
// my-program.go

package main
import (
    "fmt"
    "github.com/BurntSushi/toml"
)

func main() {
    pathToSecretFile := "secrets.toml"

    var environmentVariables EnvironmentVariables
    if _, err := toml.DecodeFile(
        pathToSecretFile,
        &environmentVariables); err != nil {
		panic(err)
	}

    fmt.Printf("Secret key: %#v", environmentVariables.Secret_api_key)
}

// BurntSushi/toml requires a struct to
// model the form of the secrets in
// order to read properly
type EnvironmentVariables struct {
    // The struct and properties must both be public
    // in order for BurntSushi/toml to reference them
    Secret_api_key string
}

Want more like this?

The best / easiest way to support my work is by subscribing for future updates and sharing with your network.