Skip to content

sue445/gcp-kmsenv

Repository files navigation

gcp-kmsenv

Detect variable from environment variable or GCP Cloud KMS.

You can access KMS with a syntax similar to os.Getenv

Latest Version Build Status Coverage Status Maintainability GoDoc Go Report Card

Requirements

Base64 encoded ciphertext

Encrypt credential with gcloud kms encrypt and convert with base64.

e.g.

echo -n SECRET_ACCESS_TOKEN | gcloud --project PROJECT_NAME kms encrypt --plaintext-file=- --ciphertext-file=- --location=global --keyring=KEY_RING_NAME --key=KEY_NAME | base64

After that, register with the environment variable starting with KMS_. (e.g. KMS_ACCESS_TOKEN )

Service account

Add IAM role roles/cloudkms.cryptoKeyDecrypter to service account if necessary.

Example

export SOME_KEY="env_value"
export KMS_ACCESS_TOKEN="base64_encoded_ciphertext"
package main

import "github.com/sue445/gcp-kmsenv"

func main() {
    keyringKeyName := "projects/PROJECT_NAME/locations/global/keyRings/KEY_RING_NAME/cryptoKeys/KEY_NAME"
    k, err := kmsenv.NewKmsEnv(keyringKeyName)
    if err != nil {
        panic(err)
    }

    // get from environment variable
    value, err := k.GetFromEnvOrKms("SOME_KEY", false)
    // => "env_value"

    // get and decrypt from KMS
    // NOTE. prefix `KMS_` is needless
    access_token, err := k.GetFromEnvOrKms("ACCESS_TOKEN", false)
    // => "SECRET_ACCESS_TOKEN"

    // When key is not found in both environment variable and KMS, returned empty string (not error)
    value, err := k.GetFromEnvOrKms("INVALID_KEY", false)
    // => ""

    // When key is not found in both environment variable and KMS, returned error
    value, err := k.GetFromEnvOrKms("INVALID_KEY", true)
    // => error
}

ProTip

Securely embed secret values in app.yaml for Google App Engine

# app.yaml
runtime: go113

env_variables:
  KMS_ACCESS_TOKEN: "THIS_IS_BASE64_ENCODED_CIPHER_TEXT"

Development

cp .envrc .envrc.example
vi .envrc