Back to all posts
development
USE CASES
Company
Infrastructure
Workflows
Apr 16, 2025
April 16, 2025

Keep your data safe: why encryption matters

From moving ML checkpoints to storing training data, encryption is at the core of our Kubernetes architecture
Posted by
Juliette Lehmann
Founder's Associate

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.

How UltiHash handles encryption

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: Secure traffic without changing how you work

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.

→ Using Kubernetes ingress

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:

  • register a domain name for UltiHash cluster in your private or public DNS server (for example example.domain.name)
  • generate TLS private key and certificate bound to your registered domain name
  • create a Kubernetes secret in your UltiHash namespace with TLS credentials as shown here (assume the secret's name is secret-tls)
  • enable the Ingress object using your domain name and the corresponding TLS secret in the helm values.
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.

→ Behind a cloud load balancer (AWS)

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

At-rest encryption: Protect the data on disk

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.

Share this post:
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
Posted by
Juliette Lehmann
Founder's Associate
Build faster AI infrastructure with less storage resources
Get 10TB Free

Keep your data safe: why encryption matters

From moving ML checkpoints to storing training data, encryption is at the core of our Kubernetes architecture

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.

How UltiHash handles encryption

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: Secure traffic without changing how you work

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.

→ Using Kubernetes ingress

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:

  • register a domain name for UltiHash cluster in your private or public DNS server (for example example.domain.name)
  • generate TLS private key and certificate bound to your registered domain name
  • create a Kubernetes secret in your UltiHash namespace with TLS credentials as shown here (assume the secret's name is secret-tls)
  • enable the Ingress object using your domain name and the corresponding TLS secret in the helm values.
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.

→ Behind a cloud load balancer (AWS)

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

At-rest encryption: Protect the data on disk

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.