Google Cloud Secret Manager
This tutorial shows how to setup a KES server that uses GCP Secret Manager as a persistent key store.
Google Cloud Secret Manager
The Google Cloud Secret Manager is a key-value store for secrets, such as passwords, access tokens, and cryptographic keys.
-
Login in to the GCP console
-
Create a new project or select an existing project
-
Enable the Secret Manager service if not already enabled for your project
-
Go to GCP IAM for service accounts and create a new service account for KES. KES uses this service account to authenticate to GCP and access the Secret Manager.
-
Assign one or more roles to the new account
If you want to get started quickly, assign the
Secret Manager Admin
role. However, this grants more permissions than KES needs.Alternatively, create a new role for KES with the minimal permissions required:
secretmanager.secrets.create secretmanager.secrets.delete secretmanager.secrets.get
-
Create a key for the service account via
Actions
-Create Key
.Use the
JSON
key format.GCP let’s you download a JSON file with the following structure:
{ "type": "service_account", "project_id": "<your-project-id>", "private_key_id": "<your-private-key-id>", "private_key": "-----BEGIN PRIVATE KEY-----\n ... -----END PRIVATE KEY-----\n", "client_email": "<your-service-account>@<your-project-id>.iam.gserviceaccount.com", "client_id": "<your-client-id>" }
Use this credentials file to configure KES to authenticate to GCP and access the SecretManager.
KES Server setup
The KES Server requires a TLS private key and certificate.
The KES server is secure-by-default and can only run with TLS. This tutorial uses self-signed certificates for simplicity.
-
Generate a TLS private key and certificate for the KES server
The following command generates a new TLS private key
server.key
and a self-signed X.509 certificateserver.cert
that is issued for the IP127.0.0.1
and DNS namelocalhost
(as SAN). Customize the command to match your setup.kes tool identity new --server --key server.key --cert server.cert --ip "127.0.0.1" --dns localhost
Any other tooling for X.509 certificate generation works as well. For example, you could use
openssl
:$ openssl ecparam -genkey -name prime256v1 | openssl ec -out server.key $ openssl req -new -x509 -days 30 -key server.key -out server.cert \ -subj "/C=/ST=/L=/O=/CN=localhost" -addext "subjectAltName = IP:127.0.0.1"
-
Create a private key and certificate for the application
kes tool identity new --key=app.key --cert=app.cert app
You can compute the
app
identity at any time.kes tool identity of app.cert
-
Create the config file
server-config.yml
address: 0.0.0.0:7373 root: disabled # We disable the root identity since we don't need it in this guide tls: key : server.key cert: server.cert policy: my-app: allow: - /v1/key/create/my-app* - /v1/key/generate/my-app* - /v1/key/decrypt/my-app* identities: - ${APP_IDENTITY} keystore: gcp: secretmanager: project_id: "<your-project-id>" # Use your GCP project ID credentials: client_email: "<your-client-email>" # Use the client email from your GCP credentials file client_id: "<your-client-id>" # Use the client ID from your GCP credentials file private_key_id: "<your-private-key-id" # Use the private key ID from your GCP credentials file private_key: "-----BEGIN PRIVATE KEY----- ..." # Use the private key from your GCP credentials file
-
Start a KES server in a new window/tab:
Linux
export APP_IDENTITY=$(kes tool identity of app.cert) kes server --config=server-config.yml --auth=off
The command uses--auth=off
because ourroot.cert
andapp.cert
certificates are self-signed.Containers
The following instructions use Podman to manage the containers. You can also use Docker.
Modify addresses and file paths as needed for your deployment.
sudo podman pod create \ -p 9000:9000 -p 9001:9001 -p 7373:7373 \ -v ~/minio-kes-gcp/certs:/certs \ -v ~/minio-kes-gcp/minio:/mnt/minio \ -v ~/minio-kes-gcp/config:/etc/default/ \ -n minio-kes-gcp sudo podman run -dt \ --cap-add IPC_LOCK \ --name kes-server \ --pod "minio-kes-gcp" \ -e KES_SERVER=https://127.0.0.1:7373 \ -e KES_CLIENT_KEY=/certs/kes-server.key \ -e KES_CLIENT_CERT=/certs/kes-server.cert \ quay.io/minio/kes:2024-01-11T13-09-29Z server \ --auth \ --config=/etc/default/kes-config.yaml \ sudo podman run -dt \ --name minio-server \ --pod "minio-kes-gcp" \ -e "MINIO_CONFIG_ENV_FILE=/etc/default/minio" \ quay.io/minio/minio:RELEASE.2024-01-31T20-20-33Z server \ --console-address ":9001"
You can verify the status of the containers using the following command. The command should show three pods, one for the Pod, one for KES, and one for MinIO.
sudo podman container list
-
In the other window or tab, connect to the server
export KES_CLIENT_CERT=app.cert export KES_CLIENT_KEY=app.key kes key create -k my-app-key
export APP_IDENTITY=$(kes tool identity of app.cert) kes server --config=server-config.yml --auth=off
The command uses--auth=off
because ourroot.cert
andapp.cert
certificates are self-signed.Now, if you go to the GCP Secret Manager, you should see a secret key named
my-app-key
. -
Derive and decrypt data keys from the previously created
my-app-key
kes key derive -k my-app-key { plaintext : ... ciphertext: ... }
kes key decrypt -k my-app-key <base64-ciphertext>
Using KES with a MinIO Server
MinIO Server requires KES to enable server-side data encryption.
See the KES for MinIO instruction guide for additional steps needed to use your new KES Server with a MinIO Server.
Configuration References
The following section describes the Key Encryption Service (KES) configuration settings to use Google Cloud Secret Manager as the root KMS to store external keys, such as the keys used for Server-Side Encryption on a MinIO Server.