Encrypt Metadata and Data Source Credentials

Data source credentials and organization’s OIDC client secrets are vital pieces of metadata that must be safeguarded. While in GoodData Cloud we ensure your credentials are encrypted and stored securely on our end, in GoodData.CN the responsibility falls on the deployment administrator. This article explains how to secure your data source credentials in GoodData.CN.

We use the Google Tink library to encrypt this metadata using AES256-GCM authenticated encryption with associated data, with the keyset passed as a metadata-api service configuration parameter.

Follow these steps to ensure your data source credentials stored in GoodData.CN are encrypted:

  1. Create and Manage Keysets
  2. Configure Helm Chart

Create and Manage Keysets

Google Tink provides a key management tool, Tinkey. Use Tinkey to manage your keys.

Install Tinkey

Download and extract the Tinkey key management tool:

curl -fsL https://storage.googleapis.com/tinkey/tinkey-1.9.0.tar.gz | tar xzvf -

Create New Keyset

Generate a new keyset, with one key set as primary and enabled:

tinkey create-keyset --key-template AES256_GCM --out gdcn-keyset.json

Keep the Keyset Safe

Keep the encryption keyset in a secure location and back it up alongside your database backups. If the keyset is lost, you will not be able to decrypt metadata values.

You can now configure the Helm chart.

Inspect a Keyset

To view the keys in a keyset and see which one is primary:

tinkey list-keyset --in gdcn-keyset.json
primary_key_id: 343627806
key_info {
  type_url: "type.googleapis.com/google.crypto.tink.AesGcmKey"
  status: ENABLED
  key_id: 1088398113
  output_prefix_type: TINK
}
key_info {
  type_url: "type.googleapis.com/google.crypto.tink.AesGcmKey"
  status: ENABLED
  key_id: 343627806
  output_prefix_type: TINK
}

Rotate Keysets

See Rotate Encryption Keys.

Configure Helm Chart

Once you have your Tink keyset, update the following parameters in the helm chart options for GoodData.CN to enable the encryption of data source credentials in your GoodData.CN deployment:

metadataApi.encryptor.enabled

Enable or disable the use of encryption for your data source credentials. Enabled by default.

Encryption is Irreversible!

Be aware that once you enable encryption, your credentials become irreversibly encrypted. If you later change the metadataApi.encryptor.enabled setting from true to false, your GoodData.CN deployment will become unusable. To restore functionality, you will need to update all secrets via the API to store them in an unencrypted format. Additionally, because OAuth2 client credentials are also encrypted, users will lose access to the UI. However, token authentication will remain functional.

metadataApi.encryptor.existingSecret

Store your Tink keyset in a Kubernetes Secret and reference the Secret name here. The Secret must live in the release namespace and hold the keyset under the data key keySet. That key name is fixed: metadata-api and every other service that reads encrypted metadata mounts the keyset from the keySet data key, so a Secret that stores it under any other name makes those pods fail to start.

Create the Secret from the keyset file you generated with Tinkey:

kubectl -n gooddata-cn create secret generic gdcn-encryption --from-file=keySet=gdcn-keyset.json

Then reference it in your values:

metadataApi:
  encryptor:
    enabled: true
    existingSecret: gdcn-encryption

metadataApi.encryptor.keySet

Alternatively, store the contents of the Tink keyset as plain text here. The chart then creates the Secret for you and puts the value under the same keySet data key.

For security reasons we recommend you store your keyset using a secret. In case both existingSecret and keySet fields are populated, the backend will use existingSecret.

Note that if the encryption is enabled, but no keyset is provided, the metadata-api deployment will fail.

Encrypt Existing Credentials

If you enable encryption on a deployment that already stores credentials, or you install a different keyset, re-encrypt the stored credentials by calling the reencrypt actuator endpoint:

kubectl -n gooddata-cn exec -c metadata-api deployments/gooddata-cn-metadata-api -- curl -X POST -v http://localhost:9008/actuator/reencrypt

The same call is part of the key rotation procedure.