> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# K8s secrets encrypted keys managed remediation

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To remediate the misconfiguration "Ensure Kubernetes Secrets Are Encrypted Using KMS Keys" in GCP using the GCP console, follow the below steps:

        1. Open the Google Kubernetes Engine (GKE) cluster in the GCP console.

        2. Navigate to the "Workloads" tab on the left-hand side menu and select the deployment that you want to remediate.

        3. Click on the "Edit" button at the top of the screen.

        4. Scroll down to the "Environment Variables" section and click on "Add Environment Variable".

        5. Add the following environment variable:

           Name: GOOGLE\_ENCRYPTION\_KEY

           Value: \[the name of the KMS key you want to use to encrypt the secrets]

        6. Click on the "Save" button at the bottom of the screen to save the changes.

        7. Repeat steps 4-6 for each deployment that needs to be remediated.

        By following these steps, you have ensured that Kubernetes secrets are encrypted using KMS keys in GCP.

        #
      </Accordion>

      <Accordion title="Using CLI">
        To remediate the misconfiguration of Kubernetes Secrets not being encrypted using KMS Keys on GCP, you can follow the below steps:

        1. Open the Cloud Shell in the GCP Console.

        2. Run the following command to get the list of Kubernetes secrets in the cluster:

           ```
           kubectl get secrets
           ```

        3. Identify the secrets that are not encrypted using KMS keys.

        4. Create a KMS keyring and key:

           ```
           gcloud kms keyrings create [KEYRING-NAME] --location [LOCATION]

           gcloud kms keys create [KEY-NAME] --location [LOCATION] --keyring [KEYRING-NAME] --purpose encryption
           ```

           Replace \[KEYRING-NAME], \[LOCATION] and \[KEY-NAME] with the appropriate values.

        5. Encrypt the Kubernetes secrets using the KMS key:

           ```
           gcloud kms encrypt --key [KEY-NAME] --keyring [KEYRING-NAME] --location [LOCATION] --plaintext-file [SECRET-FILE-PATH] --ciphertext-file [ENCRYPTED-FILE-PATH]
           ```

           Replace \[KEYRING-NAME], \[LOCATION], \[KEY-NAME], \[SECRET-FILE-PATH] and \[ENCRYPTED-FILE-PATH] with the appropriate values.

        6. Update the Kubernetes secrets with the encrypted data:

           ```
           kubectl create secret generic [SECRET-NAME] --from-file=[SECRET-FILE-PATH]=[ENCRYPTED-FILE-PATH]
           ```

           Replace \[SECRET-NAME], \[SECRET-FILE-PATH] and \[ENCRYPTED-FILE-PATH] with the appropriate values.

        7. Verify that the secrets have been encrypted using KMS keys:

           ```
           kubectl get secrets
           kubectl describe secret [SECRET-NAME]
           ```

           Replace \[SECRET-NAME] with the name of the secret.

        8. Delete the unencrypted Kubernetes secrets:

           ```
           kubectl delete secret [SECRET-NAME]
           ```

           Replace \[SECRET-NAME] with the name of the secret.

        By following these steps, you can ensure that the Kubernetes secrets are encrypted using KMS keys on GCP.
      </Accordion>

      <Accordion title="Using Python">
        To remediate the misconfiguration of ensuring Kubernetes secrets are encrypted using KMS keys in GCP using Python, you can follow the below steps:

        1. Install the necessary Python libraries:
           * google-auth
           * google-auth-oauthlib
           * google-auth-httplib2
           * google-cloud-kms
           * kubernetes

        2. Authenticate with GCP using a service account key file:
           ```
           from google.oauth2 import service_account
           credentials = service_account.Credentials.from_service_account_file('key.json')
           ```

        3. Connect to the KMS service:
           ```
           from google.cloud import kms_v1
           kms_client = kms_v1.KeyManagementServiceClient(credentials=credentials)
           ```

        4. Get the KMS key resource name:
           ```
           key_name = kms_client.crypto_key_path_path('project-id', 'location', 'key-ring', 'key')
           ```

        5. Retrieve the Kubernetes secret:
           ```
           from kubernetes import client, config
           config.load_kube_config()
           v1 = client.CoreV1Api()
           secret = v1.read_namespaced_secret('secret-name', 'namespace')
           ```

        6. Encrypt the secret data using the KMS key:
           ```
           from google.cloud import kms_v1
           plaintext = secret.data['key']
           response = kms_client.encrypt(key_name, plaintext.encode('utf-8'))
           ```

        7. Update the Kubernetes secret with the encrypted data:
           ```
           secret.data['key'] = response.ciphertext
           v1.replace_namespaced_secret('secret-name', 'namespace', secret)
           ```

        By following these steps, you can ensure that Kubernetes secrets are encrypted using KMS keys in GCP using Python.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Customer-managed key for secrets encryption
        resource "google_kms_key_ring" "gke_secrets" {
          name     = "GKE_SECRETS_KEY_RING"
          location = "KMS_LOCATION" # e.g. "us-central1"
          project  = "PROJECT_ID"
        }

        resource "google_kms_crypto_key" "gke_secrets" {
          name            = "GKE_SECRETS_KEY"
          key_ring        = google_kms_key_ring.gke_secrets.id
          rotation_period = "2592000s" # 30 days; adjust as needed
        }

        # Grant GKE's Google-managed SA permission to use the key
        # Replace PROJECT_NUMBER and PROJECT_ID appropriately.
        resource "google_kms_crypto_key_iam_binding" "gke_secrets" {
          crypto_key_id = google_kms_crypto_key.gke_secrets.id
          role          = "roles/cloudkms.cryptoKeyEncrypterDecrypter"

          members = [
            "serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com",
          ]
        }

        # GKE cluster with secrets encryption using the CMEK
        resource "google_container_cluster" "primary" {
          name     = "CLUSTER_NAME"
          location = "CLUSTER_LOCATION" # e.g. "us-central1"
          project  = "PROJECT_ID"

          # Other required cluster settings here:
          # network, subnetwork, remove_default_node_pool, ip_allocation_policy, etc.

          database_encryption {
            state    = "ENCRYPTED"
            key_name = google_kms_crypto_key.gke_secrets.id
          }
        }
        ```

        Enabling or disabling `database_encryption` or changing `key_name` on an existing `google_container_cluster` forces replacement of the cluster, causing an outage during recreation; plan carefully before applying.

        `terraform plan` should show the `google_container_cluster` either being created with `database_encryption.state = "ENCRYPTED"` and `key_name` set to the KMS key, or (for an existing cluster) destroyed and re-created with those fields changed from `DECRYPTED`/`""` (or absent) to the new CMEK configuration, along with creation of the KMS key ring, key, and IAM binding.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
