Skip to content

Commit

Permalink
feat: add tink encryption migration from symmetric to envelope example (
Browse files Browse the repository at this point in the history
GoogleCloudPlatform#72)

Co-authored-by: Alessio Buraggina <[email protected]>
  • Loading branch information
romanini-ciandt and tdbhacks authored Jul 15, 2024
1 parent 8b9bf51 commit a02fedd
Show file tree
Hide file tree
Showing 10 changed files with 332 additions and 11 deletions.
26 changes: 16 additions & 10 deletions examples/tink-envelope-encryption-sample/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

locals {
temp_sa_key_file = "./sa_key.tmp"
key = "old-key"
keyring = "old-keyring"
location = "us-central1"
}

resource "local_file" "temp_sa_key_file" {
Expand All @@ -36,17 +39,20 @@ module "bootstrap" {
tink_keyset_output_file = "./encrypted_keyset"
}

// Envelope encrypt the file.
module "envelope_encrypt_file" {
source = "../../tink-envelope-encryption-sample/1-encrypt"
// Migrate from direct symmetric encryption to envelope encryption.
module "reencrypt_symmetric_to_envelope" {
source = "../../tink-envelope-encryption-sample/3-reencrypt-symmetric-to-envelope"

input_file_path = "./secret_file_sample.txt"
kek_uri = module.bootstrap.kek_uri
tink_keyset_file = module.bootstrap.tink_keyset_file
tink_sa_credentials_file = local.temp_sa_key_file
cli_path = var.cli_path
current_keyring = local.keyring
current_key = local.key
current_encrypted_file_path = "./symmetric_encrypted_file"
current_project_id = var.project_id
kek_uri = module.bootstrap.kek_uri
tink_keyset_file = module.bootstrap.tink_keyset_file
tink_sa_credentials_file = local.temp_sa_key_file
cli_path = var.cli_path

depends_on = [local_file.temp_sa_key_file, module.bootstrap]
depends_on = [local_file.temp_sa_key_file, null_resource.encrypt_symmetric, module.symmetric_kms, module.bootstrap]
}

// Decrypt the enveloped encrypted file.
Expand All @@ -58,5 +64,5 @@ module "decrypt_enveloped_file" {
encrypted_file_path = "./envelope_encrypted_file"
tink_keyset_file = module.bootstrap.tink_keyset_file

depends_on = [module.envelope_encrypt_file]
depends_on = [module.reencrypt_symmetric_to_envelope]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// This file provides all the required resources to demonstrate a encryption key changing from a symmetric encryption to envelope encryption.

module "symmetric_kms" {
source = "terraform-google-modules/kms/google"
version = "2.3.0"

keyring = local.keyring
location = local.location
project_id = var.project_id
keys = [local.key]
prevent_destroy = false
}

resource "null_resource" "encrypt_symmetric" {

provisioner "local-exec" {
when = create
command = <<EOF
gcloud kms encrypt \
--key ${local.key} \
--keyring ${local.keyring} \
--location ${local.location} \
--ciphertext-file ./symmetric_encrypted_file \
--plaintext-file ./secret_file_sample.txt \
--project ${var.project_id}
EOF
}

depends_on = [module.symmetric_kms]
}
2 changes: 1 addition & 1 deletion tink-envelope-encryption-sample/2-decrypt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ This module decrypts a file previously encrypted with envelope encryption using
terraform apply
```

1. The desired file is now decrypted.
1. The desired file is now re-encrypted.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# [3-reencrypt-symmetric-to-envelope module] Envelope encryption with Tink

## Overview

This module decrypts a file that was symmetrically encrypted using an existing GCP KMS CryptoKey, and re-encrypts it with envelope encryption using Tink and Terraform.

## Prerequisites

- [Terraform](https://developer.hashicorp.com/terraform/downloads);
- [Google Cloud CLI (`gcloud`)](https://cloud.google.com/sdk/docs/install-sdk);
- You must be authenticated in your GCP account. If you're not you should run `gcloud auth login`;
- An existing [GCP project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project) with a KMS symmetric key created;
- And a file encrypted with this KMS symmetric key;
- [Go 1.22+](https://go.dev/dl/);

## Deploy infrastructure

1. Rename `terraform.example.tfvars` to `terraform.tfvars`:
```sh
mv terraform.example.tfvars terraform.tfvars
```

1. Update `terraform.tfvars` file with the required values.

1. Create the infrastructure.

```sh
terraform init
terraform plan
terraform apply
```

1. The desired file is now decrypted.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| associated\_data | The associated data in Authenticated Encryption with Associated Data (AEAD) is used to tie ciphertext to specific associated data. Associated data is authenticated but NOT encrypted. | `string` | `"associated_data_sample"` | no |
| cli\_path | CLI base path. | `string` | `"../"` | no |
| current\_encrypted\_file\_path | Path to the symmetric encrypted file to be used. | `string` | n/a | yes |
| current\_key | Key encryption name used to symmetric encryption. | `string` | n/a | yes |
| current\_keyring | Keyring name used to symmetric encryption. | `string` | n/a | yes |
| current\_project\_id | GCP project ID of the KMS used to symmetric encryption. | `string` | n/a | yes |
| encrypted\_file\_path | Path to the encrypted file to be output by terraform. | `string` | `"./envelope_encrypted_file"` | no |
| kek\_uri | KMS Key Encryption Key (KEK) URI. | `string` | n/a | yes |
| location | Location for the resources used to symmetric encryption. | `string` | `"us-central1"` | no |
| rotate\_encrypted\_file\_path | Path to the encrypted file to be used to envelope encryption on rotation. | `string` | `"./file_to_be_envelope_encrypted"` | no |
| tink\_keyset\_file | Tink keyset file name. | `string` | n/a | yes |
| tink\_sa\_credentials\_file | Service accounts credential file path required by Tink. | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| encrypted\_file\_path | Path to the encrypted file created by terraform. |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

resource "null_resource" "decrypt_current_file" {

triggers = {
current_encrypted_file_path = var.current_encrypted_file_path
rotate_encrypted_file_path = var.rotate_encrypted_file_path
}

provisioner "local-exec" {
when = create
command = <<EOF
gcloud kms decrypt \
--key ${var.current_key} \
--keyring ${var.current_keyring} \
--location ${var.location} \
--ciphertext-file ${var.current_encrypted_file_path} \
--plaintext-file ${var.rotate_encrypted_file_path} \
--project ${var.current_project_id}
EOF
}

}

module "tink_encrypt" {
source = "../1-encrypt"

tink_keyset_file = var.tink_keyset_file
kek_uri = var.kek_uri
tink_sa_credentials_file = var.tink_sa_credentials_file
input_file_path = var.rotate_encrypted_file_path
encrypted_file_path = var.encrypted_file_path
cli_path = var.cli_path
associated_data = var.associated_data

depends_on = [null_resource.decrypt_current_file]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

output "encrypted_file_path" {
description = "Path to the encrypted file created by terraform."
value = module.tink_encrypt.encrypted_file_path
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

# You can find all these inputs values in 0-bootstrap and 1-encrypt modules outputs by running `terraform output` at the module path.

current_project_id = "REPLACE-WITH-THE-PROJECT-ID-OF-YOUR-KMS-symmetric-KEY"
current_key = "REPLACE-WITH-THE-NAME-OF-YOUR-symmetric-KEY"
current_keyring = "REPLACE-WITH-THE-NAME-OF-YOUR-symmetric-KEYRING"
current_encrypted_file_path = "REPLACE-WITH-YOUR-ENCRYPTED-FILE-PATH"
kek_uri = "REPLACE-WITH-YOUR-KEK-URI" # Format expected: "gcp-kms://projects/PROJECT-ID/locations/us-central1/keyRings/KEYRING/cryptoKeys/CRYPTOKEY"
tink_keyset_file = "REPLACE-WITH-YOUR-KEYSET-FILE-PATH"
tink_sa_credentials_file = "REPLACE-WITH-YOUR-SA-CREDENTIALS-KEY-FILE-PATH"
associated_data = "associated_data_sample"
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

variable "tink_sa_credentials_file" {
description = "Service accounts credential file path required by Tink."
type = string
}

variable "rotate_encrypted_file_path" {
description = "Path to the encrypted file to be used to envelope encryption on rotation."
type = string
default = "./file_to_be_envelope_encrypted"
}

variable "current_encrypted_file_path" {
description = "Path to the symmetric encrypted file to be used."
type = string
}

variable "cli_path" {
description = "CLI base path."
default = "../"
}

variable "associated_data" {
description = "The associated data in Authenticated Encryption with Associated Data (AEAD) is used to tie ciphertext to specific associated data. Associated data is authenticated but NOT encrypted."
default = "associated_data_sample"
}

variable "tink_keyset_file" {
description = "Tink keyset file name."
type = string
}

variable "kek_uri" {
description = "KMS Key Encryption Key (KEK) URI."
type = string
}

variable "current_project_id" {
description = "GCP project ID of the KMS used to symmetric encryption."
type = string
}

variable "location" {
description = "Location for the resources used to symmetric encryption."
type = string
default = "us-central1"
}

variable "current_keyring" {
description = "Keyring name used to symmetric encryption."
type = string
}

variable "current_key" {
description = "Key encryption name used to symmetric encryption."
type = string
}

variable "encrypted_file_path" {
description = "Path to the encrypted file to be output by terraform."
type = string
default = "./envelope_encrypted_file"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

terraform {
required_version = ">= 1.5.7"
required_providers {
null = {
source = "hashicorp/null"
version = "3.2.2"
}
}

provider_meta "google" {
module_name = "blueprints/terraform/kms-solutions:tink-envelope-encryption-sample-decrypt/v0.1.0"
}
}
6 changes: 6 additions & 0 deletions tink-envelope-encryption-sample/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ This automation has 4 terraform modules: [0-bootstrap](./0-bootstrap/README.md),

**2-decrypt** module is responsible to decrypt a file using a tink encrypted [keyset](https://developers.google.com/tink/design/keysets).

**3-reencrypt-symmetric-to-envelope** module is responsible to change a file encryption from [symmetric](https://cloud.google.com/kms/docs/encrypt-decrypt) to [envelope](https://cloud.google.com/kms/docs/client-side-encryption#envelope_encryption_with_tink) using Tink.

## Expected workflow

**Note:** First of all it's important to mention that it is possible to use all the modules individually as demand. For example, you could use directly [1-encrypt](./1-encrypt/README.md) module if you already have the existing GCP and Tink infrastructure for envelope encryption.
Expand All @@ -23,3 +25,7 @@ This automation has 4 terraform modules: [0-bootstrap](./0-bootstrap/README.md),
1. [0-bootstrap module](./consumer/0-bootstrap/README.md) execution;
2. [1-encrypt module](./1-encrypt/README.md) execution;
2. [2-decrypt module](./2-decrypt/README.md) execution;

#### Changing from symmetric encryption to Envelope encryption
1. [0-bootstrap module](./consumer/0-bootstrap/README.md) execution;
2. [3-reencrypt-symmetric-to-envelope](./3-reencrypt-symmetric-to-envelope/README.md) execution;

0 comments on commit a02fedd

Please sign in to comment.