{"id":15221911,"url":"https://github.com/googlecloudplatform/k8s-cloudkms-plugin","last_synced_at":"2025-08-09T01:41:48.087Z","repository":{"id":30867198,"uuid":"123325995","full_name":"GoogleCloudPlatform/k8s-cloudkms-plugin","owner":"GoogleCloudPlatform","description":"K8S KMS Plugin for Google CloudKMS","archived":false,"fork":false,"pushed_at":"2025-03-13T01:43:06.000Z","size":5227,"stargazers_count":56,"open_issues_count":2,"forks_count":13,"subscribers_count":30,"default_branch":"main","last_synced_at":"2025-04-09T20:08:03.812Z","etag":null,"topics":["google-cloudkms","kms","kubernetes"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GoogleCloudPlatform.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-28T18:35:45.000Z","updated_at":"2025-02-07T09:30:02.000Z","dependencies_parsed_at":"2024-12-27T02:06:33.202Z","dependency_job_id":"34b7aacf-d490-4fbc-9487-63a25fe78d64","html_url":"https://github.com/GoogleCloudPlatform/k8s-cloudkms-plugin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fk8s-cloudkms-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fk8s-cloudkms-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fk8s-cloudkms-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fk8s-cloudkms-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GoogleCloudPlatform","download_url":"https://codeload.github.com/GoogleCloudPlatform/k8s-cloudkms-plugin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248103872,"owners_count":21048245,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["google-cloudkms","kms","kubernetes"],"created_at":"2024-09-28T15:08:50.448Z","updated_at":"2025-04-09T20:08:08.298Z","avatar_url":"https://github.com/GoogleCloudPlatform.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kubernetes KMS Plugin for Cloud KMS\n\nThis repo contains an implementation of a [Kubernetes KMS Plugin][k8s-kms-plugin] for [Cloud KMS][gcp-kms].\n\n**If you are running on Kubernetes Engine (GKE), you do not need this plugin. You can enable [Application-layer Secrets Encryption][gke-secrets-docs] and GKE will manage the communication between GKE and KMS automatically.**\n\n\n## Use with Compute Engine\n\nIf you are running Kubernetes on VMs, the configuration is logically divided into the following stages. These steps are specific to Compute Engine (GCE), but could be expanded to any VM-based machine.\n\n1. Create Cloud KMS Keys\n1. Grant service account IAM permissions on Cloud KMS keys\n1. Deploy the KMS plugin binary to the Kubernetes master nodes\n1. Create Kubernetes encryption configuration\n\n### Assumptions\n\nThis guide makes a few assumptions:\n\n* You have gcloud and the [Cloud SDK][cloud-sdk] installed locally. Alternatively you can run in [Cloud Shell][cloud-shell] where these tools are already installed.\n\n* You have [billing enabled][gcp-billing] on your project. This project uses Cloud KMS, and you will not be able to use Cloud KMS without billing enabled on your project. Even if you are on a free trial, you will need to enable billing (your trial credits will still be used first).\n\n* The Cloud KMS keys exist in the same project where the GCE VMs are running. This is not a hard requirement (in fact, you may want to separate them depending on your security posture and threat model adhering to the principle of separation of duties), but this guide assumes they are in the same project for simplicity.\n\n* The VMs that run the Kubernetes masters run with [dedicated Service Account][dedicated-sa] to follow the principle of least privilege. The dedicated service account will be given permission to encrypt/decrypt data using a Cloud KMS key.\n\n* The KMS plugin will share its security context with the underlying VM. Even though principle of least privilege advocates for a dedicated service account for the KMS plugin, doing so breaks the threat model since it forces you to store a service account key on disk. An attacker with access to an offline VM image would therefore decrypt the contents of etcd offline by leveraging the service account stored on the image. GCE VM service accounts are not stored on disk and therefore do not share this same threat vector.\n\n### Set environment variables\n\nSet the following environment variables to your values:\n\n```sh\n# The ID of the project. Please note that this is the ID, not the NAME of the\n# project. In some cases they are the same, but they can be different. Run\n# `gcloud projects list` and choose the value in \"project id\" column.\nPROJECT_ID=\"\u003cproject id\u003e\"\n\n# The FQDN email of the service account that will be attached to the VMs which\n# run the Kubernetes master nodes.\nSERVICE_ACCOUNT_EMAIL=\"\u003cservice-account email\u003e\"\n\n# These values correspond to the KMS key. KMS crypto keys belong to a key ring\n# which belong to a location. For a full list of locations, run\n# `gcloud kms locations list`.\nKMS_LOCATION=\"\u003clocation\u003e\"\nKMS_KEY_RING=\"\u003ckey-ring name\u003e\"\nKMS_CRYPTO_KEY=\"\u003ccrypto-key name\u003e\"\n```\n\nHere is an example (replace with your values):\n\n```sh\nPROJECT_ID=\"my-gce-project23\"\nSERVICE_ACCOUNT_EMAIL=\"kms-plugin@my-gce-project23@iam.gserviceaccount.com\"\nKMS_LOCATION=\"us-east4\"\nKMS_KEY_RING=\"my-keyring\"\nKMS_CRYPTO_KEY=\"my-key\"\n```\n\n### Create Cloud KMS key\n\nCreate the key in Cloud KMS.\n\n```sh\n# Enable the Cloud KMS API (this only needs to be done once per project\n# where KMS is being used).\n$ gcloud services enable --project \"${PROJECT_ID}\" \\\n    cloudkms.googleapis.com\n\n# Create the Cloud KMS key ring in the specified location.\n$ gcloud kms keyrings create \"${KMS_KEY_RING}\" \\\n    --project \"${PROJECT_ID}\" \\\n    --location \"${KMS_LOCATION}\"\n\n# Create the Cloud KMS crypto key inside the key ring.\n$ gcloud kms keys create \"${KMS_KEY_NAME}\" \\\n    --project \"${PROJECT_ID}\" \\\n    --location \"${KMS_LOCATION}\" \\\n    --keyring \"${KMS_KEY_RING}\"\n```\n\n### Grant Service Account key permissions\n\nGrant the dedicated service account permission to encrypt/decrypt data using the Cloud KMS crypto key we just created:\n\n```sh\n$ gcloud kms keys add-iam-policy-binding \"${KMS_KEY_NAME}\" \\\n    --project \"${PROJECT_ID}\" \\\n    --location \"${KMS_LOCATION}\" \\\n    --keyring \"${KMS_KEY_RING}\" \\\n    --member \"serviceAccount:${SERVICE_ACCOUNT_EMAIL}\" \\\n    --role \"roles/cloudkms.cryptoKeyEncrypterDecrypter\"\n```\n\nIn addition to the IAM permissions, you also need to increase the oauth scopes on the VM. The following command assumes your VM master nodes require the `gke-default` scopes. If that is not the case, alter the command accordingly. Replace \"my-master-instance\" with the name of your VM:\n\n```sh\n$ gcloud compute instances set-service-account \"my-master-instance\" \\\n   --service-account \"${SERVICE_ACCOUNT_EMAIL}\" \\\n   --scopes \"gke-default, https://www.googleapis.com/auth/cloudkms\"\n```\n\nRestart any instances to pickup the scope changes:\n\n```sh\n$ gcloud compute instances stop \"my-master-instance\"\n$ gcloud compute instances start \"my-master-instance\"\n```\n\n\n### Deploy the KMS plugin\n\nThere are a few options for deploying the KMS plugin into a Kubernetes cluster:\n\n1. As a Docker image\n\n    A pre-built image is available at:\n\n    ```text\n    gcr.io/cloud-kms-lab/k8s-cloudkms-plugin:$TAG\n    ```\n\n    where `TAG` refers to a published git tag or \"latest\" for builds off the master branch. You can also build and publish your own image by cloning this repository and running:\n\n    ```sh\n    $ gcloud builds submit \\\n        --tag gcr.io/$PROJECT_ID/k8s-cloudkms-plugin \\\n        .\n    ```\n\n1. As a Go binary\n1. As a [static pod][k8s-static-pod]\n\n\n#### Pull image onto master VMs\n\n**On the Kubernetes master VM**, run the following command to pull the Docker image. Replace the URL with your repository's URL:\n\n```sh\n# Pick a tag and pin to that tag\n$ docker pull \"gcr.io/cloud-kms-lab/k8s-cloudkms-plugin:1.2.3\"\n```\n\n#### Test the interaction between KMS Plugin and Cloud KMS\n\n**On the Kubernetes master VM**, instruct the KMS plugin to perform a self-test. First, set some environment variables:\n\n```sh\nKMS_FULL_KEY=\"projects/${PROJECT_ID}/locations/${KMS_LOCATION}/keyRings/${KMS_KEY_RING}/cryptoKeys/${KMS_CRYPTO_KEY}\"\nSOCKET_DIR=\"/var/kms-plugin\"\nSOCKET_PATH=\"${SOCKET_DIR}/socket.sock\"\nPLUGIN_HEALTHZ_PORT=\"8081\"\nPLUGIN_IMAGE=\"gcr.io/cloud-kms-lab/k8s-cloudkms-plugin:1.2.3\" # Pick a tag\n```\n\nStart the container:\n\n```sh\n$ docker run \\\n    --name=\"kms-plugin\" \\\n    --network=\"host\" \\\n    --detach \\\n    --rm \\\n    --volume \"${SOCKET_DIR}:/var/run/kmsplugin:rw\" \\\n    \"${PLUGIN_IMAGE}\" \\\n      /bin/k8s-cloudkms-plugin \\\n        --logtostderr \\\n        --integration-test=\"true\" \\\n        --path-to-unix-socket=\"${SOCKET_PATH}\" \\\n        --key-uri=\"${KMS_FULL_KEY}\"\n```\n\nProbe the plugin on it's healthz port. You should expect the command to return \"OK\":\n\n```sh\n$ curl \"http://localhost:${PLUGIN_HEALTHZ_PORT}/healthz?ping-kms=true\"\n```\n\nStop the container:\n\n```sh\n$ docker kill --signal=\"SIGHUP\" kms-plugin\n```\n\nFinally, depending on your deployment strategy, configure the KMS plugin container to automatically boot at-startup. This can be done with systemd or an orchestration/configuration management tool.\n\n\n### Configure kube-apiserver\n\nUpdate the kube-apiserver's encryption configuration to point to the shared socket from the KMS plugin. If you changed the `SOCKET_DIR` or `SOCKET_PATH` variables above, update the `endpoint` in the configuration below accordingly:\n\n```yaml\nkind: EncryptionConfiguration\napiVersion: apiserver.config.k8s.io/v1\nresources:\n  - resources:\n    - secrets\n    providers:\n    - kms:\n        apiVersion: v2\n        name: myKmsPlugin\n        endpoint: unix:///var/kms-plugin/socket.sock\n   - identity: {}\n```\n\nMore information about this file and configuration options can be found in the [Kubernetes KMS plugin documentation][k8s-kms-plugin].\n\n\n## Learn more\n\n* Read [Encrypting Kubernetes Secrets with Cloud KMS][blog-container-security]\n* Read [GKE documentation for encrypting secrets][gke-secrets-docs]\n* Watch [Turtles all the way down: Managing Kubernetes Secrets][video-turtles]\n\n\n\n[gcp-kms]: https://cloud.google.com/kms\n[k8s-kms-plugin]: https://kubernetes.io/docs/tasks/administer-cluster/kms-provider/\n[blog-container-security]: https://cloud.google.com/blog/products/containers-kubernetes/exploring-container-security-encrypting-kubernetes-secrets-with-cloud-kms\n[gke-secrets-docs]: https://cloud.google.com/kubernetes-engine/docs/how-to/encrypting-secrets\n[video-turtles]: https://www.youtube.com/watch?v=rLHJZE2XKl8\n[cloud-sdk]: https://cloud.google.com/sdk\n[cloud-shell]: https://cloud.google.com/shell\n[gcp-billing]: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_new_project\n[k8s-static-pod]: https://kubernetes.io/docs/tasks/administer-cluster/static-pod/\n[dedicated-sa]: https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Fk8s-cloudkms-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgooglecloudplatform%2Fk8s-cloudkms-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Fk8s-cloudkms-plugin/lists"}