Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added GCP KMS option for sops encryption #38

Merged
merged 2 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Git as Terraform backend? Seriously? I know, might sound like a stupid idea at f
- [`sops`](#sops)
- [PGP](#pgp)
- [AWS KMS](#aws-kms)
- [GCP KMS](#gcp-kms)
- [Hashicorp Vault](#hashicorp-vault)
- [AES256](#aes256)
- [Running backend remotely](#running-backend-remotely)
Expand Down Expand Up @@ -221,6 +222,7 @@ We are using [`sops`](https://github.com/mozilla/sops) as encryption abstraction

- PGP
- AWS KMS
- GCP KMS
- Hashicorp Vault

Before we integrated with `sops` - we had a basic AES256 encryption via static passphrase. It is no longer recommended, although might be useful in some limited scenarios. Basic AES256 encryption is using one shared key, and it encrypts entire JSON state file that it can no longer be read as JSON. `sops` supports various encryption-as-service providers such as AWS KMS and Hashicorp Vault Transit - meaning encryption can be safely performed without revealing private key to the encryption clients. That means keys can be easily rotated, access can be easily revoked and generally it dramatically reduces chances of the key leaks.
Expand All @@ -237,6 +239,10 @@ Use `TF_BACKEND_HTTP_SOPS_PGP_FP` to provide a comma separated PGP key fingerpri

Use `TF_BACKEND_HTTP_SOPS_AWS_KMS_ARNS` to provide a comma separated list of KMS ARNs. AWS SDK will use standard [credentials provider chain](https://docs.aws.amazon.com/sdk-for-go/api/aws/credentials/) in order to automatically discover local credentials in standard `AWS_*` environment variables or `~/.aws`. You can optionally use `TF_BACKEND_HTTP_SOPS_AWS_PROFILE` to point it to a specific shared profile. You can also provide additional KMS encryption context using `TF_BACKEND_HTTP_SOPS_AWS_KMS_CONTEXT` - it is a comma separated list of `key=value` pairs.

##### GCP KMS

Use `TF_BACKEND_HTTP_SOPS_GCP_KMS_KEYS` to provide a comma separated list of GCP KMS IDs. Read [Encrypting using GCP KMS](https://github.com/getsops/sops#encrypting-using-gcp-kms) for further details.

##### Hashicorp Vault

Use `TF_BACKEND_HTTP_SOPS_HC_VAULT_URIS` to point it to the Vault Transit keys. It is a comma separated list of URLs in a form of `${VAULT_ADDR}/v1/transit/keys/key`, where `transit` is a name of Vault Transit mount and `key` is the name of the key in that mount. Under the hood Vault SDK is using standard credentials resolver to automatically discover Vault credentials in the environment, meaning you can either use `vault login` or set `VAULT_TOKEN` environment variable.
Expand Down
31 changes: 31 additions & 0 deletions crypt/sops/gcp_kms.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package sops

import (
"os"

sops "go.mozilla.org/sops/v3"
"go.mozilla.org/sops/v3/gcpkms"
)

func init() {
Configs["gcp-kms"] = &GcpKmsConfig{}
}

type GcpKmsConfig struct{}

func (c *GcpKmsConfig) IsActivated() bool {
_, ok := os.LookupEnv("TF_BACKEND_HTTP_SOPS_GCP_KMS_KEYS")
return ok
}

func (c *GcpKmsConfig) KeyGroup() (sops.KeyGroup, error) {
keys := os.Getenv("TF_BACKEND_HTTP_SOPS_GCP_KMS_KEYS")

var keyGroup sops.KeyGroup

for _, k := range gcpkms.MasterKeysFromResourceIDString(keys) {
keyGroup = append(keyGroup, k)
}

return keyGroup, nil
}