Skip to main content
Version: 3.1

Secure your volumes

Summary and Key concepts

Summary:

This article discusses how to implement encryption for Persistent Volume Claims (PVCs) using the Portworx CSI Driver. It explains two methods for securing CSI-enabled volumes: using Kubernetes secrets or external secret providers (such as Vault, Google KMS, AWS KMS). The article provides detailed steps on how to create and configure StorageClasses with encryption, using either hardcoded or template-based secret values. It also describes how to generate and manage the required tokens for securing PVCs, emphasizing token-based authorization and how to reference these tokens in StorageClass configurations.

Kubernetes Concepts:

  • PersistentVolumeClaim (PVC): A request for storage resources from Kubernetes users.
  • StorageClass: Defines the class of storage available, with customizable parameters such as replication and encryption.
  • Kubernetes Secrets: Used to store and manage sensitive information, like authentication tokens or encryption keys, securely in Kubernetes.

Portworx Concepts:

  • Portworx CSI Driver: Enables the use of Portworx storage features such as encryption and snapshots with Kubernetes CSI.
  • Encryption with Portworx: Provides support for encrypting storage using keys managed by Portworx or third-party providers.
  • PX Security - Shared Secret Model: A method for securing storage with token-based authentication, automatically creating and refreshing user tokens in the Portworx StorageCluster.

Encryption with CSI

For information about how to encrypt PVCs on CSI using Kubernetes secrets, see encrypting PVCs on CSI with Kubernetes secrets.

Authorization and Authentication

You can secure your CSI-enabled volumes with token-based authorization. In using token-based authorization, you create secrets containing your token credentials and specify them in your StorageClass in one of two ways:

  • Using hardcoded values
  • Using template values

You can also mix these two methods to form your own hybrid approach.

Using hardcoded values

This example secures a storage class by specifying hardcoded values for the token and namespace. Users who create PVCs based on this StorageClass will always have their PVCs use the px-user-token Secret under the <px-namespace> namespace.

  1. Find or create your token secret:

For operator deployment with security enabled, a user token is automatically created and refreshed under px-user-token in your StorageCluster namespace. Refer to secure your storage with the Operator for more information.

kubectl get secrets px-user-token -n <px-namespace>
NAME            TYPE     DATA   AGE
px-user-token Opaque 1 23h

For all other configurations, create your own token secret:

kubectl create secret generic px-user-token \
-n <px-namespace> --from-literal=auth-token=$USER_TOKEN

  1. Modify the storageClass:

    If you're using Kubernetes secrets, add the following parameters that are shown in the following example:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
    name: px-csi-db-encrypted-k8s
    provisioner: pxd.portworx.com
    parameters:
    repl: "3"
    secure: "true"
    io_profile: auto
    io_priority: "high"
    csi.storage.k8s.io/provisioner-secret-name: px-user-token
    csi.storage.k8s.io/provisioner-secret-namespace: <px-namespace>
    csi.storage.k8s.io/node-publish-secret-name: px-user-token
    csi.storage.k8s.io/node-publish-secret-namespace: <px-namespace>
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    allowVolumeExpansion: true

    If you're using another secret provider, such as Vault, Google KMS, AWS KMS, or KVDM, define the desired encryption key in the secret_key parameter directly as a parameter on the CSI storage class. For example:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
    name: px-csi-db-encrypted-vault
    provisioner: pxd.portworx.com
    parameters:
    repl: "3"
    secure: "true"
    io_profile: auto
    io_priority: "high"
    secret_key: px-cluster-key
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    allowVolumeExpansion: true
note

Ensure that the secret called px-cluster-key exists and contains the value that you can use to encrypt your volumes.

Using template values

This example secures a StorageClass by hardcoding the token and namespace. If you have created PVCs based on this StorageClass, you can have your PVCs use the StorageClass, which you specify in the annotation of your PVC, and the namespace specified in your PVC.

  1. Modify the StorageClass, adding the highlighted csi.storage.k8s.io parameters:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
    name: px-csi-db-encrypted-k8s
    provisioner: pxd.portworx.com
    parameters:
    repl: "3"
    secure: "true"
    io_profile: auto
    io_priority: "high"
    csi.storage.k8s.io/provisioner-secret-name: ${pvc.name}
    csi.storage.k8s.io/provisioner-secret-namespace: ${pvc.namespace}
    csi.storage.k8s.io/node-publish-secret-name: ${pvc.name}
    csi.storage.k8s.io/node-publish-secret-namespace: ${pvc.namespace}
    reclaimPolicy: Delete
    volumeBindingMode: Immediate
    allowVolumeExpansion: true
  2. Create a secret in your PVC's namespace with the same name as the PVC. For example, a PVC named px-mysql-pvc must have an associated secret named px-mysql-pvc.

  1. Get the token as mentioned in Using hardcoded values:
USER_TOKEN=$(kubectl get secrets px-user-token -n <px-namespace> -o json | jq -r '.data["auth-token"]' | base64 -d)
  1. Create the secret:
kubectl create secret generic px-mysql-pvc -n <px-namespace> --from-literal=auth-token=$USER_TOKEN