-
Notifications
You must be signed in to change notification settings - Fork 98
GCP SecretManager
This guide shows how to setup a KES server that uses GCP SecretManager as a persistent key store.
╔═════════════════════════════════════════════════╗
┌────────────┐ ║ ┌────────────┐ ┌───────────────────┐ ║
│ KES Client ├───────────╫──┤ KES Server ├──────────┤ GCP SecretManager │ ║
└────────────┘ ║ └────────────┘ └───────────────────┘ ║
╚═════════════════════════════════════════════════╝
The GCP SecretsManager is basically a key-value store for secrets - like passwords, access tokens and cryptographic keys.
- As initial step, login in to your GCP console and create a new project or select an existing project. Then enable the SecretManager service if it isn't enabled for your project, already.
- Once done, switch over to GCP IAM for service accounts and create a new
service account for KES. This service account will be used by KES to authenticate to GCP and access the SecretManager.
When creating the service account you can assign one or multiple roles to it. If you just want to get started quickly you can assign the
Secret Manager Admin
role. However, we recommend that you create a new role for KES with the minimal permissions required:secretmanager.secrets.create secretmanager.secrets.delete secretmanager.secrets.get secretmanager.versions.add secretmanager.versions.access
- When you have created a new service account with sufficient permissions you can create a key for the service account via
Actions
-Create Key
. Please use the JSON key format. GCP let's you download a JSON file with the following structure:The content of this credentials file will be used to configure KES such that KES can authenticate to GCP and access the SecretManager.{ "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>" }
First, we need to generate a TLS private key and certificate for our KES server. A KES server can only be run with TLS - since secure-by-default. Here we use self-signed certificates for simplicity. For a production setup we highly recommend to use a certificate signed by CA (e.g. your internal CA or a public CA like Let's Encrypt)
-
Generate a TLS private key and certificate for the KES server.
The following command will generate a new TLS private keyserver.key
and a X.509 certificateserver.cert
that is self-signed and issued for the IP127.0.0.1
and DNS namelocalhost
(as SAN). You may want to customize the command to match your setup.kes 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"
-
Then, create private key and certificate for your application:
kes identity new --key=app.key --cert=app.cert app
You can compute the
app
identity via:kes identity of app.cert
-
Now, we have defined all entities in our demo setup. Let's wire everything together by creating the config file
server-config.yml
:address: 0.0.0.0:7373 admin: identity: disabled 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
-
Finally we can start a KES server in a new window/tab:
export APP_IDENTITY=$(kes identity of app.cert) kes server --config=server-config.yml --auth=off
--auth=off
is required since our root.cert and app.cert certificates are self-signed -
In the previous window/tab we now can connect to the server by:
export KES_CLIENT_CERT=app.cert export KES_CLIENT_KEY=app.key kes key create -k my-app-key
-k
is required because we use self-signed certificatesNow, if you go to the GCP SecretManager you should see a secret key named
my-app-key
. -
Finally, we can 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>