MinIO Key Management Service Helm Chart

The following code block includes the full contents of the MinIO Key Management Service Helm chart default values.yaml and all accompanying documentation.

# Following annotations/labels are applied to all resources created by the Helm chart
annotations: {}
labels: {}

# Allow to override the namespace for all resources
#namespaceOverride: "test"

# The Helm chart will try to auto-detect OpenShift. If it cannot detect OpenShift
# (i.e. when running helm template), then it will default to false. You can
# override this setting to force OpenShift mode.
#forceOpenShift: true

###
# Root key for MinKMS
minkms:
  ###
  # The Key Manager name
  #
  # When the key manager name is not specified, the chart will use the release name
  # as the key manager name.
  #name: mykms
  ###
  # Specify the container image to use.
  # ``image.tag``
  # For example, the following sets the image to the ``quay.io/minio/aistor/minkms`` repo and the RELEASE.2025-03-24T19-33-06Z tag.
  # The container pulls the image if not already present:
  #
  # .. code-block:: yaml
  #
  #    image:
  #       repository: quay.io/minio/aistor/minkms
  #       tag: RELEASE.2025-03-24T19-33-06Z
  #       pullPolicy: IfNotPresent
  #
  # The chart also supports specifying an image based on digest value:
  #
  # .. code-block:: yaml
  #
  #    image:
  #       repository: quay.io/minio/aistor/minkms
  #       digest: sha256:2ebef198955b802aae9fc2b7789d1d3073e9d1d05c8b70d702aeef7d064a9e56
  #       pullPolicy: IfNotPresent
  #
  #
  image: {}
  #   repository: quay.io/minio/aistor/minkms
  #   tag: RELEASE.2025-03-24T19-33-06Z
  #   pullPolicy: IfNotPresent
  ###
  #
  # An array of Kubernetes secrets to use for pulling images from a private image repository.
  # NOTE: This was renamed from `imagePullSecret` (object) to `imagePullSecrets` (array) - a breaking change.
  # If you previously set `imagePullSecret: {name: ...}`, migrate to `imagePullSecrets: [{name: ...}]`.
  imagePullSecrets: []

  ###
  # MinKMS server configuration file (server-config.yaml).
  #
  # At least one HSM must be provided - either a soft HSM static key (minkms.hsm.key) or one or more
  # external HSM backends configured here (configuration.hsm). Both can be used together for redundancy:
  # if one HSM becomes unavailable, MinKMS can still unseal using another.
  #
  # This section configures external HSM backends. When set, the chart embeds the connection details
  # into server-config.yaml, which MinKMS reads at startup to connect to the external HSM service and
  # obtain the seal/unseal key. This is distinct from minkms.hsm.key (below), which is a static key
  # stored directly in a Kubernetes secret and injected as the MINIO_KMS_HSM_KEY environment variable.
  configuration:
    #name: mykms-server-config
    existingSecret: false
    #hsm:
    #  # Option 1: Use another MinKMS cluster as the external HSM backend.
    #  minio:
    #    minkms:
    #      server:
    #        - hsm-minkms.ns.svc.cluster.local:7373      # Server addresses
    #      enclave: my-hsm-enclave                       # Name of the enclave on the MinKMS HSM cluster containing the seal/unseal key.
    #      key: sse-root-key                             # Name of the key used for sealing/unsealing the on-disk state.
    #      auth:
    #        key: k1:pMhutEWtChHgFYcQuy6V7NwuHTA0g59QDFrR9YpQY74 # API key for accessing the seal/unseal key within the enclave.
    #
    #  # Option 2: Use HashiCorp Vault as the external HSM backend.
    #  hashicorp:
    #    vault:
    #      server: https://vault-hsm.vault.svc.cluster.local:8200  # Service endpoint
    #      transit:
    #        key: my-transit-key                                   # The transit key used to seal/unseal MinKMS state.
    #        path: transit/                                        # The transit engine mount path.
    #      approle:
    #        path: approle                                         # The approle mount path.
    #        id: 6e2fe00b-0507-6287-fd6c-fc000763301f              # The approle role ID.
    #        secret: 9a2c9dec-53ce-47d3-7a40-fb0735d0e0ef          # The approle secret ID - NOT the secret accessor ID.

  ###
  # Soft HSM static key.
  #
  # This is an alternative (or complement) to the external HSM backends in configuration.hsm above.
  # When set, the key is stored in a Kubernetes secret and injected into the MinKMS pod as the
  # MINIO_KMS_HSM_KEY environment variable. MinKMS uses it directly to seal/unseal its on-disk state
  # without connecting to any external service.
  #
  # At least one of minkms.hsm.key or minkms.configuration.hsm must be provided.
  hsm:
    #name: mykms-secret
    existingSecret: false
    #
    # Generate key using the `docker run quay.io/minio/aistor/minkms:latest --soft-hsm` command
    #
    # IMPORTANT: This default value cannot be used and should be replaced if it is desired to use an HSM static key.
    #            Changing or loosing the HSM key causes data loss of the entire Key Manager deployment.
    #            Since Key Manager maintains encryption keys for its client applications, all data encrypted by
    #            these applications is also lost in such a case.
    #key: "hsm:aes256:????????????????????????????????????????????"

  apikey:
    #name: mykms-apikey-secret
    existingSecret: false
    #
    # Generate first temporal HSM key using the `docker run quay.io/minio/aistor/minkms:latest --soft-hsm`
    # command and then derive API key with `docker run quay.io/minio/aistor/minkms:latest identity <HSM-key>` command
    #
    # IMPORTANT: This default value is not intended for use and must be replaced if you want to apply a
    #            custom API key. If no API key is defined here, then Key Manager Operator will create
    #            an API key secret for you. This API key can be rotated and it can be recreated without
    #            loosing data.
    #key: "k1:???????????????????????????????????????????"

  # affinity:
  #   nodeAffinity: {}
  #   podAffinity: {}
  #   podAntiAffinity: {}

  ###
  # Configures external certificate settings for the Key Manager.
  certificates:
    disableAutoCert: false
    ###
    # Specify an array of Kubernetes TLS secrets, where each entry corresponds to a secret the TLS private key and public certificate pair.
    #
    # This is used by MinIO to verify TLS connections from clients using those CAs
    # If you omit this and have clients using TLS certificates minted by an external CA, those connections may fail with warnings around certificate verification.
    certConfig: {}
      # commonName: ...
      # dnsNames:
      # - "..."
      # - "..."
      # organizationName:
      # - "..."
      # - "..."
    ###
    # externalCertSecret is the secret storing the MinKMS server TLS certificate when `disableAutoCert: true`
    # and you want MinKMS to present an externally-generated certificate on its TLS endpoint.
    #
    # The operator reads the certificate and key from the secret based on its type:
    #   - `kubernetes.io/tls`: `tls.crt` and `tls.key`
    #   - `Opaque` (or any other type): `public.crt` and `private.key`
    # MinKMS uses SNI to select among multiple server certificates if more than one entry is provided.
    # externalCertSecret:
    # - name: keymanager-server-secret
    ###
    # externalCaCertSecret Allows MinKMS pods to verify client certificates signed by a Certificate Authority not in the default pod's trust store.
    #
    # If the ObjectStore uses custom or user-controlled TLS certificates, you *must* provide the CA for those certificates here
    # externalCaCertSecret:
    # - name: external-ca-secret-name
    #   type: kubernetes.io/tls
    # - "..."
    ###
    # externalClientCertSecrets provides additional client certificates that MinKMS uses for outbound mTLS
    # (e.g. to an external KMS backend). Each entry is mounted under a separate `certs/client-N/` folder.
    # This is NOT the server certificate. Use `externalCertSecret` above for that.
    # externalClientCertSecrets:
    # - name: minkms-client-secret
    #   type: kubernetes.io/tls

  # containerSecurityContext:
  #   runAsUser: 1000
  #   runAsGroup: 1000
  #   runAsNonRoot: true
  #   allowPrivilegeEscalation: false
  #   capabilities:
  #     drop:
  #       - ALL
  #   seccompProfile:
  #     type: RuntimeDefault

  # securityContext:
  #   runAsUser: 1000
  #   runAsGroup: 1000
  #   runAsNonRoot: true
  #   fsGroup: 1000

  ###
  # An array of `Initialization Containers <https://kubernetes.io/docs/concepts/workloads/pods/init-containers/>`__ to initialize the Key Manager pods.
  #
  # All initialization containers should be run to completion before the Key Manager pod starts.
  initContainers: []

  # env: []
  # Annotations to apply to the MinKMS StatefulSet and Pod template.
  # annotations: {}
  #   my-annotation: value
  # Labels to apply to the MinKMS StatefulSet and Pod template.
  # labels: {}
  #   my-label: value
  # serviceAccountName: ""
  # nodeSelector: { }

  ###
  # The `PodManagement <https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#pod-management-policy>`__ policy for Key Manager pods.
  # Can be "OrderedReady" or "Parallel"
  podManagementPolicy: Parallel

  ###
  # PriorityClassName indicates the Pod priority and hence importance of a Pod relative to other Pods.
  # Refer Kubernetes documentation for details https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass/
  priorityClassName: ""

  replicas: 3
  # resources: { }
  # runtimeClassName: ""
  # schedulerName: ""
  service: {}
    # name: mykms-service
    # annotations: {}
    # labels: {}
    # nodePort: 31002
    # serviceType: NodePort
    # serviceExternalTrafficPolicy: Local

  ###
  # The `Kubernetes Service Account <https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/>`__ associated with the MinKMS.
  serviceAccountName: ""

  sideCars: {}
    # containers: []
    # resources: {}
    # volumeClaimTemplates: []
    # volumes: []

  # tolerations: []
  # topologySpreadConstraints: []

  ###
  # volumeClaimTemplate is used to create a PersistentVolumeClaim for the Key Manager pods.
  # The amount of storage requested is specified in the `resources.requests.storage` field
  # The default value of '25Mib' should meet the requirements of reasonable production workloads.
  # MinKMS may require more storage in workloads with a large number
  # of enclaves and master keys. You can use the following formula to
  # roughly estimate required storage:
  # ( N_enclaves * 200 ) + ( N_keys * 200 ) + ( 64 * 1024 ) = total number of bytes
  volumeClaimTemplate:
    metadata:
      name: mykms-volume
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 25Mi

extraResources: []

Installing the minkms Helm chart prints the following output, including configuration next steps:

The key manager is successfully installed and -once initialized- should be available
from within the cluster on <KMS_URL>. If you want to enable Key Manager with the
object store, then perform the following steps:

1. Obtain the admin API key for the object store:
   docker run --rm quay.io/minio/aistor/minkms:latest identity <MINKMS_HSM_KEY>

2. Create an enclave dedicated for the object store:
   kubectl exec -n <KMS_NS> <KMS_NAME>-0 -- /minkms add-enclave --api-key <ADMIN_API_KEY> <ENCLAVE_NAME>

3. Create an administrator identity that is used by MinIO to manage the keys:
   kubectl exec -n <KMS_NS> <KMS_NAME>-0 -- /minkms add-identity --api-key <ADMIN_API_KEY> --enclave <ENCLAVE_NAME> --admin

   This step will return both the API key and the identity. Make sure you write down
   the API key, because it will only be displayed during creation and cannot be obtained
   later anymore. This API key will be used later and is refered to <ENCLAVE_API_KEY>.

4. Create a default key that is used to encrypt the data (server side encryption key)
   kubectl exec -n <KMS_NS> <KMS_NAME>-0 -- /minkms add-key --api-key <ADMIN_API_KEY> --enclave <ENCLAVE_NAME> <SSE_KEY_NAME>

Then create the object-store that holds the following environment variables:
- MINIO_KMS_SERVER: <KMS_URL>
- MINIO_KMS_ENCLAVE: <ENCLAVE_NAME>       (this is the enclave created in step 2)
- MINIO_KMS_API_KEY: <ENCLAVE_API_KEY>    (this is not the admin API key, but the enclave API key from step 3)
- MINIO_KMS_SSE_KEY: <SSE_KEY_NAME>       (this is the SSE key created in step 4)