Check this out:
Keep your data safe: why encryption matters
From moving ML checkpoints to storing training data, encryption is at the core of our Kubernetes architecture
ultihash.io/blog/
keep-your-data-safe-why-encryption-matters

Whether you’re storing video, training datasets, or large-scale logs, encryption is a core part of keeping your systems trustworthy. From AI pipelines to internal ops, keeping data secure in transit and at rest is what lets teams move fast without looking over their shoulder.
That's why UltiHash has encryption as a core feature. In this post, we’ll walk through how it works, what it means for your setup, and how it helps you stay fast, protected, and focused on what matters.
UltiHash gives users the flexibility to enable in-transit encryption, when data is moving between clients and the storage server; and at-rest encryption, when data is written to disk. You can configure both, independently or together, depending on how sensitive your data is and how your infrastructure is set up.
You don’t need a separate security layer or external tool to make it work. Since UltiHash is Kubernetes-native, it’s built into how it runs, whether you're deploying on-premises, in the cloud, or hybrid and it integrates cleanly with your existing Kubernetes.
In-flight encryption ensures that any data exchanged between your applications and UltiHash is protected from interception or tampering as it moves through networks. This applies whether you're uploading ML checkpoints, accessing object metadata, or syncing large video files between environments. Without it, data could be visible in transit, especially if you're routing through public or shared infrastructure.
UltiHash supports TLS (Transport Layer Security) to encrypt all traffic between clients and the storage layer. You can enable this in your Kubernetes engine using an ingress controller, whether you’re routing traffic through a cloud load balancer or exposing it on-prem via a reverse proxy like NGINX or Traefik.
If you’re deploying with our Helm chart and using an ingress controller (like NGINX or Traefik), TLS is handled at the ingress level. This is typically the cleanest setup for Kubernetes-native environments, where you already manage routing and SSL termination through Kubernetes resources.
The process involves registering a domain for your cluster, creating a TLS certificate, and loading it into your cluster as a Kubernetes secret. Once that’s done, you reference the secret in your Helm config, and all incoming traffic is encrypted.
To enable TLS encryption at Ingress level perform the following actions:
example.domain.name
)secret-tls
)
kubectl get ingress -n <namespace>
#Configure the Ingress object via Helm values
entrypoint:
ingress:
# Make sure Ingress is enabled to expose UltiHash cluster outside your Kubernetes cluster
enabled: true
# Specify a domain name under which the UltiHash cluster will be accessible outside the Kubernetes cluster
host: example.domain.name
# Add annotations specific for your Ingress controller if required
annotations: {}
# Configure in-flight encryption by using TLS
tls:
- hosts:
- example.domain.name
secretName: secret-tls
This setup keeps encryption close to the edge of your system, while leaving the internal components of UltiHash unchanged. It also plays nicely with auto-renewing certificates (e.g., using Cert-Manager and Let’s Encrypt) if you're aiming for a hands-off ops experience.
Once configured, your clients can connect over HTTPS without requiring any additional changes: encryption is enforced automatically at the entry point.
If you’re setting the encryption through a load balancer, the TLS configuration depends on the type of load balancer you’re using. Make sure to refer to the documentation of your specific load balancer for exact steps.
Below is an example of a TLS for a Network Load Balancer configuration on AWS, which is the recommended option on AWS for better performance.
When using the NGINX Ingress controller on an AWS EKS cluster, the TLS can be configured by setting up a Network Load Balancer. To provision it automatically, make sure the AWS Load Balancer Controller is installed. Then, adjust the Helm values of the NGINX Ingress controller’s chart as follows:
controller:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-name: nlb-name # Specify the name for the load balancer
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing # Specify the scheme for the load balancer (internal or internet-facing)
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-healthcheck-protocol: http
service.beta.kubernetes.io/aws-load-balancer-healthcheck-path: /healthz
service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: 10254
service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-xxxx, mySubnet # Specify the subnet IDs or name in which the load balancer has to be provisioned
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:eu-central-1:3223213123233:certificate/c6a3ff73-3eb8-4e72-9e68-2dsa4cce549c # Specify ARN of the ACM certificate (has to be provisioned in advance)
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
Once data reaches your storage layer securely, encryption at rest ensures it’s safeguarded on disk too. Encrypting data at rest means ensuring that everything written to disk, whether it's raw files, deduplicated blocks, or internal metadata, is protected even if the physical storage is compromised.
UltiHash uses the encryption provided by your Kubernetes volume backend, as long as it supports CSI (Container Storage Interface) and volume-level encryption. This lets you manage encryption consistently across your infrastructure, without adding another layer or changing how you deploy.
If you're on AWS, this works seamlessly with EBS (Elastic Block Store). Other providers like Hetzner or GCP offer similar capabilities through their own CSI drivers.
Below, you can find a script template that walks you through the code needed. First, we define a StorageClass
with encryption turned on. This tells Kubernetes to provision encrypted volumes using your provider's built-in support (in AWS’s case, optionally using KMS keys).
From this point forward, anything UltiHash writes to disk is encrypted automatically.
Once implemented, there’s no need to change how you interact with the system, and in most real-world cases, there’s no noticeable performance impact.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: example-storage # Specify a name for the storage class
parameters:
encrypted: "true" # Enable the CSI driver to encrypt the EBS volumes it provisions
type: gp3 # Select the required type of EBS volumes to provision ('gp2', 'gp3', 'io1', or other)
# kmsKeyID: "" # (optional): specify the KMS key to encrypt the provisioned EBS volumes. If omitted, the AWS-managed KMS key will be used
provisioner: ebs.csi.aws.com
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
Once that’s in place, we simply tell UltiHash which StorageClass
to use. All components that write data, like storage
, deduplicator
, database
, and etcd
, can point to the same encrypted backend.
etcd:
persistence:
storageClass: example-storage
database:
primary:
persistence:
storageClass: example-storage
storage:
storageClass: example-storage
deduplicator:
storageClass: example-storage
If you're starting from scratch, it's worth putting encryption in place early, not just for compliance, it rather lays the groundwork for keeping your data secure as things grow and avoid costly rewrites later. It’s a foundational piece that scales with you, and having it from the start means one less blocker when security or regulatory needs inevitably catch up.
And if you’re already at scale, you know how quickly security gaps turn into real risks. Encryption at the storage layer gives you a solid baseline, one that holds up as teams grow, audits pile up, and the surface area expands.
Whether you’re storing video, training datasets, or large-scale logs, encryption is a core part of keeping your systems trustworthy. From AI pipelines to internal ops, keeping data secure in transit and at rest is what lets teams move fast without looking over their shoulder.
That's why UltiHash has encryption as a core feature. In this post, we’ll walk through how it works, what it means for your setup, and how it helps you stay fast, protected, and focused on what matters.
UltiHash gives users the flexibility to enable in-transit encryption, when data is moving between clients and the storage server; and at-rest encryption, when data is written to disk. You can configure both, independently or together, depending on how sensitive your data is and how your infrastructure is set up.
You don’t need a separate security layer or external tool to make it work. Since UltiHash is Kubernetes-native, it’s built into how it runs, whether you're deploying on-premises, in the cloud, or hybrid and it integrates cleanly with your existing Kubernetes.
In-flight encryption ensures that any data exchanged between your applications and UltiHash is protected from interception or tampering as it moves through networks. This applies whether you're uploading ML checkpoints, accessing object metadata, or syncing large video files between environments. Without it, data could be visible in transit, especially if you're routing through public or shared infrastructure.
UltiHash supports TLS (Transport Layer Security) to encrypt all traffic between clients and the storage layer. You can enable this in your Kubernetes engine using an ingress controller, whether you’re routing traffic through a cloud load balancer or exposing it on-prem via a reverse proxy like NGINX or Traefik.
If you’re deploying with our Helm chart and using an ingress controller (like NGINX or Traefik), TLS is handled at the ingress level. This is typically the cleanest setup for Kubernetes-native environments, where you already manage routing and SSL termination through Kubernetes resources.
The process involves registering a domain for your cluster, creating a TLS certificate, and loading it into your cluster as a Kubernetes secret. Once that’s done, you reference the secret in your Helm config, and all incoming traffic is encrypted.
To enable TLS encryption at Ingress level perform the following actions:
example.domain.name
)secret-tls
)
kubectl get ingress -n <namespace>
#Configure the Ingress object via Helm values
entrypoint:
ingress:
# Make sure Ingress is enabled to expose UltiHash cluster outside your Kubernetes cluster
enabled: true
# Specify a domain name under which the UltiHash cluster will be accessible outside the Kubernetes cluster
host: example.domain.name
# Add annotations specific for your Ingress controller if required
annotations: {}
# Configure in-flight encryption by using TLS
tls:
- hosts:
- example.domain.name
secretName: secret-tls
This setup keeps encryption close to the edge of your system, while leaving the internal components of UltiHash unchanged. It also plays nicely with auto-renewing certificates (e.g., using Cert-Manager and Let’s Encrypt) if you're aiming for a hands-off ops experience.
Once configured, your clients can connect over HTTPS without requiring any additional changes: encryption is enforced automatically at the entry point.
If you’re setting the encryption through a load balancer, the TLS configuration depends on the type of load balancer you’re using. Make sure to refer to the documentation of your specific load balancer for exact steps.
Below is an example of a TLS for a Network Load Balancer configuration on AWS, which is the recommended option on AWS for better performance.
When using the NGINX Ingress controller on an AWS EKS cluster, the TLS can be configured by setting up a Network Load Balancer. To provision it automatically, make sure the AWS Load Balancer Controller is installed. Then, adjust the Helm values of the NGINX Ingress controller’s chart as follows:
controller:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-name: nlb-name # Specify the name for the load balancer
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing # Specify the scheme for the load balancer (internal or internet-facing)
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-healthcheck-protocol: http
service.beta.kubernetes.io/aws-load-balancer-healthcheck-path: /healthz
service.beta.kubernetes.io/aws-load-balancer-healthcheck-port: 10254
service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-xxxx, mySubnet # Specify the subnet IDs or name in which the load balancer has to be provisioned
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:eu-central-1:3223213123233:certificate/c6a3ff73-3eb8-4e72-9e68-2dsa4cce549c # Specify ARN of the ACM certificate (has to be provisioned in advance)
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
Once data reaches your storage layer securely, encryption at rest ensures it’s safeguarded on disk too. Encrypting data at rest means ensuring that everything written to disk, whether it's raw files, deduplicated blocks, or internal metadata, is protected even if the physical storage is compromised.
UltiHash uses the encryption provided by your Kubernetes volume backend, as long as it supports CSI (Container Storage Interface) and volume-level encryption. This lets you manage encryption consistently across your infrastructure, without adding another layer or changing how you deploy.
If you're on AWS, this works seamlessly with EBS (Elastic Block Store). Other providers like Hetzner or GCP offer similar capabilities through their own CSI drivers.
Below, you can find a script template that walks you through the code needed. First, we define a StorageClass
with encryption turned on. This tells Kubernetes to provision encrypted volumes using your provider's built-in support (in AWS’s case, optionally using KMS keys).
From this point forward, anything UltiHash writes to disk is encrypted automatically.
Once implemented, there’s no need to change how you interact with the system, and in most real-world cases, there’s no noticeable performance impact.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: example-storage # Specify a name for the storage class
parameters:
encrypted: "true" # Enable the CSI driver to encrypt the EBS volumes it provisions
type: gp3 # Select the required type of EBS volumes to provision ('gp2', 'gp3', 'io1', or other)
# kmsKeyID: "" # (optional): specify the KMS key to encrypt the provisioned EBS volumes. If omitted, the AWS-managed KMS key will be used
provisioner: ebs.csi.aws.com
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
Once that’s in place, we simply tell UltiHash which StorageClass
to use. All components that write data, like storage
, deduplicator
, database
, and etcd
, can point to the same encrypted backend.
etcd:
persistence:
storageClass: example-storage
database:
primary:
persistence:
storageClass: example-storage
storage:
storageClass: example-storage
deduplicator:
storageClass: example-storage
If you're starting from scratch, it's worth putting encryption in place early, not just for compliance, it rather lays the groundwork for keeping your data secure as things grow and avoid costly rewrites later. It’s a foundational piece that scales with you, and having it from the start means one less blocker when security or regulatory needs inevitably catch up.
And if you’re already at scale, you know how quickly security gaps turn into real risks. Encryption at the storage layer gives you a solid baseline, one that holds up as teams grow, audits pile up, and the surface area expands.