Storing Secrets Securely for Go Cloud Applications πŸ”‘

marcuskohlberg

Marcus Kohlberg

Posted on October 26, 2023

Storing Secrets Securely for Go Cloud Applications πŸ”‘

✨ Let's learn how to secure a Go app

πŸ€” Wouldn't it be nice to store secret values like API keys, database passwords, and private keys, directly in the source code?

Of course, we can’t do that, it's horrifyingly insecure!
(Unfortunately, it's also very common.)

Encore's secrets manager makes it simple to store secrets securely, and lets you use them in your program like regular variables.

In this guide, we'll show you how!πŸ”‘

πŸ’½ Install Encore

Install the Encore CLI to run your local environment:

  • macOS: brew install encoredev/tap/encore
  • Linux: curl -L https://encore.dev/install.sh | bash
  • Windows: iwr https://encore.dev/install.ps1 | iex

πŸ›  Create an app

A common use case for storing secrets is when using a third-party API.

As an example, ElevenLabs offers a cool API for generating voices using AI.

To use it, let's create a new Encore application with this command and select the Empty app template:

encore app create
Enter fullscreen mode Exit fullscreen mode

πŸ’Ύ Download the ElevenLabs package

  1. Download the elevenlabs package from https://github.com/encoredev/examples/tree/main/bits/elevenlabs (link) and add it to the app directory you just created.
  2. Sync your project dependencies by running go mod tidy. (Note: This requires that you have Go 1.21, or later, installed.)

Notice how the program uses ElevenLabsAPIKey as a regular variable, that's because Encore takes of supplying the secret from Encore's secret manager. But first, we need to store an API key.

πŸ”‘ Get your API Key and store it in Encore's secrets manager

Get your API key from ElevenLabs by signing up for a free account at https://elevenlabs.io.

Once you have the API key, save it as a secret using Encore's secret manager with the name ElevenLabsAPIKey, by running:

encore secret set --type dev,prod,local,pr ElevenLabsAPIKey
Enter fullscreen mode Exit fullscreen mode

🏁 Run your app locally

Start your application locally by running:

encore run
Enter fullscreen mode Exit fullscreen mode

You can now open Encore's local development dashboard at http://localhost:9400 to see your app's API documentation, call the API using the API explorer and view traces, and more.

Encore local dev dash

πŸ•Ή Try out the API

Now let's play around a bit with our shiny new API integration!

From the API Explorer in the local development dashboard, try calling the elevenlabs.DownloadAudio endpoint with the text input of your choice in the request body.

API Explorer

This will use the API to generate an MP3 audio file and download it to your app root folder: speech.mp3.

If you see the file, it means your API integration works and you securely used your API key. Congratulations!πŸŽ‰

πŸ€” How it works: Using secrets in your Encore application

Ok, so we know that it works. But how does it work? Let's take a deeper look!

When using a secret in your application, you define it directly in your code by creating an unexported struct named secrets, where all fields are of type string. For example:

var secrets struct {
    SSHPrivateKey string    // ed25519 private key for SSH server
    GitHubAPIToken string   // personal access token for deployments
    // ...
}
Enter fullscreen mode Exit fullscreen mode

When you've defined secrets in your program, the Encore compiler will check that they are set before running or deploying your application. If a secret is not set, you will get a compilation error notifying you that a secret value is missing.

Once you've provided values for all secrets, you can just use them in your application like a regular variable. For example:

func callGitHub(ctx context.Context) {
    req, _ := http.NewRequestWithContext(ctx, "GET", "https:///api.github.com/user", nil)
    req.Header.Add("Authorization", "token " + secrets.GitHubAPIToken)
    resp, err := http.DefaultClient.Do(req)
    // ... handle err and resp
}
Enter fullscreen mode Exit fullscreen mode

πŸ€” How it works: Saving secret values

Using the Cloud Dashboard

The simplest way to set up secrets is with the Secrets Manager in the Encore Cloud Dashboard. Open your app in app.encore.dev, go to Settings in the main navigation, and then click on Secrets in the settings menu.

From there you can create secrets, save secret values, and configure different values for different environments.

Encore's secrets manager

Using the CLI

If you prefer, you can also set up secrets from the CLI using: encore secret set --type <types> <secret-name>

<types> defines which environment types the secret value applies to. Use a comma-separated list of production, development, preview, and local. Shorthands: prod, dev, pr.

For example encore secret set --type prod SSHPrivateKey sets the secret value for production environments,
and encore secret set --type dev,preview,local GitHubAPIToken sets the secret value for development, preview, and local environments.

In some cases it can be useful to define a secret for a specific environment instead of an environment type.
You can do so with encore secret set --env <env-name> <secret-name>. Secret values for specific environments
take precedence over values for environment types.

Environment settings

Each secret can only have one secret value for each environment type. For example: If you have a secret value that's shared between development, preview and local, and you want to override the value for local, you must first edit the existing secret and remove local using the Secrets Manager in the Cloud Dashboard. You can then add a new secret value for local. The end result should look something like the picture below.

Overriding a secret

πŸ€” How it works: Where are secrets stored?

When you store a secret Encore stores it encrypted using Google Cloud Platform's Key Management Service (KMS).

  • Production / Your own cloud: When you deploy to production using your own cloud account on GCP or AWS, Encore provisions a secrets manager in your account (using either KMS or AWS Secrets Manager) and replicates your secrets to it. The secrets are then injected into the container using secret environment variables.
  • Local: For local secrets Encore automatically replicates them to developers' machines when running encore run.
  • Development / Encore Cloud: Environments on Encore's development cloud (running on GCP under the hood) work the same as self-hosted GCP environments, using GCP Secrets Manager. ## πŸš€ Bonus: Deploy to the cloud

If you want to deploy your app to a free cloud environment in Encore's development cloud, simply run:

git add -A .
git commit -m 'Initial commit'
git push encore
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ Then head over to the Cloud Dashboard to monitor your deployment and find your production URL by going the overview page for the environment you just created. It will be something like: https://staging-[APP-ID].encr.app.

Environment overview

πŸŽ‰ Great job - you're running in the cloud!

Great job! You now have an AI-powered app running in the cloud.

Keep building with Encore using these Open Source App Templates. πŸ‘ˆ

If you have questions or want to share your work, join the developer hangout in Encore's community Slack. πŸ‘ˆ

Learn More

πŸ’– πŸ’ͺ πŸ™… 🚩
marcuskohlberg
Marcus Kohlberg

Posted on October 26, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related