Managing Secret For Your Golang Apps With The GCP Secret Manager

Razan Fawwaz
4 min readFeb 15, 2025

--

Photo by Aneta Pawlik on Unsplash

While developing a serverless application and having a secret key in JSON format, I always looked at how we store that file securely. We can’t save the JSON file in our public repository, right? ☠️

Since I plan to deploy the application using Google Cloud Run, I’ve found that Google Cloud has a Secret Manager service!

Store API keys, passwords, certificates, and sensitive data

Secret Manager is a secure and convenient storage system for API keys, passwords, certificates, and other sensitive data

- Google Cloud

With Secret Manager, we can store the credentials to the Secret Manager and integrate our application to “take” the credentials from the Secret Manager.

There are two ways to store the secret, we can use the console or CLI, for this time I will use the CLI.

For example, I have a simple Golang app that has a file called secret-key.json for authentication to database services. I want to deploy the application using Cloud Run and using the secret key that is provided so the service can communicated to the database.

I already downloaded the key and am ready to put it on Secret Manager. First of all, make sure your devices are already authenticated with your Google Cloud account.

You can log in to your account by using this command

gcloud auth login

After that, set to using your project

gcloud config set project <PROJECT_ID>

The next step is we should enable the API of the Secret Manager service. You can use this command to enable it.

gcloud services enable secretmanager.googleapis.com

If the message returns “Operation …….. finished successfully” now we’re ready to go 🚀

Now, we’re heading to the directory where we store the secret key, or you can use any directory and set it the path on the command, here is the command that we will use

gcloud secrets create <SECRET_NAME> --data-file=<SECRET_FILE_PATH>

The image below shows the results if we already created the secret in Secret Manager.

Or you can check it from the Google Cloud Console and go to the Secret Manager page.

Now this is the Go code looks alike, since we just need to read the data, the process on this code is just to retrieve the secret. You should fill out the GOOGLE_CLOUD_PROJECT_NUMBER you can hardcode it or use OS Env.

package main

import (
"context"
"log"

secretsmanager "cloud.google.com/go/secretmanager/apiv1"
"cloud.google.com/go/secretmanager/apiv1/secretmanagerpb"
)

func main() {
projectNumber := os.Getenv("GOOGLE_CLOUD_PROJECT_NUMBER")
secretName := os.Getenv("SECRET_NAME")

ctx := context.Background()
client, err := secretsmanager.NewClient(ctx)
if err != nil {
log.Fatalf("failed to setup client: %v", err)
}
defer client.Close()

accessRequest := &secretmanagerpb.AccessSecretVersionRequest{
Name: "projects/" + projectNumber + "/secrets/" + secretName + "/versions/latest",
}

result, err := client.AccessSecretVersion(ctx, accessRequest)
if err != nil {
log.Fatalf("failed to access secret version: %v", err)
}

secret := string(result.Payload.Data)

log.Printf("secret: %s", secret)
}

While running it locally, don’t forget to authenticate the program with the Google Cloud Project by using this command. For more reference, you can check this out.

gcloud auth application-default login

Then, you can run the program using go run main.go and here we go, this is the secret that we stored it before!

If you want to deploy it to Cloud Run, you can try this code

package main

import (
"context"
"fmt"
"log"
"net/http"
"os"

secretsmanager "cloud.google.com/go/secretmanager/apiv1"
"cloud.google.com/go/secretmanager/apiv1/secretmanagerpb"
)

func main() {
projectNumber := os.Getenv("GOOGLE_CLOUD_PROJECT_NUMBER")
secretName := os.Getenv("SECRET_NAME")

ctx := context.Background()
client, err := secretsmanager.NewClient(ctx)
if err != nil {
log.Fatalf("failed to setup client: %v", err)
}
defer client.Close()

accessRequest := &secretmanagerpb.AccessSecretVersionRequest{
Name: "projects/" + projectNumber + "/secrets/" + secretName + "/versions/latest",
}

result, err := client.AccessSecretVersion(ctx, accessRequest)
if err != nil {
log.Fatalf("failed to access secret version: %v", err)
}

secret := string(result.Payload.Data)

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Your secret is: %s", secret)
})

log.Fatal(http.ListenAndServe(":8080", nil))
}

Don’t forget to put the Env Variables while setting up the Cloud Run deployment.

If the deployment succeeds, you can try to call the “/” endpoint and it will return the secret key that we need.

Additionally, if the Cloud Run needs access to the Secret Manager, you can go to the Secret Manager and give access to your Cloud Run Service Account by clicking Add Principal.

That’s all! 🚀 Thanks for reading!

--

--

Razan Fawwaz
Razan Fawwaz

Written by Razan Fawwaz

Interested in Backend & Infra | Technology Management Trainee (Backend) @EDTS | Kuli Ketik @SendTheSong

No responses yet